Python:如何在基本的"混沌理论"程序中解决舍入错误?

u23*_*u23 1 python precision

我从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
Run Code Online (Sandbox Code Playgroud)

我知道Python中的默认双精度浮点数据类型不可避免地存在这种舍入错误.例如,第一个输出值恰好是0.49725.我从某处读到可以通过使用Python的十进制库中的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
Run Code Online (Sandbox Code Playgroud)

有没有办法解决这个问题,确切的输出值如0.49725?这样的问题如何处理?

Tig*_*kT3 5

问题来自您正在使用的中间步骤:eval调用(这不是将用户输入解析为浮点数的最佳方法 - float函数更安全).这会将用户的输入计算为Python解释器本身将其解析为的内容,在这种情况下,这将是一个浮点数.这意味着当你这样做时Decimal(eval(input())),你已经在传递数据之前已经干扰了数据Decimal,这只是与它给出的内容有关.删除eval呼叫并让Decimal自己处理用户的输入.此外,你必须擦洗所有其他本地浮动,例如Decimal(3.9),它创建了一个浮出的3.9 首先创建之前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')
Run Code Online (Sandbox Code Playgroud)