2013-09-02 2 views
0

Я знаю, что есть уловка, чтобы десятичное число в целое число с помощью x|0:Побитовый оператор в js противоречив?

, например:

3.14|0 ->3

Там нет округления участвует здесь:

3.999 |0 --> 3`

Вопрос

Однако: почему

9.99999999999|0 дает 9

в то время как

9.9999999999999999|0 урожайности 10?

+0

Мне больше интересно узнать, почему этот трюк работает. Не могли бы вы объяснить? – thefourtheye

+1

@ thefourtheye В JavaScript оператор '|' передает все свои аргументы в два подписи, подписанные 32-битными целыми числами. – Oswald

+0

@ Oswald Спасибо :) Я тоже видел нечто похожее, '~~ FloatNumber' – thefourtheye

ответ

2

9.9999999999999999 слишком много знаков после запятой и теряет точность представления Javascript, став 10. Вы можете проверить это: 9.9999999999999999 === 10 будет true

+0

на первом образце также теряет точность, так как он основан на двоичном представлении '(0,1 + 0,2! = 0,3)' и он также не является acccurate .... так что остался мой вопрос –

+0

Ответ заключается в том, что второе число имеет идентичное представление в памяти как 10. Следовательно, независимо от того, делаете ли вы '9.9999999999999999 | 0' или' 10 | 0', это точно то же самое. Первое число имеет точное представление '9.something', поэтому результат равен 9. – Tibos

0

мне нужно посмотреть в исходном коде светлячок, тем не менее, это интересно попробуйте несколько образцов:

>>> 9.99999999999999999.toString(2) 
"1010" 
>>> 9.9999999999999999.toString(2) 
"1010" 
>>> 9.999999999999999.toString(2) 
"1001.1111111111111111111111111111111111111111111111111" 
>>> 9.999999999999999.toString(2).length 
54 
>>> 9.99999999999999.toString(2) 
"1001.111111111111111111111111111111111111111111111101"  
>>> 9.99999999999999.toString(2).length 
53 

Грубая оценка: около 49 бит входят в мантию, которая оставляет 15 бит для знака и экспонента.

Обновление: я нашел интересную запись в FAQ по comp.lang.javascript, см. http://www.jibbering.com/faq/#FAQ4_7 Он ограничивает точность двойного типа до 53 бит.

Я думаю, что точность исчерпана во время шага, когда он преобразует двойной в 32-битный int до поразрядного логического или операции.

Смежные вопросы