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
使用される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倍精度)を使用するようになったため、「ほぼすべて」のボックスで同じになりました。上記のいずれかの方法を使用して、ボックスでそれを確認したり、ボックスが例外である場合に使用されている正確な概算を見つけることができます。