2013-03-18 5 views
1

Учитывая следующий код:Бит проблема сдвига

public class Something { 
public static void main(String[] args) { 
    int num = 1; 

    num <<= 32; 
    System.out.println(num); 

    num = 1; 
    for (int i = 0 ; i < 32; i++) 
     num <<= 1; 
    System.out.println(num); 
} 
} 

первый выход (от NUM < < = 32) равен 1.

и второй выход (из цикл) равен 0.

Я не понимаю, он выглядит таким же, как и я .. в обоих направлениях сдвинуть цифру «1» (lsb) 32 раза, а результаты разные.

Может ли кто-нибудь объяснить?

Заранее спасибо.

ответ

5

Может ли кто-нибудь объяснить?

Абсолютно. В основном операции сдвига на int имеют правильный операнд, замаскированный для получения значения в диапазоне [0, 31]. Операции сдвига на long замаскированы, чтобы получить значение в диапазоне [0, 63].

Итак:

num <<= 32; 

эквивалентно:

num <<= 0; 

От section 15.19 of the JLS:

Если расширенный тип левого операнда INT, только пять низкая биты порядка правого операнда используются как расстояние сдвига. Это как если бы правый операнд подвергался побитовому логическому оператору И & (§15.22.1) с значением маски 0x1f (0b11111). Поэтому фактически используемое расстояние сдвига всегда находится в диапазоне от 0 до 31 включительно.

+0

Подробнее см. В [JLS 15.19] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.19). –

+0

@LouisWasserman: Yup, добирался туда :) –

+0

Perfect. Большое спасибо. понял. – Rouki

0

Для операторов сдвига бит на int, только 5 lowest order bits are used. Так << 32 ничего не делает; это эквивалентно << 0, потому что последние 5 бит 32 равны 0. Но операции << 1 в цикле выполняют как ожидалось.

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