変数(スタック上)に何らかの変数があり、左端または右端にビットシフトが発生した場合はどうなりますか?変数の終わりを超えてビットシフトするとどうなりますか?
すなわち、xはメモリへのポインタはバイトにキャストされていて、同じことを何場合
byte x = 1;
x >> N;
?
byte* x = obtain pointer from somewhere;
*x = 1;
*x >> N;
変数(スタック上)に何らかの変数があり、左端または右端にビットシフトが発生した場合はどうなりますか?変数の終わりを超えてビットシフトするとどうなりますか?
すなわち、xはメモリへのポインタはバイトにキャストされていて、同じことを何場合
byte x = 1;
x >> N;
?
byte* x = obtain pointer from somewhere;
*x = 1;
*x >> N;
ただゼロになります。だから、長さはどんなものでもゼロであった。
つまり、3ビットシフトした後のバイナリが001であるとします。 ラップアラウンドは発生せず、位置を移動しません(ポインタ自体をビットシフトしていない場合を除き) 。
必ずしもゼロになるわけではありません。動作は(C99の§6.5.7、「ビット単位シフト演算子」)未定義である:
右オペランドの値が促進左 オペランドの幅に 負又は以上である場合動作は未定義です。
(C++ 0X§5.8、「オペレータシフト」):右 オペランドのビット単位の長さに負、または 以上である場合
挙動が未定義 は左オペランドを宣言しました。
シフトされた値の格納は、このいずれにも影響しません。
Uh ...「右オペランドが負ではありません」「右オペランドが昇格された左オペランドの幅以上」ではありません。 OPはNの値を指定していません。「xは1であるので、値はここでは問題ではないとわかります。 –
重要な注意:*この場合のwidth *は 'log2(var)'ではなく 'CHAR_BIT * sizeof(var)'を意味します! – ruslik
そして、何年にもわたって、単語のサイズ以上の大きさのNに対して、ふたつのふるまいが見られました。行動1は、最も一般的には、すべてのビットが「シフトアウト」され、結果がゼロであるということです。他の振る舞いは、Nが黙示的に言葉をモジュロに減らされているということです。一例として、このアーキテクチャー上のx >> 32は単純に32ビットタイプxのノーオペレーションでした。 –
あなたはビットシフトが何であるか混乱していると思います。それらは2の累乗による乗算または除算と同等の算術演算子です(Cが負の数を扱う方法についての不思議さをモジュールにします)。 メモリ内のビットは移動しません。任意の変数/メモリの内容が変更される唯一の方法は、式の結果をどこかに戻す場合です。
ビットシフト演算子の右辺オペランドが左辺式の型の幅以上の場合、動作は未定義です。
あなたは混乱していると思います。 x >> y
は、実際にはxを実際には変更しません。新しい値が計算されます。
スティーブンが指摘したように、y
は負であってはならず、「昇格された左オペランドの幅」より小さい値でなければなりません。しかし、そうでなければ、「最後から」シフトするビットは単純に破棄されます。 1 >> 2
(2
は負ではなく、1
を表すのに使用されるビット数より少なく、おそらくは32であるが確かに少なくとも16であることに注意してください)
反論:次の場所に移動する場所、次に何が起こるのでしょうか?これは、次のメモリ位置からのビットがさらにシフタになることを意味しますか?このロジックでは、すべてのメモリがシフトします。代わりにどこかで停止しなければならないと思いませんか? – ruslik
本当の質問は、メモリ空間の端にある最初と最後のビットで何が起こるかということです。 ;) – jalf
@jalf:少なくとも2つのパラレルユニバースがある場合は問題ありません。 – ruslik