컴퓨터가 수를 다루는 방식은 우리가 숫자를 사용하는 방식과 꽤 다릅니다. 사람은 열 손가락 덕분에 10진수에 익숙하죠. 하지만 컴퓨터는 전기가 흐르는지 아닌지 두 가지 상태만 봅니다. 그래서 모든 수를 이진수(binary)로 표현합니다. 0과 1만으로 이루어진 세상인 셈입니다.

이진수와 16진수의 관계

이진수는 컴퓨터에게 알맞은 방식이지만 사람이 읽기에는 너무 깁니다. 그래서 프로그래머는 이를 16진수(hexadecimal)로 바꿔서 자주 사용합니다. 이진수 네 자리를 묶으면 16진수 한 자리가 되거든요. 이렇게 하면 메모리 상태를 확인하거나 오류를 찾을 때 훨씬 직관적입니다.

예를 들어 0xFF라는 표기를 보면 8비트가 꽉 차 있다는 걸 바로 알 수 있습니다. 복잡한 0과 1의 나열보다 훨씬 눈에 잘 들어오죠. 처음에는 낯설 수 있지만 익숙해지면 정말 편리한 도구가 됩니다.

컴퓨터가 수를 다루는 비밀과 원리

정수를 표현하는 두 가지 방법

컴퓨터 안에 저장된 정수는 크게 두 가지로 나뉩니다. 부호가 없는 정수와 있는 정수입니다. 부호 없는 정수(unsigned integer)는 말 그대로 양수만 다룹니다. 음수를 고려할 필요가 없어서 모든 비트를 숫자 크기를 나타내는 데 씁니다.

반면 부호 있는 정수(signed integer)는 음수까지 표현해야 합니다. 이때 컴퓨터는 보통 2의 보수(two’s complement)라는 방식을 씁니다. 가장 앞쪽에 있는 비트인 최상위 비트(MSB)를 부호로 사용하는 방식입니다. 이 비트가 1이면 음수로 해석하게 됩니다.

2의 보수 방식은 0이 오직 하나만 존재합니다. 그리고 덧셈과 뺄셈을 같은 회로로 처리할 수 있습니다. 별도의 복잡한 규칙이 필요 없어서 하드웨어 설계가 훨씬 수월해집니다. 연산 속도도 빨라지니 컴퓨터 입장에서 아주 효율적인 선택입니다.

소수점을 고정해서 계산하기

정수만으로는 우리가 사는 세상을 모두 담아내기 어렵습니다. 소수점도 표현해야 하죠. 이때 사용하는 방법 중 하나가 고정소수점(fixed-point)입니다. 전체 비트 중에서 어디까지가 정수이고 어디부터 소수인지 미리 정해두는 방식입니다. 약속된 규칙대로 숫자를 읽기만 하면 됩니다.

예를 들어 32비트를 반으로 나눠 앞은 정수, 뒤는 소수로 쓰기로 했다고 칩시다. 그러면 표현 범위와 정밀도가 딱 정해집니다. 이 방식은 계산이 무척 빠르고 구현이 쉽다는 장점이 있습니다. 그래서 빠른 연산이 필요한 특정 상황에서 자주 쓰입니다. 하지만 유연성이 부족하다는 점은 기억해야 합니다.

유연하게 숫자를 다루는 부동소수점

더 넓은 범위의 수를 다루고 싶다면 부동소수점(floating-point) 방식이 필요합니다. 숫자를 고정된 틀에 가두지 않고 유동적으로 조절하는 방법입니다. 과학 시간에 배운 표기법을 떠올려 보면 이해가 쉽습니다. 의미 있는 숫자에 10의 몇 승을 곱하는 식입니다.

컴퓨터는 이를 위해 가수(mantissa)와 지수(exponent)라는 개념을 사용합니다. 대표적인 표준인 IEEE-754를 보면 32비트를 아주 알뜰하게 나눠 씁니다. 부호, 지수, 가수로 나누어 아주 큰 수나 아주 작은 수를 표현합니다. 덕분에 고정소수점보다 훨씬 다양한 값을 다룰 수 있게 됩니다.

정밀도와 속도 사이의 선택

부동소수점에도 한계는 있습니다. 값이 작을 때는 촘촘하게 표현되지만 값이 커지면 간격이 벌어집니다. 아주 큰 수에서는 미세한 차이를 무시해 버리기도 합니다. 가끔 0에 아주 가까운 수를 표현하기 위해 서브노멀(subnormal)이라는 특별한 형태를 쓰기도 합니다. 이는 0과 가장 작은 수 사이를 메워 주는 역할을 합니다.

컴퓨터가 숫자를 다루는 건 정수와 소수 구분의 문제 그 이상입니다. 속도와 범위, 그리고 정밀도 사이에서 줄타기를 하는 과정입니다. 어떤 방식을 쓰느냐에 따라 계산 결과가 미묘하게 달라질 수 있습니다. 프로그래머는 이 차이를 알고 상황에 맞는 최선의 방법을 골라야 합니다.

제목 영역
이미지