Почему результат разный?
важность: 5
Почему результат второго alert
такой странный?
alert( 123456789 ^ 0 ); // 123456789
alert( 12345678912345 ^ 0 ); // 1942903641
Всё дело в том, что побитовые операции преобразуют число в 32-битное целое.
Обычно число в JavaScript имеет 64-битный формат с плавающей точкой. При этом часть битов (52
) отведены под цифры, часть (11
) отведены под хранение номера позиции, на которой стоит десятичная точка, и один бит – знак числа.
Это означает, что максимальное целое число, которое можно хранить, занимает 52
бита.
Число 12345678912345
в двоичном виде: 10110011101001110011110011100101101101011001
(44 цифры).
Побитовый оператор ^
преобразует его в 32-битное путём отбрасывания десятичной точки и «лишних» старших цифр. При этом, так как число большое и старшие биты здесь ненулевые, то, естественно, оно изменится.
Вот ещё пример:
// в двоичном виде 1000000000000000000000000000000 (31 цифры)
alert( Math.pow(2, 30) ); // 1073741824
alert( Math.pow(2, 30) ^ 0 ); // 1073741824, всё ок, длины хватает
// в двоичном виде 100000000000000000000000000000000 (33 цифры)
alert( Math.pow(2, 32) ); // 4294967296
alert( Math.pow(2, 32) ^ 0 ); // 0, отброшены старшие цифры, остались нули
// пограничный случай
// в двоичном виде 10000000000000000000000000000000 (32 цифры)
alert( Math.pow(2, 31) ); // 2147483648
alert( Math.pow(2, 31) ^ 0 ); // -2147483648, ничего не отброшено,
// но первый бит 1 теперь стоит в начале числа и является знаковым