web-dev-qa-db-ja.com

16331239353195370.0に特別な意味はありますか?

import numpy as npを使用すると、

np.tan(np.pi/2)

np.infではなくタイトルに番号を付けます

16331239353195370.0

この数字に興味があります。システムマシンの精度パラメーターに関連していますか?何かから計算できましたか? (私はsys.float_infoに似た何かの線に沿って考えています)

編集:同じ結果は、Java、octace、matlabなどの他の環境でも実際に再現可能です。

87
Aguy

piは、Python float(プラットフォームCのdoubleタイプと同じ)として正確に表現できません。最も近い表現可能な近似が使用されます。

これは私のボックスで使用されている正確な近似です(おそらくあなたのボックスと同じです):

_>>> import math
>>> (math.pi / 2).as_integer_ratio()
(884279719003555, 562949953421312)
_

その比率の正接を見つけるために、wxMaximaに切り替えます。

_(%i1) fpprec: 32;
(%o1) 32
(%i2) tan(bfloat(884279719003555) / 562949953421312);
(%o2) 1.6331239353195369755967737041529b16
_

だからあなたが得たものと本質的に同一です。使用される_pi/2_のバイナリ近似は、_pi/2_の数学的な(「無限精度」)値よりも少し小さくなります。したがって、infinityの代わりに非常に大きな接線を取得します。計算されたtan()は、実際の入力に適しています!

まったく同じ理由で、例えば、

_>>> math.sin(math.pi)
1.2246467991473532e-16
_

近似値_math.pi_はpiより少し小さく、表示される結果は正しい与えられたその真実。

他の見方math.pi

使用中の正確な近似値を確認するには、いくつかの方法があります。

_>>> import math
>>> math.pi.as_integer_ratio()
(884279719003555, 281474976710656)
_

_math.pi_は、その比率の数学的な(「無限精度」)値と正確に等しい。

または、16進表記の正確なフロートとして:

_>>> math.pi.hex()
'0x1.921fb54442d18p+1'
_

または、ほぼ全員が最も簡単に理解できる方法で:

_>>> import decimal
>>> decimal.Decimal(math.pi)
Decimal('3.141592653589793115997963468544185161590576171875')
_

すぐには明らかではないかもしれませんが、すべての有限バイナリ浮動小数点は、有限10進浮動小数点として正確に表現できます(逆はnot trueです。たとえば、10進数_0.1_は有限バイナリとして正確に表現できませんfloat)、およびDecimal(some_float)コンストラクターはまったく同じものを生成します。

piの真の値に続いて_math.pi_の正確な10進数値が続き、3行目のキャレットは異なる最初の桁を指します。

_true    3.14159265358979323846264338327950288419716939937510...
math.pi 3.141592653589793115997963468544185161590576171875
                         ^
_

_math.pi_は、ほぼすべてのボックスで同じバイナリ浮動小数点形式(IEEE 754倍精度)を使用するようになったため、「ほぼすべての」ボックスで同じになりました。上記の方法のいずれかを使用して、yourボックスで確認するか、ボックスが例外の場合に使用中の正確な近似値を見つけることができます。

117
Tim Peters