Ben*_*ank 22 python floating-point
我最近发现x**.5并且math.sqrt(x)并不总是在Python中产生相同的结果:
Python 2.6.1 (r261:67517, Dec 4 2008, 16:51:00) [MSC v.1500 32 bit (Intel)]
on win32
>>> 8885558**.5 - math.sqrt(8885558)
-4.5474735088646412e-13
Run Code Online (Sandbox Code Playgroud)
检查低于10**7的所有整数,这两种方法对几乎正好0.1%的样本产生不同的结果,对于较大的数字,误差的大小增加(缓慢).
所以问题是,哪种方法更准确?
Unk*_*own 25
两者都不是更准确,它们都是等分的实际答案:
>>> (8885558**0.5)**2
8885557.9999999981
>>> sqrt(8885558)**2
8885558.0000000019
>>> 2**1023.99999999999
1.7976931348498497e+308
>>> (sqrt(2**1023.99999999999))**2
1.7976931348498495e+308
>>> ((2**1023.99999999999)**0.5)**2
1.7976931348498499e+308
>>> ((2**1023.99999999999)**0.5)**2 - 2**1023.99999999999
1.9958403095347198e+292
>>> (sqrt(2**1023.99999999999))**2 - 2**1023.99999999999
-1.9958403095347198e+292
Run Code Online (Sandbox Code Playgroud)
http://mail.python.org/pipermail/python-list/2003-November/238546.html
math模块包装了相同名称的平台C库数学函数;
math.pow()如果你需要(或只是想)与调用C的C扩展的高兼容性,它是最有用的pow().
__builtin__.pow()是Python的中缀**运算符的实现,并且处理复数,无界整数幂和模幂运算(Cpow()不处理任何这些).
**更完整.math.sqrt可能只是sqrt的C实现,可能与之相关pow.
Emi*_*l H 11
pow函数和math.sqrt()函数都可以计算比默认浮点类型可以存储的结果更准确的结果.我认为您看到的错误是浮点数学的局限性而不是函数的不准确性的结果.另外,因为当取7位数的平方根时,差异是~10 ^( - 13)?即使是最精确的物理计算也很少需要许多有效数字......
使用math.sqrt()的另一个原因是它更容易阅读和理解,这通常是以某种方式做事的一个很好的理由.
使用decimal找到更精确的平方根:
>>> import decimal
>>> decimal.getcontext().prec = 60
>>> decimal.Decimal(8885558).sqrt()
Decimal("2980.86531061032678789963529280900544861029083861907705317042")
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6028 次 |
| 最近记录: |