为什么我的二进制补码在javascript中会得到完全不同的结果

ewm0tg9j  于 2023-01-16  发布在  Java
关注(0)|答案(1)|浏览(106)

我目前正在计算一个字节缓冲区的校验和,每个字节32位,我必须计算两个校验和,字节缓冲区的每个组件都有32位unint sum和32位unint XOR(除了某些位置)。求和按预期工作,但异或给我一个奇怪的值。我从异或得到的值是**-58679487**,当应用二进制补码时,我得到58679487但当转换为十六进制值时,它是0x 037 F60 BF,而我正在查找0xFC 809 F41。如果我将初始异或值(-58679487)放入rapidtables并将其从十进制转换为十六进制,它将以十六进制显示正确的二进制补码值。我做错了什么?

i=startAddress;
    while(i<buf.length){
        if(i !== chk1 && i!== chk2 && i!== chk3 && i!== chk4){
            file32Sumt += buf.readUint32BE(i);
            file32Xort ^= buf.readUint32BE(i);
                    i+=4;
            }else{
                console.log('cks location.'+ buf.readUint32BE(i).toString(16));
                i+=4;
                }
         }
//two's complement
console.log((~file32Sumt+1).toString(16));
console.log((~file32Xort+1).toString(16));

已经通过使用位NOT运算符(~)然后加1完成了2的补码,但似乎不起作用。还尝试使用Math.abs(file 32 Xort),但得到了相同的结果。

bvhaajcl

bvhaajcl1#

不要否定,用这个:

console.log((file32Xort >>> 0).toString(16));

file32Xort已经有了正确的值,但是是一个 signed 32位整数。这里需要的是相同值的无符号解释。number >>> 0is a simple way to do that reinterpretation
另外,我觉得你应该写

file32Sumt = (file32Sumt + buf.readUint32BE(i)) >>> 0;

..或类似的东西,这次使用一些按位运算符(它不一定是无符号右移,但我认为在这种情况下是有意义的),以防止和变得太大(通过将其限制为32位)并可能表现出浮点舍入。file32Xort的计算已经使用了位运算符,因此不需要像那样的额外运算符,仅在末尾将结果重新解释为无符号。

相关问题