代码之家  ›  专栏  ›  技术社区  ›  user366312

为什么这个浮点值会从它设置的值改变?

  •  7
  • user366312  · 技术社区  · 15 年前

    为什么这个C程序输出“错误”?

    #include<stdio.h>
    
    void main()
    {
        float f = 12345.054321;
    
        printf("%f", f);
    
        getch();
    }
    

    输出:

    12345.054688
    

    但是输出应该是, 12345.054321 .

    我在VS2008中使用VC++。

    5 回复  |  直到 15 年前
        1
  •  10
  •   paxdiablo    15 年前

    它给出了“错误”的答案,仅仅是因为并非所有的实际值都可以用浮点(或双精度)表示。您将得到一个基于底层编码的近似值。

    为了表示每个实际值,即使在1.0x10之间 - 100 1.1x10 - 100 (一个真正微小的范围),您仍然需要无限多的位。

    单精度IEEE754值只有32位可用(其中一些用于指数和NAN/INF表示等其他任务),因此不能提供无限精度。它们实际上有23个可用位,精度约为2 二十四 (有一个额外的隐式位)或刚好超过7位十进制数字(对数 (2) 二十四 )约为7.2)。

    我把“错”这个词用引号括起来,因为它不是 事实上 错了。错误的是你对计算机如何代表数字的理解(不要被冒犯,但在这个误会中你并不孤单)。

    从头到脚 http://www.h-schmidt.net/FloatApplet/IEEE754.html 并在“十进制表示”框中键入您的数字,以查看实际情况。

    如果您想要一个更精确的数字,请使用double而不是float——它们的位数是表示值的两倍(假设您的C实现分别使用ieee754单精度和双精度数据类型来表示float和double)。

    如果您想要任意的精度,您需要使用“bignum”库,比如 GMP 虽然这比本地类型要慢一些,但是要确保您理解这种权衡。

        2
  •  2
  •   CB Bailey    15 年前

    十进制数12345.054321不能准确表示为 float 在你的平台上。您看到的结果是一个十进制近似值,该近似值可以表示为 浮动 .

        3
  •  2
  •   Matt Curtis    15 年前

    float S是关于方便和速度的,使用二进制表示法-如果您关心精度,请使用十进制类型。

    要了解问题,请阅读 每一个计算机科学家都应该知道什么是浮点运算 : http://docs.sun.com/source/806-3568/ncg_goldberg.html

    有关解决方案,请参见 十进制算术常见问题 : http://speleotrove.com/decimal/decifaq.html

        4
  •  0
  •   Martin B    15 年前

    单精度浮点值只能表示大约8到9个有效(十进制)数字。超过这一点,你会看到量化误差。

        5
  •  0
  •   zaf    15 年前

    一切都与精确有关。您的号码不能准确地存储在浮点中。