1

私は2つのコアを持っています。1つは32ビットで、もう1つは64ビットです。

64ビットマシンでは、unsigned long longをサポートしています。この値を、次のような32ビットマシンでアクセスできる変数に割り当てる必要があります。-

typedef struct {
    unsigned int low;
    unsigned int high;
} myint64_t;

myint64_t app_sc;

以下は、64ビットマシンのコードスニペットです。

unsigned long long sc;

/* Calculate sc */
...

64ビットマシンでは、app_scに「sc」を割り当て、64ビットマシンでのコンピューティングに使用する必要があります。

私はこのようなことをしようとしていました:-

app_sc = sc;

しかし、コンパイラはコンパイル時のエラーを出します。私も同様に、次のようなことができます:-

 app_sc.low = sc & 0xFFFFFFFF;
 app_sc.high = (sc>>32) & (0xFFFFFFFF);

しかし、それは保証されますか、それはすべての場合に機能しますか?

それを行うためのより良い方法はありますか?

4

5 に答える 5

5

かなり最近のC標準(おそらくC99、おそらくそれ以前)をサポートするそれほど古くないコンパイラでは、 (符号付き64ビット整数の場合)または(符号なし64ビット整数の場合)の<stdint.h>ような型を与えるヘッダーが必要です。 32ビットマシンでも64ビット。int64_tuint64_t

コンパイラにない場合は、コンパイラをアップグレードすることを強くお勧めします。おそらくGCCを使用できます(GCCでサポートされていない非常に奇妙なターゲットアーキテクチャがある場合を除く)。最新のGCCバージョンは4.7です。

32ビットマシンでの64ビット演算には、実際には、適度に効率的なコンパイラサポートが必要であることに注意してください。(たとえば、キャリー命令で追加を使用する場合)。ライブラリが最も複雑な操作(たとえば、32ビットマシンでの64ビット分割)を提供する必要がある場合でも、ライブラリを介してのみ実行することはできません。言い換えると、32ビットマシンの場合、高速64ビット演算をCで移植可能にコーディングすることはできません。

はるかに大きな数値の場合は、GNU gmpライブラリなどを介して任意精度の数値( bigintsと呼ばれる)を使用することを検討してください。このようなライブラリは重要なアルゴリズムを使用します(したがって、数学でさえ非常に難しいので、それらに関する本全体を読んで、競争力のあるbi​​gint実装を発明することで博士号を取得できます)。

于 2012-07-17T17:16:54.013 に答える
3

stdintまず、可能であればタイプを使用するという提案に同意するので、自分でそうします。

第二に、私が変換を行うために考えることができる唯一のおそらくより安価な方法は、次のような組合を経由することです

union Int64
{
    uint64_t val64;
    struct {
        uint32_t lo32;
        uint32_t hi32;
    };
};

union Int64 i64;
i64.val64 = sc;
app_sc.low = i64.lo32;
app_sc.high = i64.hi32;

警告

  • これを行う際にストアと再ロードが必要な場合(図のように)、ビット単位の操作よりもコストがかかる可能性があります
    • app_sc既存のものをこのユニオンのインスタンスに変換できる(32ビットロードをスキップする)ことができれば、それは価値があるかもしれません
  • scまたは、すでにメモリのどこかに本当に保存されている場合は、そのアドレスを次のようにキャストできます。(union Int64 *)
    • もちろん、sc現在レジスタが割り当てられていてダーティである場合、アドレスを取得すると、とにかくストアを強制する可能性があります
  • 原則として、現在またはその後のABIで、パッキングとアライメントの問題が発生する可能性があります
  • これはアーキテクチャに依存するため、後続のポートはユニオンを変更することを意味する可能性があります(上記のx86リトルエンディアンを想定しています)

率直に言って、警告が示されることを願っていますので、それは壊れやすいです。それでも、それはそれを行う別の方法であり、あなたはそれがあなたの場合にも良いかどうかを決めることができます。

于 2012-07-17T18:00:22.790 に答える
1

お使いのコンパイラは、32ビットマシンであっても、「longlongint」をサポートしている場合があります。それを試してみてください?

于 2012-07-17T16:44:02.020 に答える
1

ヘッダーファイルstdint.hを使用して、符号付き/符号なし変数uint64_t / int64_t /... uint8_t / int8_tを使用して、より適切な説明を行うことができます:http: //pubs.opengroup.org/onlinepubs/007904975/basedefs/stdint.h.html

于 2012-07-17T17:28:49.350 に答える
0

32ビットおよび64ビットアーキテクチャでは、ポインタのサイズが変わるため、unsigned long longは、64ビットで機能したのと同じように32でも機能します。

于 2012-07-17T16:48:41.163 に答える