1 >> 32 の結果は 1 になるのに、1 (uint64_t) >> 32 の結果は 0 になるのはなぜですか?

Linda Hamilton
リリース: 2024-10-26 12:17:02
オリジナル
985 人が閲覧しました

Why Does 1 >> 32 結果は 1 ですが、1 (uint64_t) >> 32 結果は 0? 
> 32 結果は 1 ですが、1 (uint64_t) >> 32 結果は 0 ですか? " />

右シフト演算子の奇妙な動作: 1 >> 32

問題:

C プログラムでは、右シフト演算子が奇妙な動作を示します:

<code class="cpp">int foo(int a, int b) { return a >> b; }
int main() { std::cout << "foo(1, 32): " << foo(1, 32) << std::endl; }
ログイン後にコピー

出力は 1 ですが、理論的には結果は 0 になるはずなので、これは予期せぬ結果です。さらに、動作は引数の型に基づいて異なります:

<code class="cpp">int bar(uint64_t a, int b) { return a >> b; }
std::cout << "bar(1, 32): " << bar(1, 32) << std::endl; // Outputs 0
ログイン後にコピー

説明:

この動作は、基になるデータ型 (この場合は int) の幅に応じて右シフト演算子の動作が異なるという事実に起因します。右シフトは「論理」シフトであり、b の値に関係なく、空いたビットを 0 で埋めることを意味します。したがって、ビット数を超えるシフトは効果がないため、1 > 32 は 1 と評価されます。 🎜>

ただし、64 ビット整数 (uint64_t) の場合、右シフトは「算術」シフトです。つまり、値 1 には正の符号ビットがあるため、空いたビットをオペランドと同じ符号ビットで埋めます。

コンパイラーの最適化:

さらに、コンパイラーの最適化も役割を果たします。式1>> 32 はコンパイル時定数で、これによりコンパイラはコンパイル中に 32 を 0 に折り畳むことができます。これは、関数内の foo(1, 32) の動的評価とは異なります。

移植性の問題:

この動作はアーキテクチャに依存することに注意することが重要です。 ARM などの一部のアーキテクチャでは、論理右シフトは x86/x86-64 CPU とは異なる方法で実装されます。その結果、32 ビット整数を 32 以上の値だけシフトすると、移植不可能な結果が生じる可能性があります。

以上が1 >> 32 の結果は 1 になるのに、1 (uint64_t) >> 32 の結果は 0 になるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!