python - Python:如何解决基本“混沌理论”程序中的舍入错误?
问题描述
我从 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 中默认的双精度浮点数据类型是不可避免的。例如,第一个输出值正好是 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
有没有办法解决这个问题,以便准确表示像 0.49725 这样的精确输出值?此类问题如何处理?
解决方案
问题来自您正在使用的中间步骤: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')
推荐阅读
- ruby - 如何从 cron 作业调用的脚本中停止服务?
- python - 如何让我的服务器通过 UDP 多播到 Internet 上的客户端?我需要一个特殊的多播 IP 地址吗?
- python - Python,函数,这里发生了什么?如果 lst1[index] != lst2[len(lst2) - 1 - index]
- javascript - 在 Node 中设置 AWS 开发工具包凭证
- ios - 我的 TableView 只列出了 itemArray 中的最后一项?
- amazon-web-services - aws Lex UI 不显示来自其他帐户的 lambda 函数
- django - Django 查询集获得前 3 名用户
- python - repo.checkout() :您对以下文件的本地更改将被 checkout 覆盖
- flutter - 谷歌使用 Flutter/Firebase 登录时如何获取 refreshToken
- javascript - 如何将事件侦听器添加到按钮元素