I'm trying to read an integer from a data file which is stored raw in little endian format. Once I got the corresponding bytes I originally calculated the integer value by adding the numbers multiplied by their weight (aritmetic method below) but for some reason the value is allways off by one unit on the most significant byte.
Other methods seem to work but I want to know why the result is wrong when using the following code.
#include <stdio.h>
#include <stdint.h>
void main(){
//Two bytes that form a 16-bit integer (Little endian)
char b[2] = {0xBD, 0x74};
//This gives a correct answer (Shift + Extra masking)
uint16_t n_correct;
n_correct = (b[0] & 0xFF) + ((b[1]<<8) & 0xFF00);
//This should give a correct answer but doesn't (Shifting method)
uint16_t n_incorrect;
n_incorrect = b[0] + (b[1]<<8);
//This should also give a correct answer but doesn't (Aritmetic)
uint16_t n_arith;
n_arith = b[0] + (b[1]*256);
//This works, on little endian machines. Dirty but works. (Hack)
uint16_t n_hack;
uint8_t* n_ptr = (uint8_t*)&n_hack;
n_ptr[0] = b[0];
n_ptr[1] = b[1];
printf("Shifting method: %X == %X%X?\n", n_incorrect, b[1]&0xFF, b[0]&0xFF);
printf("Shift + Masking: %X == %X%X?\n", n_correct, b[1]&0xFF, b[0]&0xFF);
printf(" Arithmetic: %X == %X%X?\n", n_arith, b[1]&0xFF, b[0]&0xFF);
printf(" Hack: %X == %X%X?\n", n_hack, b[1]&0xFF, b[0]&0xFF);
}
The output is:
Shifting method: 73BD == 74BD?
Shift + Masking: 74BD == 74BD?
Arithmetic: 73BD == 74BD?
Hack: 74BD == 74BD?
As you can see, using plain shifting or multiplication gives the wrong answer. why?
I've done this a hundred times. Change:
To
Or, better yet
Note that
char
can be more than 8 bits (I worked on a system with a 32-bit char size)