Java 증가 및 감소 연산자 및 시프트 연산자 소개

JavaGuide 에서 발췌 ("Java Learning + Interview Guide"는 대부분의 Java 프로그래머가 마스터해야 하는 핵심 지식을 다루고 있습니다. Java 면접을 준비하려면 JavaGuide가 첫 번째 선택입니다!)

증가 및 감소 연산자

코드 작성 과정에서 일반적인 상황은 정수형 변수가 1씩 증가하거나 1씩 감소해야 하는 것입니다. Java는 이러한 종류의 표현식을 위한 자체 증가 연산자(++) 및 자체 감소 연산자(-)라는 특수 연산자를 제공합니다.

++, – 연산자는 변수 앞이나 뒤에 올 수 있는데, 연산자가 변수(접두사) 앞에 있으면 먼저 증가/감소 후 할당되고, 변수(접미사) 뒤에 연산자가 있으면 먼저 값이 할당된 후 증가/감소됩니다. 예를 들어, 그 b = ++a때 먼저 자체 증가(self-increment by 1)한 다음 할당(assign to b) b = a++; 그 때 먼저 값을 할당(assign to b)한 다음 자체 증가(self-increment by 1)합니다. 즉, ++a는 a+1의 값을 출력하고, a++는 a의 값을 출력합니다. 진언은 "먼저 기호를 더하거나 빼고, 마지막 기호 다음에 기호를 더하거나 빼십시오"입니다.

시프트 연산자

시프트 연산자는 가장 기본적인 연산자 중 하나이며 거의 모든 프로그래밍 언어에 포함되어 있습니다. 쉬프트 연산은 연산된 데이터를 2진수로 간주하고 쉬프트는 일정한 비트 수만큼 왼쪽이나 오른쪽으로 쉬프트하는 연산이다.

시프트 연산자는 다양한 프레임워크와 JDK 자체 소스 코드에서 널리 사용됩니다. HashMap(JDK1.8)의 메소드 소스 코드는 hash시프트 연산자를 사용합니다.

static final int hash(Object key) {
    
    
    int h;
    // key.hashCode():返回散列值也就是hashcode
    // ^ :按位异或
    // >>>:无符号右移,忽略符号位,空位都以0补齐
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
  }

Java 코드에서 사용되며 <<변환 된 스크립트 >>>>>보다 효율적으로 실행됩니다.

여전히 시프트 연산자에 대한 가장 기본적인 지식을 습득해야 합니다. 이는 코드에서 시프트 연산자를 사용하는 데 도움이 될 뿐만 아니라 소스 코드에서 시프트 연산자와 관련된 코드를 이해하는 데 도움이 됩니다.

Java에는 세 가지 시프트 연산자가 있습니다.

  • <<: 왼쪽 시프트 연산자, 많은 비트를 왼쪽으로 시프트하고 높은 비트를 버리고 낮은 비트를 0으로 채웁니다. x << 1, 이는 x에 2를 곱하는 것과 같습니다(오버플로우 없음).
  • >>: 부호를 사용하여 오른쪽으로 이동하고 몇 비트만큼 오른쪽으로 이동한 후 부호 비트를 높은 비트로 보완하고 낮은 비트를 버립니다. 양수는 0으로 채워지고 음수는 1로 채워집니다. x >> 1, 이는 x를 2로 나누는 것과 같습니다.
  • >>>: 부호 없는 오른쪽 시프트, 부호 비트 무시, 빈 비트를 0으로 채움.

바이너리의 성능은 매우 특별하기 때문에 시프트 연산에 사용할 수 없습니다 double.float

int시프트 연산자가 지원하는 유형은 and 뿐입니다 long. 컴파일러는 short, byte및 유형에서 char시프트를 수행하기 전에 유형으로 변환합니다 int.

이동된 비트 수가 값이 차지하는 비트 수를 초과하면 어떻게 됩니까?

int형의 좌/우 쉬프트 횟수가 32비트 이상이면 좌/우 쉬프트 연산 전에 나머지(%)를 계산한다. 즉, 좌/우로 32비트 쉬프트하는 것은 쉬프트 연산이 없는 것과 같고(32%32=0), 42비트 좌/우로 쉬프트하는 것은 좌/우로 10비트 쉬프트하는 것과 같다(42%32=10). long 타입이 좌/우 시프트 연산을 수행할 때 long에 해당하는 이진수는 64비트이므로 나머지 연산의 밑수 역시 64가 된다.

즉, x<<42같음 x<<10, x>>42같음 x>>10, x >>>42같음 x >>> 10.

왼쪽 시프트 연산자 코드 예 :

int i = -1;
System.out.println("初始数据: " + i);
System.out.println("初始数据对应的二进制字符串: " + Integer.toBinaryString(i));
i <<= 10;
System.out.println("左移 10 位后的数据 " + i);
System.out.println("左移 10 位后的数据对应的二进制字符 " + Integer.toBinaryString(i));

산출:

初始数据: -1
初始数据对应的二进制字符串: 11111111111111111111111111111111
左移 10 位后的数据 -1024
左移 10 位后的数据对应的二进制字符 11111111111111111111110000000000

왼쪽 쉬프트 횟수가 32비트보다 크거나 같으므로 왼쪽 쉬프트 연산 전에 나머지(%)를 계산하므로 다음 코드를 42비트 왼쪽으로 쉬프트한 것은 10비트 왼쪽으로 쉬프트한 것과 같고(42%32=10) 출력 결과는 이전 코드와 같다.

int i = -1;
System.out.println("初始数据: " + i);
System.out.println("初始数据对应的二进制字符串: " + Integer.toBinaryString(i));
i <<= 42;
System.out.println("左移 10 位后的数据 " + i);
System.out.println("左移 10 位后的数据对应的二进制字符 " + Integer.toBinaryString(i));

오른쪽 시프트 연산자의 사용법도 비슷하고 공간 문제가 있으므로 여기서는 설명하지 않겠습니다.

추천

출처blog.csdn.net/qq_34337272/article/details/130010981