3

10 バイト (80 ビット) のリトル エンディアン float 値 (またはfloat80) の配列があります。Python 3でこの値を読み取るにはどうすればよいですか?

パッケージstructはサポートしていませんfloat80(不注意にドキュメントを読んでいる可能性があります)。

パッケージarray"struct" と同じパッケージは をサポートしていませんfloat80

パッケージは、またはタイプnumpyをサポートします。とても良いのですが、の末尾に追加して拡張したり、醜いです。このパッケージのインポートには多くの時間がかかります。float128float96\x00float80float96float128

パッケージctypesc_longdouble. それはnumpyよりも何倍も高速sizeof(c_longdouble)ですが、マシンに依存し、80ビット未満になる可能性があり、\x00末尾に追加しfloat80て拡張するのc_longdoubleも醜いです。

更新 1 : 私のgist.githubでコードをテストします。機能decode_str64は醜いですが、機能します。今、私は正しい方法を探しています

4

3 に答える 3

3

私の答えをより論理的な方法で書き直しましょう。

ctypes c_longdoublelongdouble 浮動小数点型は C 標準によって石に設定されておらず、コンパイラに依存しているため、マシンに依存します :( しかし、高精度の浮動小数点数に対して現在使用できる最高のものはまだあります...

numpy を使用する場合は、numpy.longdouble が探しているものです。numpy.float96 または numpy.float128 は非常に誤解を招く名前です。これらは、96 ビットまたは 128 ビットの IEEE 浮動小数点形式を示すものではありません。代わりに、基になる long double 型で使用されるアライメントのビット数を示します。たとえば、x86-32 では、long double は 80 ビットですが、32 ビットのアライメントを維持するために最大 96 ビットまでパディングされ、numpy は this を呼び出しますfloat96。x86-64 では、long double は再び同じ 80 ビット型ですが、64 ビットのアライメントを維持するために最大 128 ビットまでパディングされ、numpy は this を呼び出しますfloat128。余分な精度はありません。追加のパディングだけです。

a を aにするために a\x00の最後に追加するのは醜いですが、結局のところ、それは単なるパディングであり、使用するマシンのアーキテクチャに依存するorです。float80Float96float96float80numpy.longdoublefloat96float128

numpy.float128 の内部精度は?

于 2016-08-09T12:02:43.600 に答える
0

4 (x32) または 16 (x64) バイト境界での拡張精度浮動小数点数のパディング、またはメモリ アライメントが追加さます。 x86 CPU。ヒットの規模を理解するために、Microsoft のいくつかの数値では、DWORD で最大 2 倍の違いが示されています。

このレイアウトは、C のlong doublenumpy発明ではなく、基礎となる C に根付いているためnumpy、「重要な」部分のみを抽出/挿入する方法を提供しようとはしていません。

したがって、パディングのない生データがある場合は、手動でパディングを追加するのが道のりのように見えます。基になるバッファーに直接書き込むことで、プロセスを高速化できます。

fi=np.finfo(np.longdouble)
assert fi.nmant==63 and fi.nexp==15, "80-bit float support is required"
del fi

len_float80=10    #no way to extract this from dtype/finfo
len_padded=np.dtype(np.longdouble).itemsize

f=open('float80.bin','rb')
f_items=os.stat(f.name).st_size//len_float80

n = np.empty(f_items,dtype=np.longdouble)

for i in xrange(f_items):
    raw=f.read(len_float80)
    n.data[i*len_padded:i*len_padded+len_float80]=raw

del f,i,raw,f_items

または、コードを Cython に移植することで、さらに高速化することもできます(生のバッファーを使用する場合、通常の配列のインデックス付けと比較して 100 倍もの高速化が可能です!これはコードの保守性を損なう可能性がありますが、時期尚早の最適化には注意してください)。

あるいは、「交換」形式の場合は、 のような内部表現にバインドされていないものを使用することを検討してくださいsavetxt

于 2016-11-23T04:07:58.640 に答える
0

numpy コンパイラとプラットフォームがサポートしている場合、80 ビット浮動小数点数を使用できます

[より高い精度のサポート] が numpy で可能かどうかは、ハードウェアと開発環境に依存します。具体的には、x86 マシンは 80 ビット精度のハードウェア浮動小数点を提供しますが、ほとんどの C コンパイラはこれをlong double型として提供しますが、MSVC (標準のWindows ビルド) はlong doubledouble (64 ビット) と同一になります。Numpy は、コンパイラの long double を np.longdouble(および複素数の場合は np.clongdouble として) 利用できるようにします。numpy が提供するものを見つけることができますnp.finfo(np.longdouble)

Gohlke のビルドとCentOS 6だけでなく、PyPI にも在庫np.longdoubleがあることを確認しました。float64numpy-1.11.1-win32.whlfloat96numpy-1.4.1-9.el6.i686

于 2016-09-30T07:20:46.470 に答える