티스토리 뷰

Java/기본

022. 자바 : 시프트연산자

따강아지 2022. 3. 6. 16:26

자바에서 비트로 처리되는 연산자 중 하나로 비트의 위치를 좌우로 이동하는 연산자입니다.
>> 연산자는 부호 비트를 유지하면서 이동하므로 2의 배수 계산할 때 유용합니다

1Byte 기준으로 시프트 할 때 넘어가면 삭제, 들어오면 0으로 채워집니다.

 

<< 명시된 수만큼 비트들을 전부 왼쪽으로 이동시킴. (left shift 연산)
>> 부호를 유지하면서 지정한 수만큼 비트를 전부 오른쪽으로 이동시킴. (right shift 연산)
>>> 지정한 수만큼 비트를 전부 오른쪽으로 이동시키며, 새로운 비트는 전부 0이 됨.

1. 양수 시프트 연산

부호비트는 유지 하면서 이동 : 2 의 배수&amp;nbsp;

      int flags = 0b00110011;
      System.out.println(String.format("십진수 : %s, 이진수 : %s",
            Integer.valueOf(flags), Integer.toBinaryString(flags)));  // 1)
      flags = flags << 1;
      System.out.println(String.format("십진수 : %s, 이진수 : %s",
            Integer.valueOf(flags), Integer.toBinaryString(flags)));  // 2)
      flags = flags << 1;
      System.out.println(String.format("십진수 : %s, 이진수 : %s",
            Integer.valueOf(flags), Integer.toBinaryString(flags)));  // 3)
1) 십진수 : 51, 이진수 : 110011
 -> 자바에서 Binary(이진수)을 변수에 저장하기 위해서는 0b(숫자 0)를 사용합니다. 
 -> Integer.valueOf(정수) : 기본 자료형 int를 Integer 객체로 변환 해 주는 API
2) 십진수 : 102, 이진수 : 1100110  => flags = flags << 1 한번 수행 
3) 십진수 : 204, 이진수 : 11001100 => flags = flags << 1 한번 수행 

2. 음수 시프트 연산

부호비트는 유지 하면서 이동 : 2 로 나눔

int flagsNegative = -0b00110011;
System.out.println(String.format("십진수 : %s, 이진수 : %s",
            Integer.valueOf(flagsNegative), Integer.toBinaryString(flagsNegative))); // 1)
            
flagsNegative = flagsNegative << 1;
System.out.println(String.format("십진수 : %s, 이진수 : %s",
            Integer.valueOf(flagsNegative), Integer.toBinaryString(flagsNegative))); // 2)
            
flagsNegative = flagsNegative << 1;
System.out.println(String.format("십진수 : %s, 이진수 : %s",
            Integer.valueOf(flagsNegative), Integer.toBinaryString(flagsNegative)));  //3)
            
flagsNegative = flagsNegative << 1;
System.out.println(String.format("십진수 : %s, 이진수 : %s",
            Integer.valueOf(flagsNegative), Integer.toBinaryString(flagsNegative)));  //4)
1) 십진수 : -51, 이진수  : 11111111 11111111 11111111 11001101
2) 십진수 : -102, 이진수 : 11111111 11111111 11111111 10011010
3) 십진수 : -204, 이진수 : 11111111 11111111 11111111 00110100
4) 십진수 : -408, 이진수 : 11111111 11111111 11111110 01101000

int flagsRight = 0b00110011;
System.out.println(String.format("십진수 : %s, 이진수 : %s",
     Integer.valueOf(flagsRight), Integer.toBinaryString(flagsRight)));
     // 십진수 : 51, 이진수 : 110011
     
flagsRight = flagsRight >> 1;
System.out.println(String.format("십진수 : %s, 이진수 : %s",
     Integer.valueOf(flagsRight), Integer.toBinaryString(flagsRight)));
     // 십진수 : 25, 이진수 : 11001
     
flagsRight = flagsRight >> 1;
System.out.println(String.format("십진수 : %s, 이진수 : %s",
     Integer.valueOf(flagsRight), Integer.toBinaryString(flagsRight)));
     // 십진수 : 12, 이진수 : 1100

int flagsRightNegative = -0b00110011;
System.out.println(String.format("십진수 : %s, 이진수 : %s",
     Integer.valueOf(flagsRightNegative), Integer.toBinaryString(flagsRightNegative)));
     // 십진수 : -51, 이진수 : 11111111111111111111111111001101
     
flagsRightNegative = flagsRightNegative << 1;
System.out.println(String.format("십진수 : %s, 이진수 : %s",
     Integer.valueOf(flagsRightNegative), Integer.toBinaryString(flagsRightNegative)));
     // 십진수 : -102, 이진수 : 11111111111111111111111110011010
     
flagsRightNegative = flagsRightNegative << 1;
System.out.println(String.format("십진수 : %s, 이진수 : %s",
     Integer.valueOf(flagsRightNegative), Integer.toBinaryString(flagsRightNegative)));
     // 십진수 : -204, 이진수 : 11111111111111111111111100110100

3. >>> : 지정한 수만큼 비트를 전부 오른쪽으로 이동시키며, 새로운 비트는 전부 0이 됨.

양수가 음수가 될 수 있음

int flagsLogic = 0b00110011;
System.out.println(String.format("십진수 : %s, 이진수 : %s",
     Integer.valueOf(flagsLogic), Integer.toBinaryString(flagsLogic)));
     // 십진수 : 51, 이진수 : 110011
flagsLogic = flagsLogic >>> 1;
System.out.println(String.format("십진수 : %s, 이진수 : %s",
     Integer.valueOf(flagsLogic), Integer.toBinaryString(flagsLogic)));
     // 십진수 : 25, 이진수 : 11001
flagsLogic = flagsLogic >>> 1;
System.out.println(String.format("십진수 : %s, 이진수 : %s",
     Integer.valueOf(flagsLogic), Integer.toBinaryString(flagsLogic)));
     // 십진수 : 12, 이진수 : 1100

3-1 : 음수의 시프트 연산 주의사항 ( 음수에서 시프트 연산 발생 시 양수로 변경됨 )

부호비트를 포함 이동 : 음수인 경우 논리 시프트 이후 양수

int flagsLogicNegative = -0b00110011;
System.out.println(String.format("십진수 : %s, 이진수 : %s",
     Integer.valueOf(flagsLogicNegative), Integer.toBinaryString(flagsLogicNegative))); // 1) 
  
flagsLogicNegative = flagsLogicNegative >>> 1;
System.out.println(String.format("십진수 : %s, 이진수 : %s",
     Integer.valueOf(flagsLogicNegative), Integer.toBinaryString(flagsLogicNegative))); // 2) 

flagsLogicNegative = flagsLogicNegative >>> 1;
System.out.println(String.format("십진수 : %s, 이진수 : %s",
     Integer.valueOf(flagsLogicNegative), Integer.toBinaryString(flagsLogicNegative))); //3 )
1) 십진수 : -51, 이진수 : 11111111111111111111111111001101
2) >>> 1 시프트 연산 하면 무조건 시프트 연산을 수행하므로 : 이진수 : 1111111111111111111111111100110로 부호 없는 값으로 변경이 되어 십진수 : 2147483622로 변경됩니다,
3) >>> 1 ->  십진수 1073741811, 이진수 : 111111111111111111111111110011

'Java > 기본' 카테고리의 다른 글

024. 자바 : 논리 연산자  (0) 2022.03.06
023. 자바 : 비교연산자  (0) 2022.03.06
021. 자바 : 비트연산자  (0) 2022.03.06
020. 자바 : 증감연산자  (0) 2022.03.06
019. 자바 : 산술연산자  (0) 2022.03.06