Почему результат разный?
важность: 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 теперь стоит в начале числа и является знаковым