我正在用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亿个。这会照顾所有的人。