0

このリンクからここで整数の符号を計算します

int v;      // we want to find the sign of v
int sign;   // the result goes here 

sign = v >> (sizeof(int) * CHAR_BIT - 1);
// CHAR_BIT is the number of bits per byte (normally 8)

これを正しく理解している場合、 sizeof(int) = 4 バイト => 32 ビットの場合

MSB または 32 番目のビットは符号用に予約されています。したがって、(sizeof(int) * CHAR_BIT - 1) だけ右にシフトし、すべてのビットが右側から落ちて、前の MSB のみをインデックス 0 に残します。MSB が 1 の場合 => v が負の場合、それ以外の場合は正です。

私の理解は正しいですか?

もしそうなら、このアプローチがアーキテクチャ固有であるということで、著者がここで何を意味しているのかを誰かが説明してもらえますか:

符号付き整数が右にシフトされると、左端のビットの値が他のビットにコピーされるため、このトリックは機能します。左端のビットは、値が負の場合は 1、それ以外の場合は 0 です。すべて 1 のビットは -1 になります。残念ながら、この動作はアーキテクチャ固有です。

これは、32 ビットまたは 64 ビット アーキテクチャでどのように異なるのでしょうか?

4

2 に答える 2

3

「アーキテクチャ依存」は、プロセッサがサポートするシフト操作の種類に基づいていると思います。x86 (16、32、および 64 ビット モード) は、「算術シフト」と「論理シフト」をサポートします。算術バリアントは、シフトされた値の最上位ビットをシフトに沿ってコピーしますが、論理シフトはそうではなく、ゼロで埋めます。

ただし、コンパイラが次の行に沿ってコードを生成する必要がないようにします。

int temp = (1 << 31) & v; 
sign = v;
for(i = 0; i < 31; i++)
  sign = temp | (sign >> 1);

「論理的な」シフトのみを持つアーキテクチャの問題を回避するため。

ほとんどのアーキテクチャには両方のバリエーションがありますが、そうでないプロセッサもあります。(申し訳ありませんが、どのプロセッサがシフトの 2 つのバリアントを持っているか、持っていないかを示すリファレンスが見つかりません)。

また、64 ビット マシンでは 64 ビット シフトと 32 ビット シフトを区別できないため、符号の小さいビットではなく上位 32 ビットがシフトされるという問題が発生する可能性があります。そのようなプロセッサが存在するかどうかはわかりません。

他の部分は、もちろん、1 の補数の -0 の符号が実際に符号に関して "0" または "-1" の結果であるかどうかを判断することです。これは、何をしようとしているのかによって異なります。

于 2013-06-01T08:12:53.293 に答える
0

C++ では、負の値の右シフトの効果は実装定義であるため (C では、未定義の動作が生成されます)、「アーキテクチャ依存」です。つまり、コンパイラの動作に関するドキュメントを読んで理解していない限り、結果に頼ることはできません。個人的には、コンパイラが適切なコードを生成することを信頼していv < 0 ? -1 : 0ます。

于 2013-06-01T17:41:09.087 に答える