// a 64-bit number, zeroed out for now
typedefunsignedlonglong UINT64;
UINT64 x = 0x0000000000000000;
// set the byte at the highest address to 0x80
// seems to me this should be endian agnostic
((unsignedchar *)(&x))[7] = 0x80;
// print the bytes to verify
// 0000000000000080
int i;
for (i = 0; i < sizeof(x); i++) {
printf("%02x", ((unsignedchar *)(&x))[i]);
}
// rotate left 1 bit
// endian agnostic?
x = (x << 1) ^ (x >> 63);
// print the bytes again
// but now it's not at all what I expect
// 0100000000000000
for (i = 0; i < sizeof(x); i++) {
printf("%02x", ((unsignedchar *)(&x))[i]);
}
Also, how is the output unexpected? You're printing the bytes from least to most significant.
80 hex = 1000 0000 binary. Naturally that 80 rotated left becomes a 1.
line 7 is subject to system endianness. On little endian machines you will be setting x to 0x8000000000000000, and on big endian machines you will be setting x to 0x0000000000000080
The rotate left on line 18 is fine (not subject to endianness)... although I would probably be using | instead of ^.
after the rotate you're left with:
0x0000000000000001 (little endian)
or
0x0000000000000100 (big endian)
and as hamsterman pointed out, you are printing the variable low byte first.
I suppose my confusion is because the value doesn't seem to simply rotate, but rather, the byte that was set seems to move from the highest address to the lowest address. Before the rotate, the bytes from lowest to highest are 0000000000000080. After the rotate, I'd expect the result to be 0000000000000100, but actually it's 0100000000000000. It actually swapped from the highest address to the lowest address (or so it appears to me).
...then right shift 7 bits, which doesn't make any sense.
I have very little doubt that the issue is with me, that I'm visualizing this in a very wrong way, but I need a little more help to see this the correct way.
Again, you are printing the number from least to most significant bytes. If you see 0000000000000080 it actually represents a number 0x8000000000000000 = 263. If you see 0100000000000000 it actually represents a number 0x0000000000000001 = 20. The first number has only the most significant bit set, the second one has only the least significant one. Naturally it takes one rotation to get from one to another.
To help illustrate what hamsterman is saying, try this:
1 2 3 4 5 6
x = 0x001122334455667788;
// then print how you're printing:
for (i = 0; i < sizeof(x); i++) {
printf("%02x", ((unsignedchar *)(&x))[i]);
}
You'll notice the number prints as 887766554433221100, which is backwards. This is because you're printing it "backwards" (low byte first instead of high byte first like you seem to be expecting)