# C When division, MSB get set

0

I'm working on a memory address based problem and I found this is very confusing (Below algorithm is mainly calculate the address difference between "Value" and "nv_var.EEStart"):

``````    ValueI = (int*)(Value);     // ValueI is int*
EP = (int)(&nv_var.EEStart);            // EP is int
E = (long)(EP);                         // E is long
V = (long)(ValueI);                     // V is long
printf("Current V: %.8x\n", V);
printf("Current E: %.8x\n", E);
printf("V-E    is: %.8x\n", (V - E));
printf("V-E/2L is: %.8x\n", (V - E) / 2L);
``````

Then I got the following output:

``````Current V: 00439488
Current E: 004391e0
V-E    is: 000002a8
V-E/2L is: 80000154
``````

What confused me is my V-E is actually the expected result, but when I divide this number by 2, the result should be 0x00000154, but I got 0x80000154. I'm using gcc compiler without any extra flag, and the expected result should be 0x154.

I can improve it easily by masking off the MSB, but I just wondering why this will happen.

Thanks for all the help.

c
division
asked on Stack Overflow Jun 11, 2020 by Zhiheng Zhang

2

Your program has potential and actual undefined behavior all over the place, but the core problem is likely in part of the code you're not showing: the types of `E` and `V`. I suspect they're `long`. At least `(V-E)/2L` has type `long` (or wider), and when you pass that as the argument for a `%x` format specifier, you get undefined behavior. What's likely happening is that `V-E` has nonzero bits above bit 31, and your system's implementation of `printf` (or argument-passing ABI) masks off all the bits outside the size of `unsigned int` when printing/reading an argument for `%x`. But after dividing by 2, a nonzero bit 32 has been shifted down to bit 31 and shows in the (UB) `printf` output.

User contributions licensed under CC BY-SA 3.0