2012-04-08 3 views
1

У меня возникли проблемы с левой битными сдвигами в Java возвращаются неправильные значения ...Java Bit сдвиг влево Возвращает неверное значение

Возьмите 108 < < 60, например. Ответ на этот вопрос должен быть *:

124515522497539473408 

Java возвращает это значение

-4611686018427387904 

для этого утверждения:

System.out.println(108L << 60L); 

Почему ??? Оба значения принудительно длинны ... поэтому я не вижу причин, по которым любые битовые значения должны быть усечены. Что мне здесь не хватает?

* Образец цитирования: Wolfram Alpha

+3

Хм ... какое наибольшее значение может держать 'long'? – Mysticial

+0

Я верю, что это в квадриллионах? – bgroenks

ответ

4

Вы смещаются за пределы длины long (64 бита). 108 занимает семь бит, поэтому 108L << 60L требует, чтобы 67 бит представляли его правильно. Фактически, поскольку это подписанный тип, вам понадобится 68 бит, чтобы избежать его интерпретации как отрицательного числа.

+0

Хорошо спасибо. Я пропустил это. – bgroenks

1

108 - 7 бит, поэтому < < 60 - 67 бит.

1

Число, которое представляет 108L << 60, является слишком большим, чтобы быть представленным как long. Таким образом, вы получаете переполнение и теряете бит высокого порядка.

Если вы хотите представить цифры, это большое (без усечения), самым простым было бы использовать BigInteger.

Кстати, вторым операндом оператора смены не должно быть long. Фактическое количество сдвига рассчитывается путем усечения операнда до числа в диапазоне от 0 до 63 (для сдвига long) - см. JLS 15.19.

+0

Да, BigInteger работает. – bgroenks