关于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 阅读 38 次 更新于 2025-09-11 00:49:38 我来答关注问题0
  •  翡希信息咨询 详谈python中的小数运算,以及四舍五入不精确问题

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

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

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

  •  阿暄生活 python浮点数的数值范围 python浮点数怎么表示

    通常情况下,Python的浮点数能够表示的数值范围大约是3.4e-38到3.4e+38(这是单精度浮点数的范围,但Python实际上使用的是双精度,即double precision,范围更大)。具体来说,Python浮点数能够安全表示的数值范围从大约-1.798e+308到1.798e+308。表示方法:小数形式:浮点数最直接的表示方法就是使用...

  • 在python中 float是什么意思?float是一种数据类型。浮点型数据类型,FLOAT 数据类型用于存储单精度浮点数或双精度浮点数。浮点数使用?IEEE(电气和电子工程师协会)格式。浮点类型的单精度值具有 4 个字节,包括一个符号位、一个 8 位 二进制指数和一个 23 位尾数。由于尾数的高顺序位始终为 1,因此...

  • 在Python中,float代表了一种数据类型,用于存储具有浮点精度的数值。以下是关于float的详细解释:数据类型:float是Python中的一种基本数据类型,专门用于存储浮点数。数值范围与精度:float类型采用IEEE标准,能够表示大约在3.4E+38到3.4E+38之间的数值范围。float类型的数值精度取决于其存储方式,单精度值...

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

Python相关话题

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