2010-12-28 13 views
11

私が持っている問題は、一種の大きな整数ライブラリを作成することです。私はそれをクロスプラットフォームとできるだけ速くしたいと思っています。これは、システム上でネイティブにサポートされているような大きなデータ型で数学を実行しようとする必要があることを意味します。現在のプラットフォームで最大のネイティブ整数型を見つけよう

実際に私が32ビットまたは64ビットシステム用にコンパイルしているかどうかを知りたくありません。私が必要とするのは、64ビットまたは32ビットのビット整数を作成する方法です。私はsizeofを使って、それが何であるかによって異なった振る舞いをするでしょう。

使用はsizeof(void *型):ここで

は、いくつかの可能な解決策とその問題となっている これは、メモリへのポインタのサイズを与えます。システムのメモリへのポインタが、それよりも大きいか、またはその逆の可能性があります(そうはないかもしれません)。 常にいくつかのプラットフォームで長い整数はアーキテクチャによって異なりますが(私のシステムはこのような例の1つです)、いくつかのコンパイラは64ビットでも4バイトの長整数を実装します。

常にlong longを使用してください: 多くの32ビットシステムでは、これは効率的ではない可能性がありますが(おそらく、私が書き込んでいるコードよりも効率的ですが)、64ビット整数です。この問題の本当の問題は、一部のアーキテクチャ(例えば、自分のmp3プレーヤーに電力を供給しているものなど)ではまったくサポートされていない可能性があるということです。

強調すると、私のコードは一度選択された整数の実際のサイズが気にしません(sizeof()が問題となるものなら何でも)に依存します。私は、コードを最も効率的にする整数型を選択したいだけです。

+0

私の頭に浮かぶのは、何らかの形でCPUのレジスタのサイズを調べることです。 – BlackBear

+0

既存のbignumライブラリで答えを探しましたか? http://sourceforge.net/projects/bignlibacbignum/ – mth

+0

おそらく何かを移動して何かを追加し、オーバーフローフラグを確認してください – BlackBear

答えて

6

あなたは本当にネイティブサイズの種類をしたい場合は、私がsize_tptrdiff_t、またはintptr_tuintptr_tを使用します。非病理学的なシステムでは、これらはすべてネイティブワードサイズになります。

一方、固定サイズで作業することは簡単であるという利点があります。この場合、私はちょうどint32_tまたはuint32_tを使用します。私がより簡単だと言う理由は、「型に適合する10の最大の累乗」(小数変換のための)や型の定数表現として容易に表現できない他の定数あなたは使っています。固定ビット数を選ぶだけなら、便利な定数(私の例では1000000000など)を修正することもできます。もちろん、このようにすれば、ハイエンドシステムのパフォーマンスを犠牲にすることになります。逆のアプローチを取って、より高い固定サイズ(64ビット)を使用することができます。これは、ハイエンドシステムでは最適であり、32ビットマシンでの64ビット算術用のコンパイラのコードは、あなたのbignumコードは2つの32ビットワードを扱いますが、その場合でも最適です。

+0

お返事の最初の部分は、私が探しているものです。 – Collin

+0

一方、とにかく私はおそらくGMPを使用していると思います。 – Collin

+1

警告: 'ptrdiff_t'はポインタ減算のために十分な大きさが保証されていますが、誰もそれを大きくすることはできません。(' size_t'が32ビットのときに64ビットの 'ptrdiff_t 'これは、アドレス空間の半分以上の違いが 'ptrdiff_t'に格納されないことを意味します)。あなたが頼っている基準に注意してください。 – Mehrdad

4

自動検出に頼るのではなく、#if/#else文のセットで特定のコンパイラを対象にして、テストして最適と判断したタイプを選択することをお勧めします。ここで

+0

コンパイラが検出されない場合はおそらくuintptr_tにフォールバックします。 – Charles

0

bsdnthow we did itです:

#if ULONG_MAX == 4294967295U 

typedef uint32_t word_t; 
typedef unsigned int dword_t __attribute__((mode(DI))); 
#define WORD_BITS 32 

#else 

typedef uint64_t word_t; 
typedef unsigned int dword_t __attribute__((mode(TI))); 
#define WORD_BITS 64 

#endif 

それは興味のなら、プロジェクトを開始した男はBIGNUMライブラリを書くことにblogを書いています。

GMP/MPIRは非常に複雑です。 gmp-h.inこれを定義gmp.hポスト構成となる。要するに

#define GMP_LIMB_BITS      @[email protected] 

、長さがconfig.guess(即ちautotoolsの)を介してそれを動作ビルドプロセスの一部として設定されています。

+0

ULONG_MAXが2^48 - 1の場合はどうなりますか? –

+0

gcc固有のハッキングがありません.... –

+0

@R確かに。それは確かに進行中の仕事です。 ... –

0

stdint.hのint_fast32_tを使用すると、「高速」が何を意味するのかについて、あなたが決定した人の慈悲にあるものの、オプションであるように見えます。

+1

x86_64のように32ビットアクセスのペナルティがない場合、 'int_fast32_t'は32ビット型でなければなりませんが、bignum算術演算を実行する必要があります64ビットユニットでは確かに好ましいでしょう... –

+1

一般的には正しいかもしれませんが、私のx86_64マシン(Ubuntu 10.10)では64ビットです。私はそれがマシンの主なデータレジスタの幅に相関するものと期待していますが、私はそれについての確かな証拠はありません。 – ergosys

関連する問題