当前位置:首页>python>Python 浮点数陷阱详解:如何完美解决 x * 0.1 的精度问题

Python 浮点数陷阱详解:如何完美解决 x * 0.1 的精度问题

  • 2026-09-23 21:26:06
Python 浮点数陷阱详解:如何完美解决 x * 0.1 的精度问题

1. 现象: 为什么读到的温度计数据小数位有那么多?

刚到了一个温湿度传感器,我就把他接入到八哥开关小帮手上面。 数据是通过Modbus-RTU的协议传输到服务器上,是一个整型 int16AB 编码,刚好是10倍的关系, 计算公式为 value = 0.1 * read_value。 计算出来的数据很奇怪,18.9000000000002,后面多出来了好多的小数点,用眼睛看就知道有问题了。 我们希望的是得到 18.9,但计算机给出了一个带有微小“尾巴”的数字。这并不是 Python 的 bug,而是计算机底层存储浮点数方式导致的物理限制。

2. 原理:二进制的世界没有 0.1

在十进制中,

 是无限循环小数 (0.3333...);同理,在二进制中,

(即 0.1) 也是一个无限循环小数:

因为计算机的存储空间(53位有效数字)是有限的,它必须在某一位进行截断。这种截断导致了微小的精度丢失,就像把 0.3333... 截断为 0.3333 一样,结果虽然极其接近,但在数学上并不完全相等。

3. 采用 decimal 金融级精确计算来解决

Decimal 模块模拟了人类手算的方式,避免了二进制转换误差,这样我们算出来的数据就不会出现那么多的小数位了。

Python

from decimal import Decimal# 核心原则:必须以 '字符串' 形式初始化a = Decimal('189')b = Decimal('0.1')print(a * b)  # 输出: 18.9 (类型为 Decimal)

警告:如果写成 Decimal(0.1),由于括号内的 0.1 已经是浮点数,误差会被带入 Decimal 中,导致前功尽弃。

4. 终于没有那么多的小数位了

经过 Decimal 的处理,终于可以计算出正确的数字了,没有那么多的小数位。

最新文章

随机文章