我试图编写一个函数来近似平方根(我知道有数学模块......我想自己做),但我被浮点运算搞砸了。如何避免这种情况?
def sqrt(num):
root = 0.0
while root * root < num:
root += 0.01
return root
使用它会产生以下结果:
>>> sqrt(4)
2.0000000000000013
>>> sqrt(9)
3.00999999999998
我意识到我可以使用round()
,但我希望能够使其非常准确。我希望能够计算出 6 或 7 位数字。如果我四舍五入的话这是不可能的。我想了解如何在 Python 中正确处理浮点计算。
最佳答案
这实际上与 Python 无关 - 您会在使用硬件的二进制浮点算术的任何语言中看到相同的行为。第一 read the docs .
读完后,您将更好地理解您没有在代码中添加百分之一。这正是您要添加的内容:
>>> from decimal import Decimal
>>> Decimal(.01)
Decimal('0.01000000000000000020816681711721685132943093776702880859375')
该字符串显示二进制浮点(C 中的“ double ”)的精确十进制值,近似于精确的十进制值 0.01。您真正要添加的内容比 1/100 稍大一些。
控制 float 值误差是一个称为“数值分析”的领域,是一个非常庞大和复杂的主题。只要您对 float 只是十进制值的近似值感到惊讶,就可以使用 decimal
模块。这将为您消除一个充满“肤浅”问题的世界。例如,对您的函数进行这个小修改:
from decimal import Decimal as D
def sqrt(num):
root = D(0)
while root * root < num:
root += D("0.01")
return root
然后:
>>> sqrt(4)
Decimal('2.00')
>>> sqrt(9)
Decimal('3.00')
它并不是真的更准确,但在简单的示例中可能并不那么令人惊讶,因为现在它恰好增加了百分之一。
另一种方法是坚持使用 float ,并添加一些可以完全表示为二进制 float 的东西:I/2**J
形式的值。例如,不要添加 0.01,而是添加 0.125 (1/8) 或 0.0625 (1/16)。
然后查找“牛顿法”来计算平方根;-)
关于python - 如何避免浮点错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52731171/