当我找到一个字节的二进制补码时,我得到了很多额外的字节。
例如“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)。
答案 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
。