1

符号付き整数に対応するビットパターンが右にシフトされる場合、

1   vacant bit will be filled by the sign bit   
2   vacant bit will be filled by 0  
3   The outcome is implementation dependent 
4   none of the above

この質問への答えは3番目のオプションです。誰でもこれを説明できますか、、

また、Cプログラミングにおける左シフトおよび右シフト演算子の背後にある理論について、いくつかの基本的な考え方を示します。例えば

いずれかの操作が実行されたときに空のビットに何が埋められるか。確認したところ、左シフトで空のビットが0で埋められ、右シフトで1が埋められていることがわかりました。ロジックをクリアしてください...

4

5 に答える 5

6

実装に正確に依存しているのは何かという質問については、仕様を確認する必要があります。しかし、私が(つぶやく)何年にもわたる組み込みシステムプロジェクトで使用したすべての実装は賢明でした:

  • 左シフトは常に下位ビットで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標準は、演算子をそれぞれに効率的に実装できるように、実装定義の動作を十分に許可することによってそれを反映しています。マシーン。

代替案は、すべての数学演算が完全に指定されており、どのマシンにも効率的に実装できない世界にすばやくつながります。

于 2009-03-17T07:34:05.137 に答える
5

Cは、符号ビット、または整数のビットレベル表現に関する何かがあることを保証しません。それが理由です。

2の補数の場合、通常、符号ビットがシフトインされますが、それは実装次第です。

于 2009-03-17T07:30:14.880 に答える
2

ISO C99 は、表現のどこかに符号ビットを必要としますが、さまざまな補数/符号および大きさのスキーム間のオプションを提供し、パディング ビットを許可します。これらはすべて の操作に影響します>>

セクション 6.2.6.2 (整数型)

符号付き整数型の場合、オブジェクト表現のビットは、値ビット、パディング ビット、符号ビットの 3 つのグループに分けられます。パディング ビットは必要ありません。正確に 1 つの符号ビットがあります。

セクション 6.5.7 (ビット単位のシフト演算子)

E1 >> E2 の結果は、E1 を右シフトした E2 ビット位置です。E1 が unsigned 型の場合、または E1 が signed 型で負でない値の場合、結果の値は E1 / 2 E2の商の整数部になります。E1 に符号付きの型と負の値がある場合、結果の値は実装定義です。

1 の補数、2 の補数、または符号と大きさのどれが使用されるか、符号ビットが値ビットの左か右か、またはパディングがどこにあるかは指定されません。これらはすべて、>>演算子の出力に影響を与えます。署名されたネガ。

RBerteig の質問への回答として、C99 は整数の BCD 表現を排除します。

セクション 6.2.6.2 (整数型)

N 個の値ビットがある場合、各ビットは 1 から 2 N −1 までの異なる 2 の累乗を表すため、その型のオブジェクトは純粋な 2 進数表現を使用して 0 から 2 N − 1 までの値を表すことができます。これは、値表現として知られるものとします。

于 2009-03-17T10:20:58.777 に答える
0

C言語の実装は、ビットシフト操作を対応するマシンコード命令に直接マップする傾向があります。異なるハードウェアアーキテクチャは歴史的に異なることを行ってきたため、C仕様では、C実装がハードウェアが提供するものをすべて利用できるように、実装が定義されたままになる傾向があります。

于 2009-03-17T07:47:37.007 に答える
0

結果は実装に依存します。ただし、実際には、これまでに使用したすべてのx86、PPC、およびMIPSコンパイラーは、右にシフトするための次の規則に従いました。

  1. オペランドが符号付き整数の場合、空のビットは符号ビット(実際には最上位ビット)で埋められます。

  2. オペランドが符号なし整数の場合、空のビットはゼロで埋められます。

RBerteigが言うように、これは、符号付き整数の場合、正と負の両方のnでn >> 1 = n / 2(切り捨て)であり、符号なし整数の場合、n>2^でもn>>1 = n/2です。 31(32ビットアーキテクチャの場合)。

対応するハードウェア命令は、算術(符号拡張)および論理(符号拡張ではない)シフトです。コンパイラは、オペランドが符号付きか符号なしかに基づいて、これらのいずれかを選択します。

于 2009-03-17T07:55:06.427 に答える