0

我面临着关于舍入float和转换为的非常奇怪的事实int

如此处所述: http ://www.gnu.org/software/libc/manual/html_node/Rounding.html

舍入到最接近的可表示值是默认舍入模式。但似乎不是。

所以我创建了这个简单的程序:

#include <fenv.h>
#include <stdio.h>

int a;
double b;

main() {
  b=1.3; a=b; printf("%f %d\n",b,a);
  b=1.8; a=b; printf("%f %d\n",b,a);
  b=-1.3; a=b; printf("%f %d\n",b,a);
  b=-1.8; a=b; printf("%f %d\n",b,a);
  printf("%d %d %d\n",fegetround(),FE_TONEAREST,FE_TOWARDZERO);
}

程序使用 gcc-4.7 (debian)、cygwin gcc 和 Visual Studio 编译。输出是一样的,只是定义FE_TOWARDZERO改变了。

程序输出:

 1.300000 1
 1.800000 1
-1.300000 -1
-1.800000 -1
0 0 3072

所以我们可以清楚地看到,FE_TONEAREST在所有经过测试的编译器中,舍入模式都设置为(默认),但它们都向零舍入。

为什么?

PS:是的,我可以使用Math.round(),但我想知道为什么会这样。

4

2 回答 2

2

因为舍入模式适用于浮点舍入函数。转换为int总是截断。

于 2013-05-31T07:26:42.807 回答
0

好的,我发现了为什么会发生这种情况的问题。如此处所述:

http://software.intel.com/en-us/articles/fast-floating-point-to-integer-conversions

在章节中

A Closer Look at Float-to-Int Conversions

从浮点数转换为 32 位整数的问题源于 ANSI C 标准,该标准规定应通过截断数字的小数部分并保留整数结果来实现转换。因此,每当 Microsoft Visual C++ 6.0 编译器遇到 (int) 或 (long) 类型转换时,它都会插入对 _ftol C 运行时函数的调用。此函数将浮点舍入模式修改为“截断”,执行转换,然后将舍入模式重置为强制转换之前的原始状态。

于 2013-05-31T08:06:23.130 回答