N Log

진법 변환

정수의 진법 변환

n진수를 10진수로 변환

1000112=1×25+0×24+0×23+0×22+1×21+1×20=32+0+0+0+2+1=3510438=4×81+3×80=32+3=35102316=2×161+3×160=32+3=3510\begin{aligned} 10\,0011_2 &= 1 \times 2^5 + 0 \times 2^4 + 0 \times 2^3 + 0 \times 2^2 + 1 \times 2^1 + 1 \times 2^0 \\ &= 32 + 0 + 0 + 0 + 2 + 1 = 35_{10} \\ \\[0.5em] 43_8 &= 4 \times 8^1 + 3 \times 8^0 \\ &= 32 + 3 = 35_{10} \\ \\[0.5em] 23_{16} &= 2 \times 16^1 + 3 \times 16^0 \\ &= 32 + 3 = 35_{10} \end{aligned}

각 자리의 수에 해당 자릿값을 곱한 뒤 모두 더하면 10진수 값을 구할 수 있다.
자릿값은 n1n^1이 아니라 n0n^0부터 시작한다는 점에 주의해야 한다.

2진수와 8진수 사이의 변환

10 001 011 011(2)=2133(8)10\ 001\ 011\ 011\,(2) = 2133\,(8)

8은 232^3이므로 2진수 세 자리와 8진수 한 자리가 대응한다.

2진수를 8진수로 바꿀 때는 오른쪽부터 세 자리씩 묶어 각 묶음을 8진수 한 자리로 바꾼다.
왼쪽 끝 묶음이 세 자리가 되지 않으면 앞의 빈자리를 0으로 간주한다.

8진수를 2진수로 바꿀 때는 각 8진수 한 자리를 대응하는 세 자리 2진수로 바꾼다.

2진수와 16진수 사이의 변환

1 0101 1100 0011(2)=15C3(16)1\ 0101\ 1100\ 0011\,(2) = 15C3\,(16)

16은 242^4이므로 2진수 네 자리와 16진수 한 자리가 대응한다.

2진수를 16진수로 바꿀 때는 오른쪽부터 네 자리씩 묶어 각 묶음을 16진수 한 자리로 바꾼다.
왼쪽 끝 묶음이 네 자리가 되지 않으면 앞의 빈자리를 0으로 간주한다.

16진수를 2진수로 바꿀 때는 각 16진수 한 자리를 대응하는 네 자리 2진수로 바꾼다.

10진수를 n진수로 변환

2 ) 35 ... 1          8 ) 35 ... 3          10 ) 35 ... 5         16 ) 35 ... 3
2 ) 17 ... 1          8 )  4 ... 4          10 )  3 ... 3         16 )  2 ... 2
2 )  8 ... 0               0                      0                     0
2 )  4 ... 0
2 )  2 ... 0          43(8)                 35(10)                23(16)
2 )  1 ... 1
     0

10 0011(2)

n진법에서는 한 자리에 0부터 n-1까지, 모두 n개의 숫자를 사용한다.
2진수에서는 01을 사용한다.
8진수에서는 0부터 7까지를 사용한다.
10진수에서는 0부터 9까지를 사용한다.
16진수에서는 0부터 F까지를 사용한다.
따라서 n으로 나눈 나머지는 n진수의 한 자리 숫자로 사용할 수 있다.

처음 구한 나머지는 가장 낮은 자리인 일의 자리다.
위의 10진수 예시를 보면 알 수 있다.
나머지는 일의 자리에서 높은 자리 순서로 쌓인다.
따라서 마지막 나머지부터 처음 나머지까지 거꾸로 읽는다.

실수의 진법 변환

2진수를 10진수로 변환

0.1012=1×21+0×22+1×23=0.5+0+0.125=0.62510\begin{aligned} 0.101_2 &= 1 \times 2^{-1} + 0 \times 2^{-2} + 1 \times 2^{-3} \\ &= 0.5 + 0 + 0.125 \\ &= 0.625_{10} \end{aligned}

각 자리의 수에 해당 자릿값을 곱한 뒤 모두 더하면 10진수 값을 구할 수 있다.

10진수를 2진수로 변환

첫째 자리 구하기0.625=x121+x222+x323++xn2n2×0.625=2×(x121+x222+x323++xn2n)1.250=x1+x221+x322++xn2(n1)1.250=1+x221+x322++xn2(n1)x1=1둘째 자리 구하기0.250=x221+x322++xn2(n1)2×0.250=2×(x221+x322++xn2(n1))0.500=x2+x321++xn2(n2)0.500=0+x321++xn2(n2)x2=0셋째 자리 구하기0.500=x321++xn2(n2)2×0.500=2×(x321++xn2(n2))1.000=x3+x421++xn2(n3)1.000=1+x421++xn2(n3)x3=10.62510=0.1012\begin{aligned} \text{첫째 자리 구하기} & \\[2pt] 0.625 &= x_1 2^{-1} + x_2 2^{-2} + x_3 2^{-3} + \cdots + x_n 2^{-n} \\[4pt] 2 \times 0.625 &= 2 \times \left( x_1 2^{-1} + x_2 2^{-2} + x_3 2^{-3} + \cdots + x_n 2^{-n} \right) \\[4pt] 1.250 &= x_1 + x_2 2^{-1} + x_3 2^{-2} + \cdots + x_n 2^{-(n-1)} \\[4pt] 1.250 &= 1 + x_2 2^{-1} + x_3 2^{-2} + \cdots + x_n 2^{-(n-1)} \\[4pt] x_1 &= 1 \\[12pt] \text{둘째 자리 구하기} & \\[2pt] 0.250 &= x_2 2^{-1} + x_3 2^{-2} + \cdots + x_n 2^{-(n-1)} \\[4pt] 2 \times 0.250 &= 2 \times \left( x_2 2^{-1} + x_3 2^{-2} + \cdots + x_n 2^{-(n-1)} \right) \\[4pt] 0.500 &= x_2 + x_3 2^{-1} + \cdots + x_n 2^{-(n-2)} \\[4pt] 0.500 &= 0 + x_3 2^{-1} + \cdots + x_n 2^{-(n-2)} \\[4pt] x_2 &= 0 \\[12pt] \text{셋째 자리 구하기} & \\[2pt] 0.500 &= x_3 2^{-1} + \cdots + x_n 2^{-(n-2)} \\[4pt] 2 \times 0.500 &= 2 \times \left( x_3 2^{-1} + \cdots + x_n 2^{-(n-2)} \right) \\[4pt] 1.000 &= x_3 + x_4 2^{-1} + \cdots + x_n 2^{-(n-3)} \\[4pt] 1.000 &= 1 + x_4 2^{-1} + \cdots + x_n 2^{-(n-3)} \\[4pt] x_3 &= 1 \\[12pt] \therefore\quad 0.625_{10} &= 0.101_2 \end{aligned}

등호 왼쪽의 0.625는 10진수로 적은 값이고, 오른쪽은 그 값을 2진수 자릿값의 합으로 나타낸 식이다.
0.625의 2진수 표현을 아직 모르므로, 0.x1x2x320.x_1x_2x_3\cdots_2처럼 각 자리를 미지수로 둔다.
이 수에 2를 곱하면 2진수의 각 자리가 왼쪽으로 한 자리씩 이동하여, 첫 번째 소수 자리 x1x_1이 일의 자리가 된다.
이는 10진수 0.123에 10을 곱해 1.23을 만들면, 소수점 아래 첫째 자리의 1이 정수 부분의 일의 자리로 옮겨가는 것과 같은 원리이다.

둘째 자리 구하기에서 앞 단계에서 남은 소수 부분 0.250에 2를 곱해 x2x_2를 구한다.
세 번째 단계도 같은 방식으로 0.500에 2를 곱해 x3x_3를 구한다.
이제 남은 소수 부분이 모두 0이므로 계산을 마친다.

매 단계마다 이 전개식을 쓰지 않고 쉽게 계산하는 방법이 있다.

0.3125×2=0.62500.625×2=1.2510.25×2=0.500.5×2=1.010.312510=0.01012\begin{aligned} 0.3125 \times 2 &= 0.625 &&\Rightarrow 0 \\ 0.625 \times 2 &= 1.25 &&\Rightarrow 1 \\ 0.25 \times 2 &= 0.5 &&\Rightarrow 0 \\ 0.5 \times 2 &= 1.0 &&\Rightarrow 1 \\ \therefore\quad 0.3125_{10} &= 0.0101_2 \end{aligned}

10진수에 2를 곱하고, 결과의 정수 부분을 순서대로 기록한다.
각 단계에서는 이전 단계 결과의 소수 부분만으로 계산을 진행하며, 소수 부분이 0이 될 때까지 이를 반복한다.

2진수로 정확히 표현할 수 없는 실수

앞에서는 10진수 소수를 2진수 소수로 변환하는 방법을 살펴보았다.
그런데 모든 10진수 소수가 2진수에서 유한소수로 끝나는 것은 아니다.
그 이유를 이해하기 위해, 먼저 10진수에서 유한소수가 되는 조건부터 살펴보자.

10진수에서 어떤 수를 n10k\frac{n}{10^k} 꼴로 표현할 수 있다면, 유한소수가 된다.
즉 기약분수의 분모의 소인수가 2255뿐이면 유한소수다.

625103=6251000=58=523=0.625\frac{625}{10^3} = \frac{625}{1000} = \frac{5}{8} = \frac{5}{2^3} = 0.625

10진수로 표현한 어떤 수를 n2k\frac{n}{2^k} 꼴로 나타낼 수 있다면, 그 수는 2진수에서 유한소수가 된다.

0.31250.3125를 기약분수로 나타내면 다음과 같다.

0.3125=312510000=516=5240.3125 = \frac{3125}{10000} = \frac{5}{16} = \frac{5}{2^4}

분모가 242^4이므로 0.31250.3125는 2진수에서 유한소수가 된다.

0.01012=1×22+1×24=14+116=5160.0101_2 = 1 \times 2^{-2} + 1 \times 2^{-4} = \frac{1}{4} + \frac{1}{16} = \frac{5}{16}

따라서 10진수 0.31250.3125는 2진수로 변환하면 유한소수 0.010120.0101_2이 된다.

반면 0.110=110=12×50.1_{10} = \frac{1}{10} = \frac{1}{2 \times 5}의 기약분수 분모에는 55가 남는다.
분모가 22의 거듭제곱이 아니므로 0.1100.1_{10}은 유한한 2진수 소수로 표현할 수 없다.
2를 계속 곱해 변환해 보면 소수 부분이 0.20.40.80.60.2 \rightarrow 0.4 \rightarrow 0.8 \rightarrow 0.6을 반복한다.

0.1×2=0.200.2×2=0.400.4×2=0.800.8×2=1.610.6×2=1.210.2×2=0.400.4×2=0.800.8×2=1.610.6×2=1.210.2×2=0.40\begin{aligned} 0.1 \times 2 &= 0.2 &&\Rightarrow 0 \\ 0.2 \times 2 &= 0.4 &&\Rightarrow 0 \\ 0.4 \times 2 &= 0.8 &&\Rightarrow 0 \\ 0.8 \times 2 &= 1.6 &&\Rightarrow 1 \\ 0.6 \times 2 &= 1.2 &&\Rightarrow 1 \\ 0.2 \times 2 &= 0.4 &&\Rightarrow 0 \\ 0.4 \times 2 &= 0.8 &&\Rightarrow 0 \\ 0.8 \times 2 &= 1.6 &&\Rightarrow 1 \\ 0.6 \times 2 &= 1.2 &&\Rightarrow 1 \\ 0.2 \times 2 &= 0.4 &&\Rightarrow 0 \end{aligned} 0.110=0.00011001100112=0.000112\therefore\quad 0.1_{10} = 0.0001100110011\cdots_2 = 0.0\overline{0011}_2

10진수 값을 2진수로 변환했을 때, 그 값을 유한한 비트 수로 정확히 표현할 수 있든 없든 변환 결과의 비트열이 실제 메모리에 그대로 저장되는 것은 아니다.
컴퓨터는 2진수로 표현된 값을 일정한 규칙에 따라 부호, 지수, 가수로 나누어 비트에 저장한다.
이러한 부동소수점 저장 방식을 표준화한 대표적인 규격이 IEEE 754이다.