Как x | 0 заполняет номер в JavaScript?

В принятом ответе на мой предыдущий вопрос (Какой самый быстрый способ генерировать случайное целое в javascript?), мне было интересно, как число теряет свои десятичные знаки через символ | .

Например:

var x = 5.12042;
x = x|0;

Как это слово набирает номер 5?

Еще несколько примеров:

console.log( 104.249834 | 0 ); //104
console.log( 9.999999 | 0 );   // 9

Ответ 1

Поскольку, согласно спецификациям ECMAScript, операторы побитовых операторов вызывают ToInt32 для каждого оцениваемого выражения.

См. 11.10 Бинарные побитовые операторы:

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

  • Оцените A.

  • Вызов GetValue(Result(1)).

  • Оцените B.

  • Вызов GetValue(Result(3)).

  • Вызов ToInt32(Result(2)).

  • Вызов ToInt32(Result(4)).

  • Примените побитовый оператор @ к Result(5) и Result(6). Результатом является подписанное 32-битное целое число.

  • Возврат Result(7).

Ответ 2

Побитовые операторы преобразуют свои аргументы в целые числа (см. http://es5.github.com/#x9.5). Большинство языков, которые я знаю, не поддерживают такой тип преобразования:

    $ python -c "1.0|0"
    Traceback (most recent call last):
      File "", line 1, in 
    TypeError: unsupported operand type(s) for |: 'float' and 'int'

    $ ruby -e '1.0|0'
    -e:1:in `': undefined method `|' for 1.0:Float (NoMethodError)

    $ echo "int main(){1.0|0;}" | gcc -xc -
    : In function ‘main’:
    :1: error: invalid operands to binary | (have ‘double’ and ‘int’)

Ответ 3

При выполнении floor, хотя было бы возможно преобразовать аргумент в целое число, это не то, что будет делать большинство языков, потому что исходный тип является числом с плавающей запятой.

Лучшим способом сделать это, сохраняя тип данных, является переход на exponent цифры в mantissa и нуль остальных бит.

Если вам интересно, вы можете взглянуть на спецификацию IEEE для чисел с плавающей запятой.