4

C の知識が乏しいことを前もってお詫びします。Python を使用してコーディングし、標準 C 関数を使用して Cython でいくつかのモジュールを作成し、速度を大幅に向上させました。ただし、より高い範囲が必要です(はい、あなたはそれを正しく読んで1e308 います) 。double complexcexpcabs

cexpl関数andを使用しようcabslとし、変数の型を と宣言しましたが、 のlong double complex後でもオーバーフローが発生し1e308ます。これはおそらく、私のコンパイラが long double を double に変換することを意味します。そうですか? しかしウィキペディアによると、

GNU C コンパイラを使用すると、型に使用される物理ストレージ (96 ビットまたは 128 ビットのいずれか) に関係なく、x86 プロセッサでは long double は 80 ビットの拡張精度になります。[4]

私は arch Linux (および問題があれば Python 2.7.8) で 64 ビット システムを使用しています。

long double の使用を強制する Cython モジュールを作成するにはどうすればよいですか? 私が行っている科学計算には、このような大きな数が必要です。

編集: フラグ -m128bit-long-double を指定してコンパイルすると、同じ結果が得られます。ここに示されているように、

x86-64 コンパイラでは、-m128bit-long-double がデフォルトの選択です。これは、その ABI が long double を 16 バイト境界に揃えることを指定しているためです。

したがって、これは違いはないようです。

また、次のプログラムを実行して、システムの範囲を確認しました。

#include <stdio.h>
#include <float.h>

int main()
{
   printf("Storage size for float : %d \n", sizeof(float));
   printf("Minimum float positive value: %E\n", FLT_MIN );
   printf("Maximum float positive value: %E\n", FLT_MAX );
   printf("Precision value: %d\n", FLT_DIG );

   printf("Storage size for double : %d \n", sizeof(double));
   printf("Minimum double positive value: %E\n", DBL_MIN );
   printf("Maximum double positive value: %E\n", DBL_MAX );
   printf("Precision value: %d\n", DBL_DIG );

   printf("Storage size for long double : %d \n", sizeof(long double));
   printf("Minimum long double positive value: %Le\n", LDBL_MIN );
   printf("Maximum long double positive value: %Le\n", LDBL_MAX );
   printf("Precision value: %d\n", LDBL_DIG );

   return 0;
}

そして、次の出力を得ました:

Storage size for float : 4 
Minimum float positive value: 1.175494E-38
Maximum float positive value: 3.402823E+38
Precision value: 6
Storage size for double : 8 
Minimum double positive value: 2.225074E-308
Maximum double positive value: 1.797693E+308
Precision value: 15
Storage size for long double : 16 
Minimum long double positive value: 3.362103e-4932
Maximum long double positive value: 1.189731e+4932
Precision value: 18

問題は私のコードにあると思いますが、そうですか?プログラムが実際に long double を使用するようにするために、変数を宣言する以外に追加する必要がある明示的な識別子はありますか?

4

1 に答える 1

2

質問の編集で見られたように、私のシステムとコンパイラは、 の正しい範囲を出力することで期待どおりに動作していましlong doubleた。関連する変数はここにありますLDBL_MAX = 1.189731e+4932

また、Cython で書かれたモジュールは type の出力を正しく提供していましたlong double。ただし、この型は Python でネイティブにサポートされていないため (この質問を参照)、返された値はdouble1.797693E+308私のシステムでは の最大サイズよりも大きく、したがって と同等でした+inf + 0j。したがって、これは gcc とはまったく関係がありませんでしたが、Python が long double を間違った方法で解釈したことが原因でした。

long double 入力型を受け入れてさらに処理できる別の C モジュールを使用することで、これを回避できることを願っていますdoublefloat)。

別のオプションとして、高精度で高範囲の数値 (おそらくGMPY ) をサポートできる Python でライブラリを使用することもできます。

于 2014-08-19T18:29:54.003 に答える