Why is the output of this expression different when the variable is replaced with what it is calculating anyways?

0

Here's the code segment. It's performing x/2^n, rounding towards 0. The first print statement calculates the correct value (-7 in this case), but the second statement, which is just the first statement with bias replaced with ((x>>31) & ((1<<n)+0xffffffff)) (what bias is calculating anyways) and produces 9. What's going on here?

#include <stdio.h>

int main(void) {
    int x = 0x80000004;
    int n = 0x1c;
    int bias = ((x>>31) & ((1<<n)+0xffffffff));
    printf("%d\n", (x + bias) >> n);
    printf("%d\n", (x + ((x>>31) & ((1<<n)+0xffffffff))) >> n);
    return 0;
}
c
bit-manipulation
asked on Stack Overflow Jan 27, 2017 by justincai • edited Jan 27, 2017 by justincai

1 Answer

2

The expressions x + bias and x + ((x>>31) & ((1<<n)+0xffffffff)) have different types; the first is an int, the second an unsigned int. The operator >> preserves the sign bit for ints, but not for unsigneds. (The compiler does not have to do this, but it may do this.) To see clearly what's going on, I have expanded the code a little:

#include <stdio.h>

int main(void) {
    int x = 0x80000004;
    int n = 0x1c;
    int bias = ((x>>31) & ((1<<n)+0xffffffff));
    printf("%d\n", (x + bias) >> n);
    printf("%d\n", (x + ((x>>31) & ((1<<n)+0xffffffff))) >> n);
    printf("%d\n", (x + (int)((x>>31) & ((1<<n)+0xffffffff))) >> n);

    printf ("(int)      %d\n", x + bias);
    printf ("(unsigned) %u\n", x + ((x>>31) & ((1<<n)+0xffffffff)));

    return 0;
}

The output is:

-7
9
-7
(int)      -1879048189
(unsigned) 2415919107
answered on Stack Overflow Jan 27, 2017 by AlexP

User contributions licensed under CC BY-SA 3.0