我已经完成了一项任务,我需要将8位符号幅度数转换为2的补码,然后添加这两个数字。我对如何做到这一点有了一个相对好的想法,但是我不知道如何找到一个整数的第八位,这样我就可以知道该数字的符号。
总的想法是,如果符号位为0,则只返回数字,因为它已经是2的补码,如果它是1,那么我想将它设置为0,然后用〜反转所有位运算符然后添加1.
提前致谢
答案 0 :(得分:1)
假设您的计算机/编译器使用了两个补码(几乎可以肯定),并假设您希望结果为二进制补码。
使用uint8_t
来保存符号和幅度编号。
要检查是否设置了位,请使用按位AND运算符&
以及与msb对应的位掩码。要获得与位 n 对应的位掩码,请将值移位1 n 。在C代码中:
#define SIGN (1 << 7)
uint8_t sm = ...;
if(sm & SIGN) // if non-zero, then the SIGN bit is set
{
}
else // it was zero, the SIGN bit is not set
{
}
要进行实际转换,有几种方法。我只是掩盖并复制数字的相关部分,再次按位AND:
#define MAGNITUDE 0x7F
int8_t magnitude = sm & MAGNITUDE; // variable magnitude is two's compl.
编辑完整解决方案(因为有人已经发布了一个):
#define SIGN (1 << 7)
#define MAGNITUDE 0x7F
uint8_t sm = ...;
int8_t twos_compl = sm & MAGNITUDE;
if(sm & SIGN) // if non-zero, then the SIGN bit is set
{
twos_compl = -twos_compl;
}
int8_t x = ...; // some other number in two's complement
int16_t result = twos_compl + x;
作为旁注,在将~
运算符与小整数类型混合时要非常小心,因为它执行隐式整数提升。例如uint8_t x = 1
然后~my_uint8
给你0xFFFFFFFE(32位系统)而不是你想象的0xFE。
对于上述任务,根本不需要使用~
。
答案 1 :(得分:1)
您可以通过创建仅具有该位设置的掩码并使用逻辑AND来检查是否设置了高位,以查看结果是否为非零。
一旦知道设置了高位,就可以通过翻转所有位并添加一位来转换为二进制补码。
uint8_t x = (some value)
if (x & (1 << 7)) {
printf("sign bit set\n");
x = (uint8_t)((~(x & (0x7F))) & 0xFF) + 1;
printf("converted value: %02X\n", x);
}
然后您可以正常将此号码添加到其他任何人。