Битовые операторы приведут к знаку 32-битному числу, означающему, что если бит в позиции 31 (считая от младшего значащего бита справа, который является битом 0) равен 1, число будет отрицательным.
Чтобы этого не происходило, используйте операторы, отличные от <<
или |
, которые приводят к получению 32-разрядного числа со знаком. Например:
(bit * 2**e) + make (more, e + 4)
Форсирование без знака 32-бит
Операторы сдвига битов предназначены для принудительного перевода результата в 32-битный диапазон со знаком, по крайней мере, заявленный для mdn (на момент написания):
Операнды всех битовых операторов преобразуются в 32-разрядные целые числа со знаком
Это на самом деле не совсем верно. Оператор >>>
является исключением из этого. EcmaScript 2015, раздел 12.5.8.1 утверждает, что операнды отображаются в без знака 32 бита перед сдвигом в 0 бит. Таким образом, даже если бы вы сместили ноль битов, вы бы увидели этот эффект.
Вам нужно будет применить его только один раз к конечному значению, как, например, в вашей функции print
:
console.log((n>>>0).toString(2))
BigInt решение
Если вам нужно больше 32 бит, и ваш движок JavaScript поддерживает BigInt , как , некоторые уже делают, тогда используйте BigInts для операндов, участвующих в побитовых операторах - они будут затем не используйте перенос 32-разрядного числа со знаком (обратите внимание на суффиксы n
):
const make = ([ bit, ...more ], e = 0n) =>
bit === undefined
? 0n
: (bit << e) + make (more, e + 4n)
const print = n =>
console.log(n.toString(2))
// Test
for (let i=1; i<20; i++) {
print(make(Array(i).fill(15n))) // longer and longer array...
}
NB. Если вы получаете сообщение об ошибке, попробуйте снова с Chrome ...