Я задаю этот вопрос в качестве продолжения моего предыдущего вопроса.
На странице в W3chools говорится:
В приведенных выше примерах используются 4 бита беззнаковых двоичных чисел. Из-за этого ~ 5 возвращает 10.
Поскольку JavaScript использует 32 бита со знаком целых чисел, он не вернет 10.
Он вернет -6. 00000000000000000000000000000101 (5)
11111111111111111111111111111010 (~ 5 = -6)
Подписанное целое число использует самый левый бит в качестве знака минус.
Инвертируя биты и прерывая бит знака, число становится 1111111111111111111111111111010, которое оценивается до 2147483642 в десятичной форме. Однако, согласно этой странице, она должна оценить -6.
Где я неправ?
Ошибка заключается в "измельчении знакового бита" 32-битного дополненного результата. Это преобразует -6 (который имеет много ведущих 1s в его двоичном представлении) в 31-битное положительное число, которое все еще имеет много ведущих 1s в своем двоичном представлении. 31-битное число, полученное путем удаления знакового бита из -6, очень близко к максимальному положительному значению 32-битного знакового числа.
Вы можете увидеть результаты без удаления 32-битного бита знака целого числа:
function unsignedNibble( i) {
return i & 0x0f;
}
function signedNumberBits( n) {
var bits = "";
for( var i = 32; i--;) {
bits = "" + (n&1) + bits;
n = n >> 1;
}
return bits;
}
console.log("Unsigned 4 bit: ");
var un5 = unsignedNibble( 5); // unsigned 4 bits of 5
console.log( "un5 = %s ( 0b%s)", un5, un5.toString(2));
var notUn5 = unsignedNibble( ~un5);
console.log( "~un5 = %s ( 0b%s)", notUn5, notUn5.toString(2));
console.log("Signed 32 bit: ");
var sn5 = 5; // signed number 5
console.log( "sn5 = %s ( 0b%s)", sn5, sn5.toString(2));
var notSn5 = ~sn5;
console.log( "~sn5 = %s ( 0b%s)", notSn5, signedNumberBits(notSn5));
~ оператор просто изменит бит.
такой как ~ 5 = ~ (00000101), он возвращает (11111010) = -6
Не делайте ~ оператора слишком сложным.