2位数的2位补码

时间:2014-08-01 20:07:04

标签: c

UInt16 Checksum16Calculate(CHECKSUM_16_TYPE* pChecksum)
{
//calculate twos compliment of checksum
pChecksum->usTwosCompliment = ~(pChecksum->usChecksum) + 1;

//store raw checksum for diagnostics
pChecksum->uiChecksumWatch = pChecksum->usChecksum;

return pChecksum->usTwosCompliment;
}



typedef struct
{
UInt16 usChecksum;
UInt16 usWordCount;
UInt16 usTwosCompliment;
UInt32 uiChecksumWatch;
}
CHECKSUM_16_TYPE;

我用& oChecksum调用CheckSumCalculate,类型为CHECKSUM_16_TYPE。让我们说计算校验和之前的数字是10010101110.用手拿两个补码给你1101010010.但我得到的数字是 111110 1101010010.忽略粗体数字我会得到正确答案。我认为这种情况正在发生,因为使用2的补码的数字是16位数,因此它将未使用的0转换为1#s。我该怎么做才能解决这个问题?

2 个答案:

答案 0 :(得分:3)

没有什么可以解决的。数字10010101110表示为16位二进制数0000010010101110;它的2补码只能是1111101010001010

答案 1 :(得分:1)

根据C标准

  

4~运算符的结果是它的按位补码   (提升)操作数(也就是说,结果中的每个位都是设置的   如果未设置转换后的操作数中的相应位)。的的   整数提升在操作数上执行,结果有   提升类型。如果提升的类型是无符号类型,则   表达式~E等于其中可表示的最大值   类型减去E.

operator ~

的操作数
~(pChecksum->usChecksum)

升级为int,您有

0000010010101110 <= original value of type `UInt16`
00000000000000000000010010101110 <= promoted value of type `int`
11111111111111111111101101010001 <= applying operator ~
11111111111111111111101101010010 <= adding 1
1111101101010010 <= assigning back the resul to the object of type `UInt16`