我从中得到了意想不到的结果round()
and roundf()
中的函数math.h
图书馆。这是示例代码:
#include <stdio.h>
#include <math.h>
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
很奇怪吧?
Update:除了答案之外,我还确认代码可以在较新的编译器上正常工作。 (我认为 %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)
如果你编译代码而不告诉 gcc 使用 C99 模式编译,你可能会失败(-std=c99
)并告诉它不要知道“特殊内置”函数(使用-fno-builtin
)。然后假设您的 round/roundf 函数定义为
int round();
int roundf();
因为在 C99 之前的时代还没有这样的函数,所以它没有声明,然后隐式声明它们。这显然会失败,因为调用方将返回值视为 int,而被调用方(在链接库中这些函数的定义中)返回浮点数。例如,我得到这些结果:
[js@HOST2 cpp]$ ./a.out
1065353216.000000
-1048576.000000
[js@HOST2 cpp]$
并不是说您现在认为可以将返回值转换为浮点数就可以了。嗯,情况更糟。甚至不能保证返回值与返回的浮点数有任何关系。调用方从它知道返回整数的位置读取。但是您的编译器可能会从被调用方在另一个位置(例如,在浮点指针寄存器中)返回浮点数。上面的代码实际上可以做任何事情,包括中止程序,因为它的行为方式未定义。
那么,你能做些什么来让它发挥作用呢?传递给编译器std=c99
标记或使用其他不需要这些功能的方式进行舍入(地板是其中之一)
gcc -std=c99 test.c -lm
请参阅联机帮助页man 3 round
。但是,如果您有一个非常旧的 GCC - 我不确定它是否支持足够的 C99 来进行该切换。然后查看 round 的联机帮助页中描述的功能测试宏。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)