Skip to main content
 首页 » 编程设计

Python:如何解决基本 "chaos theory"程序中的舍入错误

2025年05月04日23落叶无声

我是从 Zelle 的 Python 简介学习 Python 的,并遇到了以下示例,该示例是一个基于初始输入模拟混沌输出的基本程序。

 def main(): 
     print("This program illustrates a chaotic function") 
     x = eval(input("Enter a number between 0 and 1: ")) 
     for i in range(10): 
         x = 3.9 * x * (1 - x) 
         print(x) 
 
main() 
 
This program illustrates a chaotic function 
 
Enter a number between 0 and 1: .15 
0.49724999999999997 
0.97497050625 
0.09517177095121285 
0.3358450093643686 
0.8699072422927216 
0.4413576651876355 
0.9615881986142427 
0.14405170611022783 
0.48087316710014555 
0.9735732406265619 

我知道这种舍入错误对于 Python 中默认的 double float 据类型是不可避免的。例如,第一个输出值正好是 0.49725。我从某个地方读到舍入错误可以通过使用 Python 的 decimal 库中的 Decimal 函数来解决。所以我稍微修改了程序:

from decimal import Decimal 
 
def main(): 
    print("This program illustrates a chaotic function") 
    x = Decimal(eval(input("Enter a number between 0 and 1: "))) 
    for i in range(10): 
        x = Decimal(Decimal(3.9) * x * (Decimal(1) - x)) 
        print(x) 
 
main() 
 
This program illustrates a chaotic function 
 
Enter a number between 0 and 1: .15 
0.4972499999999999735211808627 
0.9749705062499999772282405220 
0.09517177095121305485295678083 
0.3358450093643692781451067085 
0.8699072422927223412528927684 
0.4413576651876335014022344487 
0.9615881986142417803060044330 
0.1440517061102311988874201782 
0.4808731671001548246798042829 
0.9735732406265634386141115723 

有什么方法可以解决这个问题,以便准确表示像 0.49725 这样的精确输出值吗?如何处理此类问题?

请您参考如下方法:

问题来自您正在使用的中间步骤:eval 调用(无论如何这都不是将用户输入解析为 float 的最佳方式 - float 功能更安全)。这会将用户的输入评估为 Python 解释器 native 将其解析为的内容,在本例中为 float 。这意味着当您执行 Decimal(eval(input())) 时,您在将数据传递给 Decimal 之前已经干扰了数据,它仅适用于它的内容给出。删除 eval 调用并让 Decimal 本身处理用户的输入。此外,您必须擦洗所有其他原生 float ,例如Decimal(3.9),它从 3.9 first 创建一个 float ,然后再从中创建一个 Decimal。您可以通过将字符串传递给 Decimal 来避免这种情况。

>>> Decimal(Decimal(3.9) * Decimal(eval('.15')) * (Decimal(1) - Decimal(eval('.15')))) 
Decimal('0.4972499999999999735211808627') 
>>> Decimal(Decimal(3.9) * Decimal(.15) * (Decimal(1) - Decimal(.15))) 
Decimal('0.4972499999999999735211808627') 
>>> Decimal(Decimal(3.9) * Decimal('.15') * (Decimal(1) - Decimal('.15'))) 
Decimal('0.4972499999999999886757251488') 
>>> Decimal(Decimal('3.9') * Decimal('.15') * (Decimal('1') - Decimal('.15'))) 
Decimal('0.49725')