2016-04-17 4 views
0

Python 2.7.10を使用して、私は5 * math.sqrt(3)とmath.sqrt(5 ** 2 * 3)が同じフロート:Python:math.sqrt()の変わった丸め動作

import math 
import decimal 

print decimal.Decimal(5*math.sqrt(3)) 
print decimal.Decimal(math.sqrt(5**2*3)) 
print 5*math.sqrt(3) == math.sqrt(5**2*3) 

戻り

8.660254037844385521793810767121613025665283203125 
8.6602540378443872981506501673720777034759521484375 
False 

彼らは15日、小数点の場所に異なることを示しています。

for j in range(1,10+1): 
    for i in range(1,10+1): 
     a = i*math.sqrt(j) 
     b = math.sqrt(i**2*j) 
     if not(a == b): 
      print [i,j], 

問題[I、J]ペアのリストが含ま:[3、興味深いことに、これは5と3に以下のコードを隣の番号を発生しません平等に障害が発生したために数字のいくつかのペアが表示さ[9,6]、[10,3]、[3,6]、[6,6]、[7,6]、[6] [3,8]、[6,8]、[9,8]、[5,10]、[7,10]、[10,10] ...なぜ丸めが解除されるのか、これらのペアのために、そして他にはありませんか?

+0

Decimalは何を期待していますか? –

+9

興味深い発見の間、それは[浮動小数点数学が壊れている]ためです(http://stackoverflow.com/questions/588004/is-floating-point-math-broken)。これらの値のどちらも「正しい」ものではありません。その違いは、中間丸めにある可能性があります。 – usr2564301

+0

数学は長い10進数で正確な結果を返さないことが知られています。私は "問題のペア"のリストが正確で、文脈になる可能性が高いと疑う。 –

答えて

1

これは浮動小数点演算が難しいためです。どちらの結果も実際には正しくありません。彼らはので、浮動小数点の丸めの問題があり、それは10の累乗に丸めていないので、それは奇妙に見えますが、あなたは、任意精度演算が必要な場合2.

の力が、あなたはこのようにmpmathモジュールを使用することができます。

from mpmath import * 

mp.dps=50 
mp.pretty = True 
sqrt3 = fmul(5, mp.sqrt(3)) 
sqrt75 = mp.sqrt(fmul(power(5,2), 3)) 
print "5*sqrt(3) = ", sqrt3 
print "sqrt(5**2*3) = ", sqrt75 
与え

5*sqrt(3) = 8.6602540378443864676372317075293618347140262690519 
sqrt(5**2*3) = 8.6602540378443864676372317075293618347140262690519 

The link provided by Rad Lexusは、このトピックの良い読み物です。

+0

さらに調べると、私はCで 'sqrt(75.0)'と異なる方法で異なる結果を得ています。 'math.h'のネイティブなsqrt、' [sqrt13'] [この網羅的な概要](http://www.codeproject.com/Articles/69941/Best-Square-Root-Method-Algorithm-Function-Precisi)では2番目のPythonの結果を返します。一方、 'sqrt9'は最初のPythonの結果を**正確に**全ての48桁に与えます!そのバビロニア人はどうですか? – usr2564301

+0

丸めの問題は「浮動小数点のため」だけではありません。 3と75の平方根はどちらも非合理的なので、任意の有理数は近似に過ぎません。 –

+0

@RadLexus「全48桁」は、倍精度計算を使用していたため、同じ倍精度数値しか計算しませんでした。これはそれほど大きな偶然ではありません。最初の17桁の数字が同じになるとすぐに、それ以降の数字はすべて同じになります。 –

関連する問題