从其字节计算整数会产生奇怪的错误结果

时间:2013-09-04 02:40:57

标签: c integer endianness base-conversion

我正在尝试从一个以小端格式存储的数据文件中读取一个整数。一旦我得到相应的字节,我最初通过将数字乘以它们的权重(下面的aritmetic方法)来计算整数值,但由于某种原因,该值总是在最高有效字节上被一个单位关闭。

其他方法似乎有效,但我想知道为什么在使用以下代码时结果是错误的。

#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);
}

输出结果为:

Shifting method: 73BD == 74BD?
Shift + Masking: 74BD == 74BD?
     Arithmetic: 73BD == 74BD?
           Hack: 74BD == 74BD?

正如您所看到的,使用普通移位或乘法会给出错误的答案。为什么呢?

2 个答案:

答案 0 :(得分:3)

我已经完成了这一百次。变化:

char b[2] = {0xBD, 0x74};

unsigned char b[2] = {0xBD, 0x74};

或者,更好的

uint8_t b[2] = {0xBD, 0x74};

注意char可以超过8位(我在一个32位字符大小的系统上工作)

答案 1 :(得分:0)

要进一步探索此问题,请尝试以下值:

 char b[2] = {0xBD, 0x01};
 char b[2] = {0xBD, 0x00};