我正在用JavaScript创建位掩码。它对于位0到14正常工作。当我仅将15位设置为1时,它会产生“-2147483648”而不是“2147483648”的整数值。我可以通过返回硬编码的“2147483648” 15位来进行特殊情况的破解,但是我想知道正确的方法。

样例代码:

function join_bitmap(hex_lower_word, hex_upper_word)
{
    var lower_word = parseInt(hex_lower_word, 16);
    var upper_word = parseInt(hex_upper_word, 16);
    return (0x00000000ffffffff & ((upper_word<<16) | lower_word));
}

当hex_lower_word为“0x0”且hex_upper_word为“0x8000”而不是2147483648时,以上代码返回-2147483648

最佳答案

如先前的答案所述,按位运算符是32位带符号的。因此,如果您在设置位31的过程中的任何时候出现了严重错误。

在您的代码中,表达式

(upper_word<<16) | lower_word)

首先由于括号而被求值,并且因为upper_word设置了最高位,所以现在您将得到一个负数(0x80000000 = -2147483648)

解决方案是确保不要将1移入第31位-因此必须在移入前将高位字的第15位设置为零:
mask15 = 0x7fff;
((upper_word&mask15)<<16|lower_word)

这将解决“太大的数字变为负数”的问题,但不能完全解决问题-只会给出错误的答案!要返回正确的答案,您需要在答案中设置第31位,前提是在upper_word中设置了第15位:
bit15 = 0x8000;
bit31 = 0x80000000;
answer = answer + (upper_word & bit15)?bit31:0;

重写后的函数将变为:
function join_bitmap(hex_lower_word, hex_upper_word)
    {
        var lower_word = parseInt(hex_lower_word, 16);
        var upper_word = parseInt(hex_upper_word, 16);
        var mask15 = 0x7fff;
        var bit15 = 0x8000;
        var bit31 = 0x80000000;
        return 0xffffffff & (((upper_word&mask15)<<16) | lower_word) + ((upper_word & bit15)?bit31:0);
    }

不仅有一个“硬编码特殊情况”-大约有20亿个。这会照顾所有的人。

10-06 11:48