左移浮点类型

10

在尝试进行操作时出现编译器错误

float_val=float_val<<1;

出现错误,提示“error C2296: '<<' : 非法,左操作数的类型为 'float'”

不能对浮点变量进行左移操作吗?为什么会这样呢?


1
在浮点数的情况下,您希望如何执行移位操作? - Tudor
我猜应该和 int(2 的幂)一样。 - Akash
1
由于浮点数的不同位具有不同的含义,对浮点数进行位移操作是没有意义的。 - Dan F
2
一篇不错的阅读材料:IEEE_754-2008 - Alexander Pavlov
可能是重复的问题:如何对浮点数执行位运算 - Shahbaz
应该根据代码的实际意图编写代码,如果想要将值加倍,则应编写 *2。如果您真的在进行位移(即使用位字段的硬件寄存器),则应编写 <<1。无论哪种方式,编译器都会生成完全相同的机器代码。尝试使用位移来缩放浮点数的幂次是编写晦涩代码的行为。相信您的编译器能够生成高效的机器代码,只需编写清晰易懂的代码即可。 - Michael
7个回答

20

你不能对 float 变量进行左移操作,因为 (a) 你的浮点运算单元(FPU)通常不会将位移器暴露给你,因此在物理上无法生成执行该操作的代码;(b) 这甚至意味着什么?底层的位表示由多个具有不同含义的字段组成,你真的希望这些位相互渗透吗?

如果你想将该变量中所保存的数字乘以二,你应该直接这样做。

如果你想将浮点数重新解释为一些可以进行左移操作的类型(例如充分大的无符号整数类型),以便进行一些可怕的位操作,比如 Carmack 的平方根,那么你也可以这样做,但在现代硬件上,你真的需要这样做吗?请认真考虑是否存在更好的方法来实现你想要的功能。


8
但是要苛求一点的话,FPU几乎肯定会有一个桶形移位器,因为这在执行浮点加法时几乎是必须的。 - Oliver Charlesworth
2
@Oli:但即使你可以控制它,它也没有连接到整个浮点数,只有尾数...我会澄清的。 - moonshadow
没问题,你的答案已经很好了。我只是像一个刻板印象中的SO龟毛! - Oliver Charlesworth
在amd64上,FP数学通常在SSE寄存器中完成。你可以在这些寄存器上使用整数左/右移位操作,没有任何限制。(除了结果对于大多数任务都没用!) - Peter Cordes

5

3
移动浮点数是没有意义的,因为它表示为符号位、指数和尾数的连接。由于移位操作涉及到位移,这将意味着从尾数向指数和/或符号位移动位。

1

浮点数在值表示层面上没有比特位,因此无法对其应用按位运算。

有关更多信息,请参见this answer


1

由于左移运算符被定义为乘以2的幂,因此对于浮点类型来说是非常合理的。然而,C语言并没有定义其使用方式,因此您必须使用scalbn函数或类似函数。


0

你不能对 float 类型的对象进行左移操作。

C 语言规定位移运算符的操作数必须是整数类型。


-2

你需要先将浮点数转换为其他类型,例如:

float f = 128;
f = (float) (((int) f) << 1 );

在上面的例子中,f 应该是 256.0。

显然,如果你从 128.4 开始,这会有问题,因为强制转换会丢失小数点后的 .4。你可能不想一开始就使用浮点数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接