Python中实现精确的浮点数运算详解

拾柒
拾柒
发布时间:2026-10-13| 2人浏览过
原创

本文深入解析Python中浮点数缺乏精确性的根本原因,即实数无限精度与计算机有限内存的矛盾。通过对比标准浮点运算与Decimal模块,展示如何利用字符串表示数字来消除舍入误差,并提供控制精度和四舍五入的具体代码示例,适用于对计算精度有严格要求的场景。

为什么说浮点数缺乏精确性?

在深入探讨之前,有必要先厘清浮点数为何缺乏精确性。这并非Python独有的问题,而是源于实数具有无限精度而计算机内存有限的根本矛盾。

举例来说,假设我们只能使用整数(即精度仅保留到个位,计算机中的浮点数同样受限于有限精度,以C语言中的双精度浮点数double为例,其精度为52个二进制位)。当试图表示任意实数(无限精度)时,只能通过舍入(rounding)来进行近似表示。

例如,1.2会被表示为1,2.4表示为2,3.6表示为4。

那么结果如何?

在计算1.2 - 1.2时,由于计算机内部的表示问题,实际执行的运算是1 - 1,结果为0,这恰好碰巧正确;

在计算1.2 + 1.2 - 2.4时,由于同样的表示问题,实际执行的运算是1 + 1 - 2,结果仍为0,再次碰巧正确;

然而,在计算1.2 + 1.2 + 1.2 - 3.6时,由于表示问题,实际执行的运算是1 + 1 + 1 - 4,结果为-1,这次运气就不太好了!

这里的1.2、2.4、3.6相当于问题中提到的0.1、0.2和0.3,而1、2、4则是计算机内部真正参与运算的数值。这样解释是否清楚?

其他相关信息可参考IEEE 754浮点数标准,例如CSAPP第二章的内容(虽然可能读者对此兴趣不大)。

另外:不仅浮点数在计算机内部的表示存在误差,运算过程本身也可能产生误差。例如,整数2可以在计算机内准确表示,但计算根号2时就会产生误差;再如,两个浮点数相除,虽然被除数和除数都是精确表示的,但除法结果的精度可能超出计算机内实数的表示范围,从而引入误差。

好了,下面进入正文:

起步

浮点数的一个普遍问题是它们无法精确表示十进制数。

>>> a = 4.2
>>> b = 2.1
>>> a + b
6.300000000000001
>>> (a + b) == 6.3
False
>>>

这是由于底层CPU和IEEE 754标准通过其浮点单元执行算术时的特性所致。看似有限的小数,在计算机的二进制表示中却是无限的。

通常情况下,这种微小的误差是可以接受的。如果不能容忍这种误差(例如在金融领域),则需要考虑采用其他解决方案。

Decimal

使用此模块可避免任何微小误差。

>>> from decimal import Decimal
>>> a = Decimal('4.2')
>>> b = Decimal('2.1')
>>> a + b
Decimal('6.3')
>>> print(a + b)
6.3
>>> (a + b) == Decimal('6.3')
True

尽管代码看起来有些奇特,使用字符串来表示数字,但Decimal支持所有常用的数学运算。decimal模块允许你控制计算的各个方面,包括数字位数和四舍五入。在这样做之前,需要创建一个临时上下文环境来更改这些设置:

>>> from decimal import Decimal, localcontext
>>> a = Decimal('1.3')
>>> b = Decimal('1.7')
>>> print(a / b)
0.7647058823529411764705882353
>>> with localcontext() as ctx:
...  ctx.prec = 3
...  print(a / b)
...
0.765
>>> with localcontext() as ctx:
...  ctx.prec = 50
...  print(a / b)
...
0.76470588235294117647058823529411764705882352941176
>>>

由于Decimal的高精度数字自然也就用字符串来做展示和中转。

总结

总的来说,当涉及金融领域时,哪怕是一点小小的误差在计算过程中都是不允许的。因此decimal模块为解决这类问题提供了方法。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对本站的支持。

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。