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。我该怎么做才能解决这个问题?
答案 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`