V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
CoooolChan
V2EX  ›  问与答

为什么很多编程语言都采用IEEE754格式编码数字,然后就产生0.1+0.2 != 0.3这样的事情,没有更合理的吗?

  •  
  •   CoooolChan · 2013-06-08 17:47:49 +08:00 · 5055 次点击
    这是一个创建于 3988 天前的主题,其中的信息可能已经有所发展或是发生改变。
    20 条回复    1970-01-01 08:00:00 +08:00
    wy315700
        1
    wy315700  
       2013-06-08 18:11:36 +08:00
    float型的一般不直接比较 都是用的 abs((0.1+0.2) - 0.3) <= inf 做比较的
    clowwindy
        2
    clowwindy  
       2013-06-08 18:39:32 +08:00   ❤️ 1
    让我想起了用 Quartz 想顺时针画一个 2pi 的圆,会什么也画不出来。

    苹果文档:

    Note that using values very near 2π can be problematic. For example,
    setting `startAngle' to 0, `endAngle' to 2π, and `clockwise' to true will
    draw nothing. (It's easy to see this by considering, instead of 0 and 2π,
    the values ε and 2π - ε, where ε is very small.) Due to round-off error,
    however, it's possible that passing the value `2 * M_PI' to approximate
    2π will numerically equal to 2π + δ, for some small δ; this will cause a
    full circle to be drawn.

    If you want a full circle to be drawn clockwise, you should set
    `startAngle' to 2π, `endAngle' to 0, and `clockwise' to true. This avoids
    the instability problems discussed above.
    hadoop
        3
    hadoop  
       2013-06-08 19:34:54 +08:00 via Android
    数学上的小数点后面可以有成千上万位,但是计算机无法有效的用二进制表示
    luikore
        4
    luikore  
       2013-06-08 20:27:35 +08:00
    0.3 和 0.299999 哪个更精确? 上过高中都知道是后者
    CoooolChan
        5
    CoooolChan  
    OP
       2013-06-08 21:22:28 +08:00
    @luikore 那1和0.99999999999还相等呢
    013231
        6
    013231  
       2013-06-08 21:30:02 +08:00
    有限長度的字節可表示的狀態是有限的, 實數的數量是無限的, 無論你怎麼設計數字編碼方案, 總有無窮多個數無法表示.
    iloahz
        7
    iloahz  
       2013-06-08 23:39:16 +08:00
    @wy315700 inf -> eps?
    chon
        8
    chon  
       2013-06-08 23:48:23 +08:00
    因为不是所有的数字都能用二进制表示
    因此用二进制表示,不惯是什么编码方案,都不能做到非常精确
    csx163
        9
    csx163  
       2013-06-08 23:53:06 +08:00
    最讨厌浮点了(游戏作弊方面)
    wy315700
        10
    wy315700  
       2013-06-09 15:01:07 +08:00
    @iloahz 好吧 好久没写了 都忘了
    rrfeng
        11
    rrfeng  
       2013-06-09 16:53:57 +08:00
    引申一下:
    有没有可能建立完全精确的实数运算器?及其相应的算法?
    luikore
        12
    luikore  
       2013-06-09 17:12:35 +08:00
    @rrfeng 不可能, 宇宙有限, 实数无限
    skydiver
        13
    skydiver  
       2013-06-09 17:18:01 +08:00
    当然可以了,那些科学计算软件计算的肯定是精确值啊。。

    只不过计算机浮点指令就是按照这种标准制定的,所以直接这么存储可以直接用浮点指令。如果想要精确的结果只能用间接的方法了,效率会降低。
    RisingV
        14
    RisingV  
       2013-06-09 17:26:16 +08:00
    现有存储介质都是2进制。
    2进制的进制基数是2,那么一个数字只要被因素包含大于2的质数的数除,都会产生无限循环小数。

    无限循环小数和无理数都无法,和非无限循环的有理数一起用同一种方式存储到存储介质上的同时
    还保持计算的兼容性。

    对于无限循环小数,可以设计一种格式存储到介质上,但是同时又要和非无限循环的有理数能够计算,效率应该会变得非常低下。

    对于无理数,小数位的数字没有规律可循,所以根本无法保存精确值,只能保存近似值。

    高精度计算,一般可以将数字转发成string, 去掉小数点,按位计算再保存回string,再加回小数点。
    rrfeng
        15
    rrfeng  
       2013-06-09 17:28:01 +08:00
    @luikore
    python 不是新增了 [实数] 表示么

    我觉得是可以的,以现在的硬件,模仿手工算法来进行计算
    至少有理数完全可以实现吧,设计分数运算规则和存储规则即可。

    无理数不好确定……
    davepkxxx
        16
    davepkxxx  
       2013-06-09 17:51:52 +08:00
    各个语言对于浮点类型数据的比较一般都会有个允许偏差的范围。
    davepkxxx
        17
    davepkxxx  
       2013-06-09 17:52:44 +08:00
    我遇到过最厉害的还是有部分语言不支持浮点类型。
    luikore
        18
    luikore  
       2013-06-09 18:04:50 +08:00
    @rrfeng 你说的是十进制表示而不是无限精确计算, 例如 √2 是不可能用十进制小数精确表示的
    est
        19
    est  
       2013-06-09 18:41:10 +08:00
    每个语言都支持 IEEE754 的原因是:现代CPU的FPU都是基于IEEE754。

    你用算数方法去精确n位的计算也可以,但是硬件FPU效率可以秒杀你一条银河系。

    如果实在有精确浮点的需要,可以使用一些软浮点大数库。
    rrfeng
        20
    rrfeng  
       2013-06-10 06:32:03 +08:00
    @luikore
    想了一下,我原来的期望是,运算过程不损失精度,得到一个特定的表示方式的结果,然后取值的时候只要进行一种/一次 会丢失精度的运算过程,而且可以方便的获得任意精度的最终结果。

    比如有理数运算,完全可以基于分数表示法和分数运算法则,最后得到一个分数。这个是精确的,我们要取值的时候,只要做一次除法运算,就可以了

    但实际上除法运算不是基本运算……呃 无解么
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3790 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 39ms · UTC 04:35 · PVG 12:35 · LAX 21:35 · JFK 00:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.