Всё дело в том, что побитовые операции преобразуют число в 32-битное целое. Обычно число в JavaScript имеет 64-битный формат с плавающей точкой. При этом часть битов (`52`) отведены под цифры, часть (`11`) отведены под хранение номера позиции, на которой стоит десятичная точка, и один бит -- знак числа. Это означает, что максимальное целое число, которое можно хранить, занимает `52` бита. Число `12345678912345` в двоичном виде: `10110011101001110011110011100101101101011001` (44 цифры). Побитовый оператор `^` преобразует его в 32-битное путём отбрасывания десятичной точки и "лишних" старших цифр. При этом, так как число большое и старшие биты здесь ненулевые, то, естественно, оно изменится. Вот ещё пример: ```js //+ run // в двоичном виде 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 теперь стоит в начале числа и является знаковым ```