我有32位中的18位(采用二进制补码表示),需要将它们转换成十进制。请给我提供一个C语言代码片段。
我有32位中的18位(采用二进制补码表示),需要将它们转换成十进制。请给我提供一个C语言代码片段。
首先,您需要对18位进行符号扩展,以填充本机int
:
const int negative = (smallInt & (1 << 17)) != 0;
int nativeInt;
if (negative)
nativeInt = smallInt | ~((1 << 18) - 1);
else
nativeInt = smallInt;
如果这个数被认为是负数(即第17位被设置),我们将其与一个在所有剩余位上都有1的位模式进行按位或运算。这将创建适当的负本地大小整数。char buf[12];
snprintf(buf, sizeof buf, "%d", nativeInt);
当然,最后一部分可能与您的期望完全不符,它可能并不是“最快”的。由于您的输入范围仅为18位,可能可以想出更加优化的方法。if (smallInt >= (1 << 17)) smallInt -= (1 << 18);
。当然,前提是smallInt在正确的范围内,并且未使用的高位为0。 - Steve Jessop这里是16位数字的代码片段。类似的方法也适用于其他位深度。但是,我不能保证这是最快的代码片段。
int16_t twosCompToDec(uint16_t two_compliment_val)
{
// [0x0000; 0x7FFF] corresponds to [0; 32,767]
// [0x8000; 0xFFFF] corresponds to [-32,768; -1]
// int16_t has the range [-32,768; 32,767]
uint16_t sign_mask = 0x8000;
// if positive
if ( (two_compliment_val & sign_mask) == 0 ) {
return two_compliment_val;
// if negative
} else {
// invert all bits, add one, and make negative
return -(~two_compliment_val + 1);
}
}
我自己尝试过,效果非常好:
int binTwosComplementToSignedDecimal(char binary[],int significantBits)
{
int power = pow(2,significantBits-1);
int sum = 0;
int i;
for (i=0; i<significantBits; ++i)
{
if ( i==0 && binary[i]!='0')
{
sum = power * -1;
}
else
{
sum += (binary[i]-'0')*power;//The -0 is needed
}
power /= 2;
}
return sum;
}
示例:
char binary[8] = '10000001';
int significantBits = 8;
int decimal = binTwosComplementToSignedDecimal(binary,significantBits);
结果为
decimal = -127