首页 > 解决方案 > 为什么我的浮点转换为二进制数不适用于某些十进​​制值?

问题描述

这是我将小数转换为二进制数的 python 代码,它适用于一些简单的数字,如 0.75,但是当我给它一些像 0.876 这样的硬数字时,答案将变为 [1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1] 但真正的二进制应该是0.11100000010000011001。我只是不知道为什么,有人可以帮助我吗?

bina = []
ori = 0.5
nextn = 0
def ftob(x):
   global ori
   global nextn
    if x == 0:
        return bina
    else:
        a = x/ori
        if a >= 1:
            bina.append(1)
            nextn = x - ori
            ori = ori/2
        else:
            bina.append(0)
            ori = ori/2
        return ftob(nextn)
print(ftob(0.876))

标签: pythonrecursionbinaryglobal

解决方案


请注意,这是二进制浮点的本质:这不是 Python 中的错误,也不是您的代码中的错误。您将在所有支持硬件浮点运算的语言中看到相同的内容(尽管某些语言可能不会在默认情况下或在所有输出模式下显示差异)。

浮点数在计算机硬件中表示为以 2 为底的(二进制)分数。例如,小数部分

0.125

有值1/10 + 2/100 + 5/1000,以同样的方式二进制分数

0.001

有价值0/2 + 0/4 + 1/8。这两个分数具有相同的值,唯一真正的区别是第一个以 10 为基数的分数符号编写,第二个以 2 为基数编写。

不幸的是,大多数十进制分数不能完全表示为二进制分数。结果是,通常,您输入的十进制浮点数仅与实际存储在机器中的二进制浮点数近似。

有趣的是,有许多不同的十进制数共享相同的最接近的近似二进制分数。例如,数字0.10.100000000000000010.1000000000000000055511151231257827021181583404541015625近似于3602879701896397 / 2 ** 55。由于所有这些十进制值共享相同的近似值,因此它们中的任何一个都可以显示,同时仍保留不变量eval(repr(x)) == x.

从历史上看,Python 提示符和内置repr()函数会选择具有 17 个有效数字的那个,即 0.10000000000000001。从 Python 3.1 开始,Python(在大多数系统上)现在可以选择其中最短的并简单地显示 0.1。

信息来自:https ://docs.python.org/3/tutorial/floatingpoint.html


推荐阅读