关于python浮点数的精度及其造成的问题

Python的默认浮点数是双精度。不过不论是什么精度,浮点数在计算机中都是以二进制保存。这就导致了在有限精度下,电脑为自己把精度范围外的小数“掐掉”,导致结果不准确。以下笔者展现一个经典的例子,0.1 + 0.2,其结果为0.30000000000000004,而不是0.3。经过一些搜索,发现NumPy提供一个相对更高...
关于python浮点数的精度及其造成的问题
在解决学术问题的过程中,Python因为其易用性和语法的简洁性而受到欢迎。然而,在某些实际问题中,由于Python默认的浮点数精度是双精度(64位),直接用此精度会出现非常大的问题。例如,回代根到等式发现等式不成立(从而造成恐慌)。本文记录了一种笔者找到的可能的解决方法用于解决Python精度不够的问题。

Python的默认浮点数是双精度。不过不论是什么精度,浮点数在计算机中都是以二进制保存。这就导致了在有限精度下,电脑为自己把精度范围外的小数“掐掉”,导致结果不准确。以下笔者展现一个经典的例子,0.1 + 0.2,其结果为0.30000000000000004,而不是0.3。

经过一些搜索,发现NumPy提供一个相对更高精度的数值类型numpy.float128()(或者numpy.longdouble(), numpy.longfloat()),它的精度比64位“稍高”。使用numpy.float128()之后,输出的结果更加接近真实值0.3。

这会导致什么问题?在大多数情况下(姑且如此说,毕竟我至今第一次遇到这个问题),不会有很大影响。但这不代表这个问题可以忽略。例如在使用SymPy求解方程时,如果直接使用默认浮点数,得到的结果并不能使等式两边成立。

我们首先尝试将64位浮点数替换为128位浮点数,但不幸的是,这种方法得到的精度提升有限。方程两边仍然无法成立。

通过搜索和求助,我得知了使用decimal包的方法。使用十进制数,这样应该就可以表示准确的小数了。但是如果直接使用SymPy去解方程,仍然不能得到精确结果!我推测SymPy仍然使用了浮点数。

在已知方程系数的情况下,求解方程的根有两种方法。一种是直接使用求根公式,适用于四次及以下的多项式方程。另一种是数值法,可以得到一个自定精度的估计值。

由于Python的decimal包中的Decimal类型的特殊性,许多常用的运算方法并不适用此类数值。接下来记录几种我从官方文档和Wikiversity中找到的常用运算方法。

来自Python官方文档:

来自Wikiversity:

可能有读者会好奇,为什么要摘录arctan()。原因是需要进行复数运算!在次数为2、3、4的一元方程中,非常容易出现复数。我针对自己的问题,对arctan()函数进行了一定的修改,并实现了能够进行复数运算的几种方法。此外,还定义了判断两个数是否相等的函数if_eq()。

到目前为止,我们已经能解决高达四次的一元方程。然而,对于大于或等于五次的多项式来说,现有方法似乎仍然显得黔驴技穷。

在没有求根公式的情况下,数值方法是一个解方程实根的很好途径。我使用了牛顿法来解决问题。参考Kong等人的在线书籍,代码实现如下,

到此为止,我们可以尝试一下,能否使用现有知识求解本文最初设置的方程。首先使用求根公式法,成功得到了方程的解!通过观察可得,仅仅是小数后被掐掉的部分不同,就会造成等式两边产生极大(绝对来说,非相对)的不同!

其次,尝试牛顿数值法。

可以看到,数值法的缺陷是需要设置不同的初值,才能得到不同的实根。但优点是,在计算机性能支持的前提下,可以逼近任意方程的某个根。可能有些读者会好奇,此处的“-10000000000000000000000”为何不需要将其进行“十进制化”?原因是在Python中,整数是精确的,不精确的只是浮点数。

本文讨论了在某些特殊方程中因为Python浮点数不够精确而导致的结果不精确的问题。当对结果的精度要求较高或者根的量级非常大时,推荐使用先求初值、再求精确值的方法进行求解。2024-10-16
mengvlog 阅读 11 次 更新于 2025-07-20 15:09:17 我来答关注问题0
  • 是的,Python的浮点数运算确实存在精度问题。这主要是由于计算机内部以二进制方式表示浮点数时存在的固有限制。以下是关于Python浮点数精度问题的详细解释:二进制表示的限制:在计算机硬件中,浮点数是以二进制小数表示的。与十进制数相比,二进制数在表示某些小数时可能无法精确表示,导致精度损失。IEEE 754...

  • Python的默认浮点数是双精度。不过不论是什么精度,浮点数在计算机中都是以二进制保存。这就导致了在有限精度下,电脑为自己把精度范围外的小数“掐掉”,导致结果不准确。以下笔者展现一个经典的例子,0.1 + 0.2,其结果为0.30000000000000004,而不是0.3。经过一些搜索,发现NumPy提供一个相对更高...

  •  翡希信息咨询 python float浮点数运算精度问题,及解决方法

    Python中float浮点数运算存在精度问题,可以通过使用decimal模块来解决。精度问题原因: 浮点数在计算机内部的存储并非无限精确,这导致了在运算过程中可能会出现精度误差。例如,2.01和3.02相加时,结果可能并非预期的5.03,而是类似5.029999999999999这样的数值。解决方法: 使用decimal模块:Python提供了decima...

  •  翡希信息咨询 详谈python中的小数运算,以及四舍五入不精确问题

    Python中的小数运算存在精度损失问题,主要是由于二进制与十进制之间的转换以及IEEE 754标准的浮点数存储方式。四舍五入不精确问题源于浮点数的不精确存储,可以通过Decimal和Fraction模块来解决。1. 精度损失与IEEE 754标准 二进制与十进制转换:绝大多数小数无法用二进制精确表示,这导致了在计算机中进行小...

  • 针对这个问题,Python提供了decimal模块作为解决浮点数精度问题的工具。Decimal()函数可以确保浮点数运算的精度,但使用时需特别注意,需要将原始浮点数转换为字符串形式,如"1.02",而非直接传递数字。这样可以避免因类型转换导致的精度损失。通过引入decimal模块,我们可以在处理金融计算、科学计算等对精度要求...

檬味博客在线解答立即免费咨询

Python相关话题

Copyright © 2023 WWW.MENGVLOG.COM - 檬味博客
返回顶部