0

そのため、整数から特定のビット x から y の整数値を取得するための非常に短い関数をテストしようとしていましたが、発生している符号拡張に問題があります。unsigned int にキャストしてから unsigned int を使用してシフトしようとしましたが、うまくいかないようです。コードは次のとおりです。

#include <stdio.h>

int main()
{
    int bo_bits = 2;
    int tag_bits = 28;
    int addr = 1;

    unsigned int index = (unsigned int)addr;
    index = index << tag_bits;
    index = index >> bo_bits;

    // at this point I would return (int)index;

    return 0;
}

符号なし整数のみをシフトしたため、符号拡張が発生している理由がわかりません。また、「addr」だけを使用してコードを実行し、符号なし int として使用しましたが、出力も変更されませんでした。

Linux マシンの gdb で関数を実行すると、index の出力値は 536870912 になり、オンラインでコンパイルすると (現在はコーディング グラウンド)、得られる値は 67108864 です。

編集: 値 536870912 を取得する方法をいくつかの人が尋ねてきました。両方のブレークポイントを介して gdb を実行し、p get_index(1)gdb からコマンドを実行して取得しました。実際のコードは次のとおりです。

unsigned int index = (unsigned int)addr;
index = index << tag_bits;
index = index >> bo_bits;
return (int)index;

助けてくれてありがとう!

4

1 に答える 1

0

536870912 は 1 << 29 に等しいため、符号拡張とは関係ありません。

プログラムをデバッグするときに間違った場所で停止するのはあなたかもしれません

これは、c99標準がビットごとの右シフトについて述べていることです。( 6.5.7 ビットシフト演算子)

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

于 2014-11-29T05:59:32.680 に答える