python - 为什么我的浮点转换为二进制数不适用于某些十进制值?
问题描述
这是我将小数转换为二进制数的 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))
解决方案
请注意,这是二进制浮点的本质:这不是 Python 中的错误,也不是您的代码中的错误。您将在所有支持硬件浮点运算的语言中看到相同的内容(尽管某些语言可能不会在默认情况下或在所有输出模式下显示差异)。
浮点数在计算机硬件中表示为以 2 为底的(二进制)分数。例如,小数部分
0.125
有值1/10 + 2/100 + 5/1000
,以同样的方式二进制分数
0.001
有价值0/2 + 0/4 + 1/8
。这两个分数具有相同的值,唯一真正的区别是第一个以 10 为基数的分数符号编写,第二个以 2 为基数编写。
不幸的是,大多数十进制分数不能完全表示为二进制分数。结果是,通常,您输入的十进制浮点数仅与实际存储在机器中的二进制浮点数近似。
有趣的是,有许多不同的十进制数共享相同的最接近的近似二进制分数。例如,数字0.1
和0.10000000000000001
都0.1000000000000000055511151231257827021181583404541015625
近似于3602879701896397 / 2 ** 55
。由于所有这些十进制值共享相同的近似值,因此它们中的任何一个都可以显示,同时仍保留不变量eval(repr(x)) == x
.
从历史上看,Python 提示符和内置repr()
函数会选择具有 17 个有效数字的那个,即 0.10000000000000001。从 Python 3.1 开始,Python(在大多数系统上)现在可以选择其中最短的并简单地显示 0.1。
推荐阅读
- mysql - 我应该将每一个有用的值都插入数据库吗?
- node.js - Node.js 不会在 Chrome 上呈现,但会在带有 JWT 身份验证的 Postman 上呈现
- wordpress - 如何展示广告以仅向未登录用户展示广告?
- reactjs - 在 Chrome 中为 React 丢弃选项卡时状态丢失
- racket - Racket v7.0 中的#lang 问题
- javascript - JavaScript 中的表单提交按钮
- reactjs - 使用 AWS Cognito 和 React 仅 Facebook/Google 登录(无用户名/密码)
- c# - 使用数组进行统计(十进制)
- keyboard-shortcuts - Rider :转到下一个建议的键盘快捷键
- javascript - Onclick 进度条