为什么两个浮点乘法给出的答案不同于一个?

时间:2010-09-05 04:38:43

标签: c floating-point

我最近遇到了一个问题,我没有得到我预期的数值结果。我将其跟踪到以下示例所示的问题:

#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]范围内。

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)。这应该会给你一致的结果。或者,您可以使用更大的有符号整数类型。