본문 바로가기

Java/기초

[Java] 진법

1. 10진법과 2진법

변수에 값을 저장하면 10진수로 저장되는 것처럼 보이지만, 컴퓨터는 2진수(0과 1) 밖에 모르기 때문에 2진수로 바뀌어 저장된다

2진수 10진수
0 0
1 1
10 2
11 3
100 4
1010 10

- 2진수는 2가 없으므로 자리올림이 발생해서 10이된다.

- 10진수도 표현할 수 있는 제일 큰 수인 9 다음에는 자리올림이 발생한다.

2. 비트(bit)와 바이트(byte)

한 자리의 2진수를 '비트(bit, binary digit)'라고 하며, 1 비트는 컴퓨터가 값을 저장할 수 있는 최소 단위이다. 그러나 1 비트는 너무 작은 값이기 때문에 1비트 8개를 묶어서 '바이트(byte)라는 단위로 정의해서 데이터의 기본 단위로 사용한다.

이 외에도 '워드(word)'라는 단위는 'CPU가 한 번에 처리할 수 있는 데이터의 크기'를 말한다.

8 bit   = 1 byte

4 byte = 1 word

 

n비트로 표현할 수 있는 10진수

- 값의 개수 : 2n

- 값의 범위 : 0 ~ 2n-1

3. 8진법과 16진법

8진수는 2진수 3자리를, 16진수는 2진수 4자리를 각각 한자리로 표현할 수 있기 때문에 자리수가 짧아져서 알아보기도 쉽고 서로간의 변환방법 또한 매우 간단하다.

2진수 8진수 10진수 16진수
0 0 0 0
1 1 1 1
10 2 2 2
11 3 3 3
100 4 4 4
101 5 5 5
110 6 6 6
111 7 7 7
1000 10 8 8
1001 11 9 9
1010 12 10 A
1011 13 11 B
1100 14 12 C
1101 15 13 D
1110 16 14 E
1111 17 15 F
10000 20 16 10

 

4. 2진수를 8진수, 16진수로 변환

2진수를 8진수로 변환하려면, 2진수를 뒤에서부터 3자리씩 끊어서 그에 해당하는 8진수로 바꾸면 된다. 8은 23이기 때문에, 8진수 한 자리가 2진수 3자리를 대신할 수 있는 것이다. 2진수를 16진수로 변환하는 방법 역시 이와 비슷한데, 3자리가 아닌 4자리씩 끊어서 바꾼다는 점만 다르다.

[참고] 8진수 또는 16진수를 2진수로 변환하려면 위와 반대로 과장을 거치기만 하면 된다.

 

1010101100(2) = 1254(8) = 2AC(16)

 

5. 실수의 진법변환

10진 소수점수를 2진 소수점수로 변환하는 방법

10진 정수를 2진 정수로 변환할 때, 10진수를 2로 계속 나누면서 나머지를 구했던 것과 반대로, 10진 소수수점수를 2진 소수점수로 변환하는 방법은 이와 반대로 10진 소수점수에 2를 계속 곱한다.

ex. 10진수 0.625를 2진수로 변환하는 방법

1) 10진 소수에 2를 곱한다.

  0.625 X 2 = 1.25

2) 위의 결과에서 소수부만 가져다가 다시 2를 곱한다.

  0.625 X 2 = 1.25

  0.25  X 2 = 0.5

3) 1)과 2)의 과정을 소수부가 0이 될 때까지 반복한다.

  0.625 X 2 = 1.25

  0.25  X 2 = 0.5

  0.5   X 2 = 1.0

4) 위의 결과에서 정수부만을 위해서 '0.'을 적고 순서대로 붙이면 된다.

  0.625(10) -> 0.101(2)

 

6. 음수의 2진 표현 - 2의 보수법

n비트의 2진수로 표현할 수 있는 값의 개수는 모두 2n개이므로, 4비트의 2진수로는 모두 24=16개의 값을 표현할 수 있다.

 

# 2진수 부호있는 10진수
1 0000 0
2 0001 1
3 0010 2
4 0011 3
5 0100 4
6 0101 5
7 0110 6
8 0111 7-> 최댓값
9 1000 -0
10 1001 -1
11 1010 -2
12 1011 -3
13 1100 -4
14 1101 -5
15 1110 -6
16 1111 -7->최소값

위처럼 음수를 이렇게 배치하면, 양수의 첫 번째 비트만 1로 바꾸면 음수가 된다는 장점이 있다. 그러나 두 수를 더했을 때 2진수로 0이 되지 않는다는 것과 0이 두개(0, -0) 존재한다는 단점이 있다.

# 2진수 부호있는 10진수
1 0000 0
2 0001 1
3 0010 2
4 0011 3
5 0100 4
6 0101 5
7 0110 6
8 0111 7-> 최댓값
9 1000 -8->최소값
10 1001 -7
11 1010 -6
12 1011 -5
13 1100 -4
14 1101 -3
15 1110 -2
16 1111 -1

그러나 위와 같이 '2의 보수법;에 의해 음수를 배치하면, 절대값이 같은 양수와 음수를 더했을 때 2진수로도 0을 결과로 얻으므로 부호를 신경 쓰지 않고 덧셈할 수 있게 된다. 그리고 2진수가 증가할 때 10진 음수가 감소한다는 모순도 없어졌다. 다만, 첫 번째 비트를 바꾸는 것만으로 값의 부호를 바꿀 수 없게 되었다.

 

2의 보수법(보수 : 부호가 다르고 절대값이 같은 수)

어떤 수의 'n의 보수'는 더했을 때 n이 되는 수를 말한다. 7의 '10의 보수'는 3이고, 3의 '10의 보수'는 7이 된다. 3과 7은 '10의 보수의 관계'에 있다고 한다. '2의 보수 관계' 역시, 더해서 2가 되는 두 수의 관계를 말하여 10진수 2는 2진수로 '10'이다. 2진수로 '10'은 자리올림이 발생하고 0이 되는 수를 뜻한다. 

 

    0101 <- 10진수로 5

+) 1011 <- 10진수로 -5

----------------------------

 1 0000 <- 자리올림이 발생했으나 크기가 4비트라서 버려짐

 

2진수 0101과 1011은 서로 '2의 보수 관계'에 있으며 이 두 2진수를 더하면 0이 된다. 

 

음수를 2진수로 표현하기

10진 음의 정수를 2진수로 변환하려면, 먼저 10진 음의 정수릐 절대값을 2진수로 변환한다. 그 다음에 이 2진수의 '2의 보수'를 구하면 된다. 

-5 -> 절대값 -> 5(10) -> 2진수 -> 0101(2) ->2의 보수 -> 1011(2)

 

2의 보수 구하기

서로 '2의 보수'의 관계에 있는 두 수를 더하면 '0(자리올림 발생)'이 된다.

0101 + 2의 보수 = 1 0000

1 0000 - 0101 = 1011 처럼 간단히 구할 수 있지만 자리수가 많아지면 뺄셈도 쉽지 않다.

 

따라서 2의 보수 = 1의 보수 + 1

'1의 보수'는 0을 1로, 1을 0으로만 바꾸면 되므로 구하기 쉽다. 

    0101

    1010  <- '0101'의 '1의 보수'

+)      1

------------

   1011  <- '0101'의 '2의 보수'

 

※ 정리

음수의 2진 표현을 구하는 방법

1) 음수의 절대값을 2진수로 변환한다

- -5의 절대값인 5를 2진수로 변환하다. 10진수 5를 2진수로 변환하면 '0101'이다

2) 1)에서 구한 2진수의 1을 0으로 0은 1로 바꾼다(1의 보수 구하기)

- '0101'이 '1010'이 된다.

3) 2)의 결과에 1을 더한다.(2의 보수 구하기, 1의 보수 +1)

- '0101'에 1을 더하면 '1011'이 되고, 이것이 -5의 2진 표현이다.