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


88

使用してimport numpy as np私はそれに気づいた

np.tan(np.pi/2)

タイトルに番号を付けますが、 np.inf

16331239353195370.0

この数が気になります。それはいくつかのシステムマシンの精度パラメータに関連していますか?何かから計算できたでしょうか?(私は似たようなものの線に沿って考えていますsys.float_info

編集:同じ結果は、Java、octace、matlabなどの他の環境でも実際に再現可能です...しかし、提案された複製は理由を説明していません。



10
私はその答えが好きではありません-それは完全に手で波打っていて、実際には原因を説明していません。「まあ、ラジアンのtan(pi / 2)は本質的に無限ですよね?」OPがここで尋ねたように、理由については何も説明していませんが、答え実際にはありませんnp.inf。しかし、なぜそうではないのかを説明するだけでなく、答えが正確に見られたものである理由も説明するのは簡単です-そして私はそうしました;-)
ティムピーターズ

回答:


119

piPython 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使用される2進近似は、の数学的(「無限精度」)値よりも少し小さくなりますpi/2。したがって、の代わりに非常に大きな接線が得られますinfinity。計算tan()は実際の入力に適しています!

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

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

は0を返しません。近似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進数フロートとして正確に表現でき(逆は当てはまりません。たとえば、10進数0.1は有限バイナリフロートとして正確に表現できません)、Decimal(some_float)コンストラクターは正確に同等のものを生成します。

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

true    3.14159265358979323846264338327950288419716939937510...
math.pi 3.141592653589793115997963468544185161590576171875
                         ^

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


@ TimPeters-これは完全に明らかです。完全を期すために、この表現はnp.piシステムのイプシロン内に最も近い合理的な表現であると推測していますか?
Aguy 2016

3
np.piPythonと同じ値を持っていると仮定するとmath.pi(私はチェックしませんでしたが、できます;-))、プラットフォームのネイティブC double浮動小数点形式で表現できる数学的な円周率に最も近い値です。これは、現在ほとんどすべてのボックスでIEEE 754倍精度を意味しているため、53ビット(仮数)の精度で最も近いバイナリ浮動小数点数になります。したがって、有理数のセットは+/- I * 2**J、整数Iが0またはである形式に制約され、整数2**52 <= I < 2**53の範囲はJ、この形式のすべての有理数をカバーするのに十分な広さpiです。
ティム・ピーターズ

2
そして、これが「バイナリ」三角関数がより一般的に実装されていればいいのですが。piは合理的に表現することはできませんので、それは0から1までの角度で動作する関数のセットと便利だろう
パイプ

まあ、彼らは輸入しましたnp.pi、ではありませんmath.pi
EKons 2016

2
@ΈρικΚωνσταντόπουλος math.pinp.piscipy.piすべて同じです。名前を付けるためだけに複製されています。stackoverflow.com/questions/12645547/…–
Tim Peters
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.