c - 我如何错误地使用 C 中的 round() 函数?

标签 c

我从 math.h 库中的 round()roundf() 函数得到了意想不到的结果。这是示例代码:

#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

奇怪吧?

更新:连同答案,我已经确认代码在较新的编译器上可以正常工作。 (我认为 %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,而被调用方(在链接库中那些函数的定义中)返回 float。例如,我得到这些结果:

[js@HOST2 cpp]$ ./a.out
1065353216.000000
-1048576.000000
[js@HOST2 cpp]$

并不是说您现在认为可以将返回值转换为 float 就可以了。好吧,情况更糟。甚至不能保证返回值与返回的 float 有任何关系。调用方从它知道返回整数的地方读取。但是你的编译器可能会从被调用方返回另一个地方的 float (比如,在一个 float 指针寄存器中)。上述实际上可以做任何事情,包括中止程序,因为它以未定义的方式运行。

那么,您可以做些什么来让它发挥作用呢?向编译器传递 std=c99 标志或使用其他不需要这些函数的舍入方式(floor 是其中之一)

gcc -std=c99 test.c -lm

请参阅man 3 round 的联机帮助页。但是,如果您有一个非常旧的 GCC - 我不确定它是否支持足够的 C99 来进行该切换。然后查看 round 联机帮助页中描述的功能测试宏。

关于c - 我如何错误地使用 C 中的 round() 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/575936/

相关文章:

c - 屏蔽位运算符

c - 从链表中删除项目导致段错误

c - 当程序完美运行时 Valgrind 大喊大叫 (C)

c++ - 编写软件时 64 位优于 32 位的优势

c - 如何定位字符串中第一次出现的字符串

c - 使用 chdir() 从终端更改目录

c - 我可以将哪些端口用于通讯应用程序

c 程序将两个特定字之间的数据从一个文件复制到另一个文件

c - 声明为 "inline"的函数递归是否合法?

c - 声明一个固定长度字符串的可变长度数组