20

32 ビット互換のコードを 64 ビットに変換していますが、問題が発生しました。VS2008 x64 プロジェクトをコンパイルすると、次の警告が表示されます。

warning C4334: '<<' : result of 32-bit shift implicitly converted to 64 bits
(was 64-bit shift intended?)

元のコード行は次のとおりです。

if ((j & (1 << k)) != 0) {

Microsoft のアドバイスに従うと、次のようになります。

if ((j & (1i64 << k)) != 0) {

コードが 32 ビット システムと 64 ビット システムの両方でコンパイルされる場合、これを行っても安全ですか? もしそうなら、最後に「i64」を追加しなければならない理由と、これが 32 ビット コンパイルに影響しない理由を説明してください。それ以外の場合は、回避策を提供していただければ幸いです。

これを超えて、さらにトリッキーなコードのように見えるものがあります。

if (id[j] != id[j ^ (1u << k)]) {

「u」は数字が符号なしであることを意味することは理解していますが、符号付き最大値を超えない値でそれを指定する意味は何ですか...これはビットシフトと関係があると思いますか?

4

4 に答える 4

11

1intC++ 標準に従った型を持ちます。64 ビットの Microsoft コンパイラのintsizeof = 4 バイトは、int32 ビット変数であることを意味します。1i64タイプがあり__int64ます。

シフト演算子を使用すると、結果の型は左オペランドの型と同じになります。これは、シフト1すると 32 ビットの結果が得られることを意味します。Microsoft コンパイラは、(64 ビット プラットフォームで) 期待したものではない可能性があると想定し、警告メッセージを表示します。

結果を使用1i64すると、両方のプラットフォームで 64 ビットになります。j暗黙的0に 64 ビットにキャストされます。したがって、式全体が 64 ビット変数で計算され、結果は になりますbool

したがって、使用1i64は両方の (32/64) プラットフォームで安全です。

于 2009-08-12T05:22:59.043 に答える
4

サフィックスはi64Microsoft 固有です。移植性を高めるために (心配な場合)、次のINT64_C()マクロを使用できstdint.hます。

#include <stdint.h>

// ...

if ((j & (INT64_C( 1) << k)) != 0) { ... }

残念ながら、MS の C ライブラリには含まれていませんstdint.h(他のほとんどのコンパイラには含まれているようです)。

これで、さまざまなコンパイラで動作する 64 ビット定数が得られます。

64 ビット値が必要な理由については、式のさまざまな部分の型によって異なります。idj、およびの型を知っていると、定数にk' ' サフィックスが必要かどうか、およびそれがどのような影響を与えるかを回答できると役立ちます。u

于 2009-08-12T06:40:24.020 に答える
1

1i64 は符号付きの 64 ビット整数であるべきだと思います。Microsoft の実装に関する専門知識を宣言することはできませんが、GCC では、32 ビット CPU で 64 ビット整数をサポートするための解決策は、構造体とさまざまなブラック マジック マクロを使用して long long を double-word にすることでした。したがって、i64は互換性があるはずです。

ブードゥー教の最後のビットについて - 1u を指定する唯一のポイントは、k が十分に大きい場合、シフトの結果が 32 ビットのストレージを満たす/超える可能性があるためです。その場合、結果は異なります。 LH オペランドが符号付きまたは符号なし整数として扱われる場合。

于 2009-08-12T04:08:08.073 に答える
0

jそのコードはビットシフトの (32 ビット) 結果で64 ビット変数を「and」しているため、結果はコンパイラによって 64 ビットに「拡張」されます。

おそらく、「and」の 2 番目のオペランドがどのように計算されるかを制御したいので、コンパイラは、最初のオペランドを__int64. これは 32 ビットでは安全ですが、実際には の型を調べてj、演算子が 32 ビットか 64 ビットかを判断する必要があります。

これは、結果がインデックスとして使用される 2 番目のビットで特に重要です。

于 2009-08-12T05:42:46.807 に答える