6

np.longdoublePython コードで dtype を操作しようとしています。NumPy を使用して、Cython でコンパイルされた C モジュールから取得した long double を操作しようとしています。

私がこれをするとします:

import numpy as np

print np.finfo(np.longdouble)
Machine parameters for float128
---------------------------------------------------------------------
precision= 18   resolution= 1e-18
machep=   -63   eps=        1.08420217249e-19
negep =   -64   epsneg=     5.42101086243e-20
minexp=-16382   tiny=       3.36210314311e-4932
maxexp= 16384   max=        1.18973149536e+4932
nexp  =    15   min=        -max
---------------------------------------------------------------------


a = np.longdouble(1e+346)

a
Out[4]: inf

b = np.longdouble(1e+347)

b
Out[6]: inf

c = a/b
/usr/lib/python2.7/site-packages/spyderlib/widgets/externalshell/start_ipython_kernel.py:1:
RuntimeWarning: invalid value encountered in longdouble_scalars
  # -*- coding: utf-8 -*-

c
Out[8]: nan

a.dtype, b.dtype, c.dtype
Out[9]: (dtype('float128'), dtype('float128'), dtype('float128'))

本質的に、それはこの質問と同じ問題にリンクされており、Python は最初1e+346に をフロートに変換し、その表現はinf. しかし、誰かが回避策を提案できますか? 最初に float に変換されない NumPy longdouble を作成する方法はありますか?

long double を出力できる C モジュールがあり、これを dtype の numpy 配列で使用したいと考えていますnp.longdouble

解決策に Python/NumPy の再コンパイルが含まれる場合でも、喜んで試します。

4

1 に答える 1

6

考慮すべき点がいくつかあります。

まず、これは混乱です。NumPy はlongdoublefloat128. 残念ながら、名前は誤解を招くものです。基本的な実装は C の long double であり、通常 (必ずしも常にではありません) 80 ビットの float です。(実際には、ここで「精度」を見るとわかります。18 桁は約 60 ビットであり、80 ビット浮動小数点数の仮数は 64 ビットです。実際の 128 ビット浮動小数点数が使用された場合、精度は約 34 桁になります。 )

long double を引数として C 関数に渡す直接的な方法はないかもしれませんが、代わりにポインターを渡すと、問題を回避できます。たとえば、配列データをuint8( を使用してmyarray.view(dtype='uint8')) として渡し、C プログラムでバッファーへのポインターを long double * にキャストすることができます。少なくとも、Python は型変換とは何の関係もありません。view(結局のところ、ポインタを配列バッファにエクスポートするだけなので、おそらく を取得する必要はありません。)

このトリックは、Python と C プログラムをコンパイルするときに、同じ種類の型設定を持つコンパイラに依存していることに注意してください。精度の違いに加えて、バイト オーダーの違い (プログラムが同じマシンで実行される場合はまれです) とアラインメントの違いがある場合があります。私の Python はlongdouble項目を 16 バイトの境界で位置合わせしているように見えます (つまり、各要素ごとに常に 6 バイトのゼロがあります) が、C コンパイラは 10/12/16 バイトの位置合わせを使用する場合があります。

私の知る限り、詳細は実装固有です。したがって、これは実行可能ですが、特別な注意が必要であり、移植性の問題が発生する可能性があります。

于 2014-08-25T08:13:51.403 に答える