【问题标题】:why does byte change when bit shifting?为什么移位时字节会改变?
【发布时间】:2010-08-11 20:13:52
【问题描述】:

我正在玩位移。我正在尝试采用 32 位 int,将每个字节保存在 char 数组中,然后重构 int。它以我认为应该的方式工作,除了右边的第二个字节似乎切换了最低位。我的代码是:

int main() {
  char paus[2];
  char b[4] = "abc";
  int c = 6104;
  int d = 0xcccccccc;
  printf("c in hex: %x\n",c);
  printf("d in hex: %x\n",d);
  printf("b[0]: %x\nb[1]: %x\n",b[0]&0xff,b[1]&0xff);
  printf("b[2]: %x\nb[3]: %x/n",b[2]&0xff,b[3]&0xff);
  printf("\n");

  b[0] = c >> 24;
  b[1] = (c >> 16) & 0xff;
  b[2] = (c >> 8) & 0xff;
  b[3] = c & 0xff;
  printf("b[0]: %x\nb[1]: %x\n",b[0]&0xff,b[1]&0xff);
  printf("b[2]: %x\nb[3]: %x\n",b[2]&0xff,b[3]&0xff);
  printf("\n");

  d = (d << 8) + 0x15;
  printf("d in hex: %x\n",d);
  d = (d << 8) + b[1];
  printf("d in hex: %x\n",d);
  d = (d << 8) + b[2];
  printf("d in hex: %x\n",d);
  d = (d << 8) + b[3];
  printf("d in hex: %x\n",d);

  fgets(paus,2,stdin);
  return 0;
}

输出是:

十六进制的c:17d8
十六进制的 d:cccccccc
b[0]: 61
b[1]: 62
b[2]: 63
b[3]: 0

b[0]: 0
b[1]: 0
b[2]: 17
b[3]: d8

十六进制的d:cccccc15
d 十六进制:cccc1500
d 十六进制:cc150017
d 十六进制:150016d8

除了为什么右边的第二个字节从位移 17 向左 8 位变为 16 之外,一切都有意义? 15 和 00 字节是一路携带的,那为什么 17 字节会发生变化呢?谢谢!

【问题讨论】:

    标签: visual-c++


    【解决方案1】:

    问题在于您的编译器设置为将char 视为signed char。试试这个:

    d = (d << 8) + (unsigned char)b[3];
    printf("d in hex: %x\n",d);
    

    (您可能希望对其他实例执行相同的操作。)

    或者,您可以更改d 的声明:

    unsigned char b[4] = "abc";
    

    【讨论】:

    • 好的,谢谢。这样可行。但是为什么它会这样工作,因为只有最后一个字节的添加会改变任何东西?如果我只是移动 17 个字节,我会得到“d in hex: 15001700”。只有在添加 d8 字节后它才会改变。既然符号位是最左边的,为什么它会改变前一个字节的最右边呢?
    • 根本原因是您的最后一个字节是唯一设置了第 7 位的字节(即其十六进制值大于或等于 0x80)。高位是符号位,当它的符号扩展到32位时(因为它是从8位有符号值到32位有符号值),实际添加的值是0xffffffd8。
    • 有关二进制补码算法中负数表示的更多信息,请参阅stackoverflow.com/questions/1125304/…等问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-24
    • 1970-01-01
    • 2013-09-29
    • 2018-06-05
    • 2020-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多