実装に正確に依存しているのは何かという質問については、仕様を確認する必要があります。しかし、私が(つぶやく)何年にもわたる組み込みシステムプロジェクトで使用したすべての実装は賢明でした:
左シフトは常に下位ビットで0にシフトします。他の値は意味がありません。
右シフトはデータ型によって異なります。符号付き整数を右シフトすると、残りのビットが右にシフトするため、上位ビットが複製されます。これは「算術シフト」と呼ばれ、元の数値の符号を保持しながら値を2で除算するという優れた特性(少なくとも2の補数の算術)を備えています。
符号なし整数の右シフトは、0を上位ビットにシフトし、通常は「論理シフト」として知られています。
両方が有用であり、どちらが意味するかを選択するために符号付き/符号なしを使用することは賢明な選択であるため、実装が両方の種類のシフトを提供することは理にかなっています。
編集:実装に絶対的に依存する少なくとも1つのことは、C標準が整数とそのストレージの基礎となる実装を(完全に)指定していないことです。たとえば、1の補数演算を使用するマシン用の準拠Cコンパイラを構築することができます。ネイティブストレージがマグニチュードBCDで署名されたマシン用に準拠したコンパイラを構築することも可能です(私は思います)。(いいえ、私は間違っていました。以下を参照してください。)
実際には、世界はCPUの2の補数バイナリにほぼ決着しており、一部の衒学者は動揺しています。
したがって、質問の一部は、実際には、使用されている基礎となる算術システムに関係なく安定した方法で、<<および>>演算子の意味をどのように定義するかということです。
IIRCの定義は、n<<1
効果的n*2
に、そしてn>>1
効果的n/2
に、1を超えるシフト(ただし31を超えない...そこに未定義のドラゴンがあります...)への自然な拡張と、>>
オペレーターが符号付きの値で操作する場合は符号付き。
編集2: Pete Kirkhamは、彼の細かい答えの中で、C標準は、符号付きの大きさであろうと10の補数であろうと、整数のBCD表現の恐ろしいケースを特に許可しないと指摘しています。クヌースがTheArtof Computer Programmingの初期の版でサンプルコードに(オプションで)BCDマシンを使用したとしても、それは良いことだと確信しています。
BCDが正解であるまれな使用例では、符号なしのlong(8桁の10の補数)または符号なしの64ビット整数(16桁の10の補数または15桁のプラス記号とフラグの余地)に格納し、それらを操作するために慎重に作成された算術ライブラリは理にかなっています。
もちろん、実際には、Cの実装は、標準で許可されているように、CPUのネイティブマシン命令に直接演算子をマップします。標準を作成した人々は、積分値の表現のような単純なものでさえ実装する多くの方法の存在に非常に気を配っていました。C標準は、演算子をそれぞれに効率的に実装できるように、実装定義の動作を十分に許可することによってそれを反映しています。マシーン。
代替案は、すべての数学演算が完全に指定されており、どのマシンにも効率的に実装できない世界にすばやくつながります。