Reputation: 795
I couldn't understand why the below identical operations reports two different outputs. When my num is declared to be of negative value and I add the num to the baseAddr, I see my addr going past 32-bit range. On the other hand, if I declare num to a positive value and do a subtraction, I do see the right result. i.e my resulting output is reported accurately. Can someone please explain what is wrong with the below computation?
/* Architecture is powerpc. Program cross-compiled for powerpc. Gcc Version- 4.6.2 */
#include <stdio.h>
typedef unsigned long long u_int64;
typedef unsigned long u_int32;
int main() {
u_int64 baseAddr = 0x8e008128;
u_int32 num = -360;
u_int64 addr = baseAddr + num;
printf("\nAddr 1st step = 0x%llx\n", addr);
/* Same operation, but slightly different */
num = 360;
addr = baseAddr - num;
printf("\nAddr 2nd step = 0x%llx\n", addr);
return 0;
}
/* Output:
Addr printed is 0x18e007fc0, but I need just 0x8e007fc0
/diagsk10copy/bin # ./e500GPR
Addr 1st step = 0x18e007fc0 //Wrong
Addr 2nd step = 0x8e007fc0
*/
Upvotes: 1
Views: 175
Reputation: 726919
u_int32
is unsigned. The negative 360
that you assigned to it gets re-interpreted as a positive 32-bit number. When you add it to u_int64
, the value gets extended with 32 zeros to match the size of the other operand. This is not what you wanted: since the number was negative, you need all ones in the upper half in order for the addition to produce the desired effect after the result of the addition is reduced modulo the number that is one greater than the largest value that can be represented by u_int64
*.
If you declare the num
as u_int64
, the first and the second parts produce the expected number (demo on ideone).
u_int64 baseAddr = 0x8e008128;
u_int64 num = -360;
u_int64 addr = baseAddr + num; // Works!
printf("\nAddr 1st step = 0x%llx\n", addr);
Upvotes: 3
Reputation: 179592
u_int32
is an unsigned type; assigning -360 to it will cause integer overflow and result in num
holding a very large positive value.
Upvotes: 4