【问题标题】:C compiler bug (floating point arithmetic)?C 编译器错误(浮点运算)?
【发布时间】:2013-02-01 03:28:06
【问题描述】:
#include<stdio.h>

int main()
{
    double fract=0;
    int tmp;

    //scanf("%lf",&fract);
    fract=0.312;
    printf("%lf",fract);
    printf("\n\n");
    while(fract>0){
        fract*=(double)10;
        printf("%d ",(int)fract);
        fract-=(int)fract;
    }
    getch();
    return 0;
}

此代码应具有以下输出: 312

但是有些事情不正常..我正在使用 devcpp 4.9.9.2 编译器...

【问题讨论】:

  • 编程的首要规则之一是问题总是在你的代码中。
  • 另外,“有些事情不对劲”真的不能告诉我们任何事情。你为什么不告诉我们你得到的输出?
  • Incorrect floating point math? 的可能重复项

标签: c floating-point


【解决方案1】:

Kernighan 和 Plauger 在他们古老但经典的书 "The Elements of Programming Style" 中说:

  • 一位睿智的老程序员曾经说过“浮点数就像一小堆沙子,每移动一次,就会失去一点沙子,得到一点土”。

他们还说:

  • 10 * 0.1 几乎不是 1.0

两句话都指出浮点运算并不精确。

请注意,一些现代 CPU (IBM PPC) 内置了 IEEE 754:2008 十进制浮点运算。如果使用正确的类型,那么您的计算将是准确的。

【讨论】:

  • 嗯,浮点算术是精确的,不那么精确的是将浮点典型的以 2 为底的尾数转换为以 10 为底的值。
【解决方案2】:

浮点运算令人困惑,并且不能保证其行为直观。

这是一个很好的参考文档:What Every Computer Scientist Should Know About Floating-Point Arithmetic。这是一个很长的文档,因为它是一个复杂的问题。

总结:如果您依赖精确值,请不要使用浮点值。

【讨论】:

    【解决方案3】:

    所以你将 0.3119999999999999999895916591441391574335284531116485595703125 乘以 1000 并截断它得到 311?我看不出问题出在哪里。

    【讨论】:

    • 谢谢。实际上我忘了提到乘以 1000 后将最后 6 位四舍五入的步骤。;-)
    猜你喜欢
    • 2022-12-18
    • 2016-05-31
    • 2018-08-19
    • 1970-01-01
    • 2012-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-21
    相关资源
    最近更新 更多