将double转换为float后的值不正确

时间:2011-09-09 03:08:50

标签: c gcc gdb floating-point

我有一些C代码执行由gcc编译的高精度算术(gcc(GCC)4.4.4 20100726(Red Hat 4.4.4-13))。计算的最终结果是double,其值为622.07999995861189我正把双人投入漂浮物。

frequency_value =(float)current_freq;

其中current_freq是double,而frequency_value是float。强制转换后的frequency_value的值是622.080017。我希望该值为622.079956,按gdb计算

(gdb)p(float)current_freq $ 1 = 622.079956

任何人都可以解释gcc和gdb计算出的值之间的巨大差异。

2 个答案:

答案 0 :(得分:3)

浮点数的精度远低于双精度浮点数;你失去了大约一半的数字。所以充其量你会看到622.0799部分(四舍五入到622.0800)。您看到的差异可能是由使用的舍入模式引起的。

以下是实际数字:

  • 双倍:622.0799999586118929073563776910305023193359375
  • As float:622.08001708984375(内部代表:1142654239)
  • 紧接在前的浮动:622.0799560546875(内部代表:1142654238)

内部表示是使用Java Float.floatToIntBits生成的值。您还可以使用Float.intBitsToFloat获取浮点数。

答案 1 :(得分:1)

浮点值通常以某种二进制格式存储在机器中,而不是以某种十进制格式存储。出于这个原因,当你截断/舍入数字时,期望它将被十进制数字截断/舍入是不合理的。即期望622.07999995861189变成必然以622.07999...开头的东西是不合理的。一些前导十进制数字应该“存活”不变,但由于截断/舍入是在二进制表示上执行的(并且您在屏幕上看到的是将原始二进制格式转换为ASCII字符串的结果)很可能是受进程影响的十进制数字将远远超出预期。在您的情况下,更改一直传播到点后的第二个数字。这就是为什么你得到622.08...而不是622.07...

至于GDB的不同结果......很可能GDB的浮点计算模型与编译器的浮点计算模型不同。例如,GDB可能会截断结果,而编译器则将其舍入。或者编译器可能正在优化计算,这通常会导致稍微不同的结果。