我最近遇到了一个问题,我没有得到我预期的数值结果。我将其跟踪到以下示例所示的问题:
#include <stdio.h>
int main()
{
double sample = .5;
int a = (int)(sample * (1 << 31));
int b = (int)(sample * (1 << 23) * (1 << 8));
printf("a = %#08x, b = %#08x\n", a, b);
}
// Output is: a = 0xc0000000, b = 0x40000000
为什么乘以(1 <&lt;&lt;&lt; 31)的结果不同于乘以(1&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&gt;我希望这两个人给出相同的答案,但他们没有。
我应该注意,我所有的浮点值都在[-1,1]范围内。
答案 0 :(得分:14)
您显然期待相同的结果,因为您假设乘以(1 << 31)
与乘以(1 << 23)
然后乘以(1 << 8)
相同。一般情况下它们不一样。您正在(1 << 31)
域中执行signed int
计算。如果您的平台使用32位整数,则(1 << 31)
表达式溢出,而(1 << 23)
和(1 << 8)
都不会溢出。这立即意味着第一次乘法的结果是不可预测的。
换句话说,在(1 << 31)
类型的值表示中只有31位的平台上执行int
没有任何意义。您需要至少32个值形成位才能有意义地计算(1 << 31)
。
如果您希望(1 << 31)
有意义,请在其中计算未签名域:(1u << 31)
,(1u << 23)
和(1u << 8)
。这应该会给你一致的结果。或者,您可以使用更大的有符号整数类型。