我从库中的函数round()
和roundf()
函数中得到了意想不到的结果math.h
.以下是示例代码:
#include#include int main(void) { float f; double d; /* Note man page says that roundf() returns a float and round() returns a double */ f = roundf(1.2); d = round(1.2); printf("%f\n", f); printf("%lf\n", d); return 0; }
当我编译并运行程序时,我得到:
gcc -lm round.c ./a.out 288.000000 524288.000000
哇哇哇?
更新: 除了答案,我已经确认代码在较新的编译器上正常工作.(我认为%lf不是正确的printf说明符,但在这种情况下不影响最终结果.)我需要弄清楚为什么编译器会以这种方式运行,因为我运行的代码使用round()和已在同一台机器上编译.我弄清楚的时候会更新帖子.
gcc -v Reading specs from /usr/lib/gcc-lib/i386-slackware-linux/2.95.3/specs gcc version 2.95.3 20010315 (release)
Johannes Sch.. 11
如果你编译代码而不告诉gcc用C99模式编译(-std=c99
)并告诉它不要知道"特殊内置"函数(使用-fno-builtin
),你可能会失败.然后它假定你的round/roundf函数被定义为
int round(); int roundf();
因为在C99之前的时代还没有这样的函数,所以它没有声明,然后隐式声明它们.这显然会失败,因为调用端将返回值视为int,而被调用方(在链接库中的那些函数的定义中)返回float.我得到这些结果例如:
[js@HOST2 cpp]$ ./a.out 1065353216.000000 -1048576.000000 [js@HOST2 cpp]$
不是你现在认为你可以将返回值强制转换为浮点值并且没问题.嗯,情况更糟.返回值甚至不保证与返回的float有任何关系.调用端从一个知道返回整数的位置读取.但是你的编译器可能会从被调用方返回另一个地方(例如浮点指针寄存器中)的浮点数.上面实际上可以做任何事情,包括中止程序,因为它以不确定的方式运行.
那么,你能做些什么让它发挥作用?通过编译器std=c99
标志或使用其他方式来舍入(floor是其中之一),不需要这些功能
gcc -std=c99 test.c -lm
请参阅的联机帮助页man 3 round
.但是,如果你有一个非常老的GCC - 我不确定它是否支持足够的C99来进行那个转换.然后查看圆形联机帮助页中描述的功能测试宏.
如果你编译代码而不告诉gcc用C99模式编译(-std=c99
)并告诉它不要知道"特殊内置"函数(使用-fno-builtin
),你可能会失败.然后它假定你的round/roundf函数被定义为
int round(); int roundf();
因为在C99之前的时代还没有这样的函数,所以它没有声明,然后隐式声明它们.这显然会失败,因为调用端将返回值视为int,而被调用方(在链接库中的那些函数的定义中)返回float.我得到这些结果例如:
[js@HOST2 cpp]$ ./a.out 1065353216.000000 -1048576.000000 [js@HOST2 cpp]$
不是你现在认为你可以将返回值强制转换为浮点值并且没问题.嗯,情况更糟.返回值甚至不保证与返回的float有任何关系.调用端从一个知道返回整数的位置读取.但是你的编译器可能会从被调用方返回另一个地方(例如浮点指针寄存器中)的浮点数.上面实际上可以做任何事情,包括中止程序,因为它以不确定的方式运行.
那么,你能做些什么让它发挥作用?通过编译器std=c99
标志或使用其他方式来舍入(floor是其中之一),不需要这些功能
gcc -std=c99 test.c -lm
请参阅的联机帮助页man 3 round
.但是,如果你有一个非常老的GCC - 我不确定它是否支持足够的C99来进行那个转换.然后查看圆形联机帮助页中描述的功能测试宏.