Почему JavaScript побитовый ИЛИ ведет себя странно? - PullRequest
6 голосов
/ 17 февраля 2012

В JavaScript это выглядит так:

(4294958077 | 0) == -9219

Почему это не 4294958077?

Это говорит о том, что происходит какое-то переполнение (хотя, как я понимаю, это тип числа JavaScriptдиапазон +/- 9007199254740992, так что это странно само по себе.)

Даже если это было переполнение, безусловно,

(4294958077 | 0) == 4294958077

должно оцениваться как true - но это не так.

Помогите пожалуйста

Ответы [ 3 ]

5 голосов
/ 17 февраля 2012

Это не имеет ничего общего с типом с плавающей запятой или переполнением.Он возвращает -9219, потому что стандарт предписывает его, поскольку все двоичные побитовые операции должны выполняться с использованием знаковых 32-разрядных целых чисел (ECMA-262 §11.10).

Производится A : A @ B , где @ - один из побитовых операторов в приведенных выше производствах.следующим образом:

  1. Пусть lref будет результатом вычисления A .
  2. Пусть lval будет GetValue ( lref ).
  3. Пусть rref будет результатом вычисления B .
  4. Let rval be GetValue ( rref ).
  5. Пусть lnum будет ToInt32 ( lval ).
  6. Пусть rnum будет ToInt32 ( rval ).
  7. Возвращает результат применения побитового оператора @ к lnum и rnum . Результатом является 32-разрядное целое число со знаком.

4294958077, преобразованное в 32-разрядное целое число со знаком (с использованием алгоритма в ECMA-262 §9.5), равно -9219и 0 по-прежнему равен 0, поэтому побитовое «или» вернет -9219.

2 голосов
/ 17 февраля 2012

Все числа в Javascript - это 64-битные числа с плавающей запятой. Побитовые операции над числами с плавающей запятой являются крайним случаем, поэтому внутренне эти числа с плавающей запятой временно преобразуются в 32-битное целое число, затем выполняется побитовая операция - отсюда ваше переполнение.

0 голосов
/ 17 февраля 2012

Побитовые числа JavaScript хранятся как 64-битные числа со знаком, т. Е. У вас есть только 32-разрядные числа, которые вы можете использовать для целого числа, которое вы превысили, поэтому это странно, если преобразовать его в целое число как можно лучше, а затем выполнитьоперация.

Дополнительная информация здесь (особенно раздел «за пределами 32-битной системы»), но реального решения нет, поэтому, к сожалению, вам придется обойти это.

...