0

So I was trying to test out a super short function for getting me the integer value of certain bits x through y from an integer, but am having some trouble with the sign extension that is happening. I tried casting to an unsigned int and then shifting using the unsigned int, but that does not seem to be working. The code is the following:

#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;
}

I don't understand why there is sign extension that is occurring, as I have shifted only on an unsigned integer. I also ran the code using just "addr" and had it as an unsigned int, but that didn't change the output either.

The output value for index is 536870912 when I run the function in gdb on a linux machine, and on compile online (now coding ground), the value that I get is 67108864.

Edit: A couple people have asked how I got the value 536870912, I have gotten it running gdb through both breakpoints and running the command p get_index(1) from gdb. The actual code is the following:

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

Thanks for all the help!

Rohan
  • 33
  • 2
  • 5
  • 2
    How are you getting 536870912? I get the expected value of 67108864 (http://ideone.com/aIcOJ3), which is `1 << 26`. – Adam Rosenfield Nov 29 '14 at 04:29
  • 4
    Please explain and edit your question with the steps you did to get this `536870912` value displayed. – ouah Nov 29 '14 at 04:33
  • You must have an simple error somewhere. What you posted gives `index after tag_bits: 268435456` `(1 << 28)` and `index after bo_bits : 67108864` `(268435456 >> 2)`. Is your function declared as `unsigned foo()` or as something else? – David C. Rankin Nov 29 '14 at 06:10
  • @David C. RankingThe function is declared as int foo(...). The reason for this is that the function declaration was given to me along with a bunch of other code, some of which I am not allowed to change, so I can't actually change the "addr" to be a truly unsigned int. Edit: Updated post with a little bit of information about where I am getting the other value from. – Rohan Nov 29 '14 at 15:44
  • It should work as int as well. Just make sure you verify the value of `( 0 <= index <= 2147483647 )` (index won't be negative) and `return (int)index;` You will only experience a type conversion, in your case, if index is above `2147483647`. Then `UINT_MAX+1` is repeated added until `index` falls outside the range of `unsigned int` per **C99 6.3.1.3(2)**. – David C. Rankin Nov 29 '14 at 20:01

1 Answers1

1

536870912 is equal to 1 << 29, which means it has nothing to do with sign extension.

maybe it is you who stop at the wrong place when debuging the program

here is what c99 standard says about bitwise right shift. (6.5.7 Bitwise shift operators)

The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2^E2. If E1 has a signed type and a negative value, the resulting value is implementation-defined.

simon_xia
  • 2,394
  • 1
  • 20
  • 32