티스토리 뷰

Java

[Java] 비트 연산

snail voyager 2024. 10. 13. 01:53
728x90
반응형

2진수 문자열 -> int 변환

입력 문자열이 2진수 형식이어야 하며, 0과 1 이외의 값이 포함된 문자열을 입력하면 NumberFormatException이 발생

public class Main {
    public static void main(String[] args) {
        String binaryString = "1101";  // 2진수 문자열
        
        // 2진수 문자열을 int로 변환
        int decimalValue = Integer.parseInt(binaryString, 2);
        
        System.out.println(decimalValue);  // 출력: 13
    }
}

int -> 2진수 문자열 변환

public class Main {
    public static void main(String[] args) {
        int decimalValue = 13;
        
        // int를 2진수 문자열로 변환
        String binaryString = Integer.toBinaryString(decimalValue);
        
        System.out.println(binaryString);  // 출력: 1101
    }
}

2진수에서 bit 수 구하기

public class Main {
    public static void main(String[] args) {
        int num = 29;  // 2진수: 11101 (1이 4개)

        // 1 비트의 개수를 계산
        int count = Integer.bitCount(num);

        System.out.println("Number of 1 bits: " + count);  // 출력: 4
    }
    
    public int hammingWeight(int n) {
        int result = 0;

        for (int i=0; i<32; i++) {
            if ((n & (1<<i)) != 0) {	//시프트 연산과 & 연산 사용해서 직접 세기
                result++;
            }
        }
        return result;
    }
}

AND 연산

AND 연산은 두 비트가 모두 1일 때만 결과가 1

public class Main {
    public static void main(String[] args) {
        int a = 12;  // 1100 (2진수)
        int b = 10;  // 1010 (2진수)

        int result = a & b;  // AND 연산

        System.out.println("a & b = " + result);  // 출력: 8 (1000 in binary)
    }
}

OR 연산

OR 연산은 각 비트를 비교하여 둘 중 하나라도 1이면 1을 반환하고, 둘 다 0일 때만 0을 반환

public class Main {
    public static void main(String[] args) {
        int a = 12;  // 1100 (2진수)
        int b = 10;  // 1010 (2진수)

        int result = a | b;  // OR 연산

        System.out.println("a | b = " + result);  // 출력: 14 (1110 in binary)
    }
}

XOR 연산

XOR(Exclusive OR) 연산은 두 비트가 다를 때 1을 반환하고, 두 비트가 같을 때는 0을 반환

public class Main {
    public static void main(String[] args) {
        int a = 12;  // 1100 (2진수)
        int b = 10;  // 1010 (2진수)

        int result = a ^ b;  // XOR 연산

        System.out.println("a ^ b = " + result);  // 출력: 6 (0110 in binary)
    }
}

왼쪽 시프트 (<<)

<< 연산자는 비트를 왼쪽으로 지정한 횟수만큼 이동시키고, 빈 자리는 0으로 채웁니다. 

이 연산은 숫자를 2의 n승 만큼 곱하는 효과가 있습니다.

public class Main {
    public static void main(String[] args) {
        int a = 5;  // 0101 (2진수)

        int result = a << 1;  // 왼쪽으로 1비트 이동

        System.out.println("a << 1 = " + result);  // 출력: 10 (1010 in binary)
    }
}

오른쪽 시프트 (>>)

>> 연산자는 비트를 오른쪽으로 이동시키며, 부호를 유지합니다. 즉, 양수의 경우 왼쪽 빈 자리를 0으로 채우고, 

음수의 경우 왼쪽 빈 자리를 1로 채웁니다. 

이 연산은 숫자를 2의 n승 만큼 나누는 효과가 있습니다.

public class Main {
    public static void main(String[] args) {
        int a = 10;  // 1010 (2진수)

        int result = a >> 1;  // 오른쪽으로 1비트 이동

        System.out.println("a >> 1 = " + result);  // 출력: 5 (0101 in binary)
    }
}

부호 없는 오른쪽 시프트 (>>>)

>>> 연산자는 부호를 무시하고 비트를 오른쪽으로 이동시킵니다. 즉, 항상 왼쪽 빈 자리를 0으로 채웁니다. 

이 연산은 양수와 음수에 상관없이 비트를 이동시킵니다.

public class Main {
    public static void main(String[] args) {
        int a = -10;  // 음수 값

        int result = a >>> 1;  // 부호 없는 오른쪽으로 1비트 이동

        System.out.println("a >>> 1 = " + result);  // 출력: 2147483643
    }
}

Not 연산자 (~)

~ 연산자는 비트 NOT 연산자로, 비트 단위로 반전하는 연산입니다. 즉, 각 비트를 0은 1로, 1은 0으로 바꿉니다.

 1의 보수를 구할 때 사용되며, 주어진 숫자의 모든 비트를 반전시킵니다.

int x = 5;         // 5의 2진수: 00000000 00000000 00000000 00000101
int result = ~x;    // ~5의 결과: 11111111 11111111 11111111 11111010 (2진수로)

System.out.println(result);  // -6 출력

1의 보수: 각 비트를 반전시킨 값입니다. 예를 들어, 5의 1의 보수는 -6입니다.
2의 보수: 1의 보수에서 1을 더한 값입니다. 컴퓨터에서는 음수를 2의 보수로 저장합니다. 따라서, ~5는 -6이 됩니다.

2의 보수(Two's Complement) 방법

2의 보수는 양수의 이진수를 이용해 음수를 표현하는 방식입니다. 이를 위해 다음 단계를 따릅니다:

  1. 양수의 이진수 표현을 구합니다.
  2. 이진수의 모든 비트를 반전(0을 1로, 1을 0으로 바꿈)하여 1의 보수를 구합니다.
  3. 1의 보수에 1을 더해 2의 보수를 구합니다.

2의 보수 사용 이유

2의 보수를 사용하는 이유는 컴퓨터가 덧셈과 뺄셈 연산을 동일한 방식으로 처리할 수 있기 때문입니다.

덧셈기에서 음수를 더하는 것은 사실상 뺄셈을 수행하는 효과가 있습니다.

   00000101
 + 11111011
 -----------
   00000000  (결과: 0)

Integer.toUnsignedString()

 

  • 부호 없는 정수로 변환된 값을 10진수 문자열로 표현합니다.
  • Java의 int는 32비트 부호 있는 정수이기 때문에, 음수 값도 부호 없는 값으로 해석하여 변환할 수 있습니다.
  • 부호 없는 정수로 해석되므로, 음수로 해석되는 값이 양수로 변환됩니다.
public class Main {
    public static void main(String[] args) {
        int negativeNumber = -5;
        
        // -5를 부호 없는 값으로 해석해서 문자열로 변환
        String unsignedString = Integer.toUnsignedString(negativeNumber);

        System.out.println(unsignedString);  // 출력: 4294967291
    }
}

 

 

  • 부호 있는 int 값은 -2147483648에서 2147483647까지의 범위를 갖지만, 부호 없는 32비트 값으로 해석하면 0에서 4294967295까지의 범위를 갖습니다.
  • Integer.toUnsignedString()은 음수 값도 양수처럼 처리하여 그 값을 부호 없는 정수로 변환한 후 문자열로 반환합니다.

 

728x90
반응형
반응형
300x250