带有2s补码的额外字节

时间:2017-05-05 05:24:22

标签: c

当我找到一个字节的二进制补码时,我得到了很多额外的字节。

例如“eb”变成“ffffff15”。当我打印这个时,它是-235,而不是像我期望的那样-21。

//unsigned char a[] holds bytes
int b=(int)a[i];
bit1=(b & 0x80 ? 1 : 0);
if (bit1==1){
  b=((~b)+1);
}
printf("b: %02x",b);

这打印ffffff15。 (%d打印-235)。

2 个答案:

答案 0 :(得分:2)

您没有发布完整代码,但似乎a必须是unsigned char数组或unsigned char指针,或char数组且类型{{ 1}}在您的平台上未签名。将char转换为a[i]不会更改该值,并评估为(int)

公式235不会扩展最重要的位,而只是计算为b=((~b)+1);。因此结果为b = -b

要复制到最重要的位,您可以写:

-235

这是一个完整的例子:

b = (a[i] & 0xFF) | (-bit1 & ~0xFF);

打印:

#include <stdio.h>

int main() {
    // a is a byte array
    unsigned char a[] = "0a\xeb";

    for (size_t i = 0; i < sizeof a; i++) {
        int b = (int)a[i];
        int s = (b & 0xFF) | ((b & 0x80) ? ~0xFF : 0);
        printf("a[%zd] = 0x%hhx, b: 0x%x, %d, s: 0x%x, %d\n",
               i, a[i], b, b, s, s);
    }
    return 0;
}

答案 1 :(得分:0)

试图理解问题:“<above_id>变成eb。当我打印这个时,它是-235,而不是-21”。 因此,您似乎希望ffffff15以十进制表示ffffff15,这看起来好像您对如何表示负积分值有一个(非常常见的)误解:将数字设为负值不仅仅是设置单个“负”位,但实际上反转所有位(并添加-21)。我们假设一个8位的例子:

1

正如您所看到的,将整数1..0000001 -1..11111111 2..0000010 -2..11111110 3..0000011 -3..11111101 ... 置为负数会将其实际变为int x(与INT_MAX - x + 1相同),而不是~x + 1。反之,x | 0x800000代表0xfffff15,表示0xfffffff - 0xeb + 1,而非-235