3

おはようございます、

FITS ファイル (単一の数値の整数部分と浮動小数点部分を表す) から 2 つの数値を読み取り、それらを long double (私のマシンでは 128 ビット) に変換してから合計しています。

結果は、128 ビット浮動小数点を使用した場合に期待するほど正確ではありません。コードは次のとおりです。

a_int = np.longdouble(read_header_key(fits_file, 'I'))
print "I %.25f" % a_int, type(a_int)
a_float = np.longdouble(read_header_key(fits_file, 'F'))
print "F %.25f" % a_float, a_float.dtype
a = a_int + a_float
print "TOT %.25f" % a, a.dtype

そして、ここに私が得る答えがあります:

I 55197.0000000000000000000000000 <type 'numpy.float128'>
F 0.0007660185200000000195833 float128
TOT 55197.0007660185219720005989075 float128

結果は、10 進数 11 桁 (合計で有効桁数 16 桁) の後で、私が期待するもの (55197.0007660185200000000195833) とは異なります。128 ビットの浮動小数点数からは、はるかに優れた精度が期待できます。私は何を間違っていますか?

この結果は、Mac マシンと Linux 32 ビット マシンで再現されました (その場合、dtype は float96 でしたが、値はまったく同じでした)。

よろしくお願いします。

マッテオ

4

2 に答える 2

3

問題は、の印刷にありますnp.longdouble。を使用してフォーマットする%fと、Python は結果を出力する前に float (64 ビット) にキャストします。

ここ:

>>> a_int = np.longdouble(55197)
>>> a_float = np.longdouble(76601852) / 10**11
>>> b = a_int + a_float
>>> '%.25f' % b
'55197.0007660185219720005989075'
>>> '%.25f' % float(b)
'55197.0007660185219720005989075'
>>> b * 10**18
5.5197000766018519998e+22

私のマシンでは、longdouble通常よりも少しだけ精度が高いことに注意してくださいdouble(小数点以下 15 桁ではなく 20 桁)。Decimalそのため、モジュールがアプリケーションにより適しているかどうかを確認する価値があります。Decimal精度を落とさずに任意精度の 10 進浮動小数点数を処理します。

于 2013-02-14T13:52:21.590 に答える
3

私の推測では、%f修飾子は longdouble オブジェクトから float を構築し、フォーマット文字列を作成するときにそれを使用します。

>>> import numpy as np
>>> np.longdouble(55197)
55197.0
>>> a = np.longdouble(55197)
>>> b = np.longdouble(0.0007660185200000000195833)
>>> a
55197.0
>>> b
0.00076601852000000001958
>>> a + b
55197.00076601852
>>> type(a+b)
<type 'numpy.float128'>
>>> a + b == 55197.00076601852
False

補足としてrepr、オブジェクトを再構築するのに十分な数字を出力しません。これは単に、に渡すのに十分な float リテラルを使用できないためですlongdouble

于 2013-02-14T13:50:17.460 に答える