메아리 저널

나루의 자료형 (2)

이전 글에서 이어진다.

정수

이전 글에서 얘기하려다가 까먹은 것으로 정수의 구현이 있다. 정수 리터럴은 어떻게 만들었다 쳐도 실제로 이를 표현하는 것 또한 만만치 않은 일일 것이다.

나루는 임의 자리수의 정수를 지원하며, 몇몇 언어들과는 다르게 프로세서가 지원하는 워드 기반 정수와 그보다 더 큰 정수 사이에 아무 차이도 없다. 숫자를 연산하다가 범위를 벗어 나면 자동으로 변환되고, 다시 원래대로 쓸만한 크기로 돌아 오면 워드로 다시 변환할 수 있을 것이다. (사실 후자의 경우 메모리 할당으로 인한 성능 저하 때문에 사용하지 않을 수도 있는데, 일단 그렇다고 치자. 여기에 대한 얘기는 메모리 관리를 얘기할 때 더 자세히 말해 보려 한다.)

이런 식으로 정수를 구현한다고 하면 두 가지 방법을 고려할 수 있다.

  • JVM처럼 완벽하게 형 관련 정보를 넣어서 정수를 처리한다.
  • 루비처럼 포인터의 최하위 비트를 1로 설정하여 작은 정수를 구분한다. 원래 워드가 나타낼 수 있는 범위의 반만큼만 표현할 수 있다는 단점이 있다.

아직 둘 중 어느 걸 어느 환경에 써야 할 지는 결정하지 않았다. 다만 외부에 나타내야 할 때는 루비와 같은 접근 방법을 취할 수 밖에 없다는 생각이 든다.

워드를 고려하기 시작하면 또 한 가지 특이한 문제점에 다다르게 된다. 혹시 마법(?)의 숫자 -2147483648 때문에 고생하신 분은 없으신지. 2의 보수로 음수를 표기하는 거의 모든 현대적인 프로세서들은 이 숫자를 프로그래머 입장에서는 별로 도움이 안 되는 방법으로 처리해 버리는 경향이 있다. (예를 들어서 저 숫자는 원래 숫자와 그에 -1을 곱한 숫자가 둘 다 음수인 유일한 숫자이다. 물론 실제로는 아니지만.) 저 숫자를 NaN과 같은 특수한 의미로 쓸 수 없을까 고민해 보고 있다.

유리수

유리수(정확히 말하면 분수)는 현대 프로그래밍 언어에서 특히 많이 소외받고 있는 감이 있다. 딱히 특수한 용도로 많이 쓰이지도 않는 것 같고 정수랑 실수 사이에 끼어 있어서 포트란 같은 일부 언어를 제외하곤 구경조차 하기 힘들다. 그럼에도 불구하고 나루에서 유리수 자료형을 따로 지원하려는 이유는 이렇다.

  • 있어서 나쁠 게 딱히 없다. (물론 이것만으로는 근거로 충분하지 않다만)
  • 프로그래밍을 처음 배우는 사람에게는 이러한 '고급' 자료형이 도움이 될 수도 있다. 파이썬에서 맨날 나오는 질문이 왜 0.3 + 0.3은 0.6이 아닌가요 같은 건지 생각해 보면 이해가 갈 것이다.
  • 수학적이나 과학적인 용도로 프로그래밍 언어를 사용할 경우에는 정확한 유리수 값을 나타내는 것이 도움이 될 때가 종종 있다. 포트란 등에 분수가 들어 간 것도 비슷한 이유로 알고 있다. (아니라면 알려 주시라.)
  • C/C++ 등의 정수 나눗셈은 매우 묵시적이라서 종종 프로그래머를 헷갈리게 한다. 유리수 자료형의 도입으로 묵시적인 정수 나눗셈을 유리수를 반환하는 진짜 나눗셈으로 안전하게 바꿀 수 있다.
  • 뒤에서 살펴 볼 임의 자리 실수를 위한 자료형이 있는데도 또 다른 자료형을 만드는 이유는 사용 용도도 다를 뿐만 아니라 유리수는 분자와 분모를 임의 자리의 정수로 지정할 수 있기 때문이다. 임의 자리 실수형은 계산 전에 그 정확도를 미리 지정해 줘야 한다.

나루에서 분수는 3r4 형태로 쓴다. 중간의 r은 정수 리터럴과 같은 이유로 항상 소문자여야 한다. 유니코드를 생각한다면 U+2044 FRACTION SLASH 문자를 대신 쓸 수도 있고 다른 이상야릇한 문자도 지원할 수 있겠지만 일단 지금은 ASCII에만 관심을 가지기로 하자.

r 앞뒤에 나오는 숫자는 어떠한 정수 리터럴이라도 될 수 있다. 0o3177r0xBEEF나, 1r36'BLAH' 같은 것도 허용된다. 하지만 여기서 볼 수 있듯이 지나치게 복잡해질 우려가 있으므로, r 대신에 _r_을 써서 구별하게 할 수 있다. (예를 들어 0b1101101_r_36'BLAH')

분수는 자동으로 통분 및 약분되며, 출력될 때는 분자와 분모가 서로 소가 되도록 약분한다. 유리수는 나루의 숫자형 체계에서 정확히 정수와 실수 사이에 있으며, 실수와 함께 연산되면 실수가 되고, 정수와 함께 연산하면 유리수로 변환된다.

전체 글 목록은 다음과 같다.

(2010-04-03)

이 글은 본래 http://mearie.org/journal/2007/08/datatype-in-naru-part-2에 썼던 것을 옮겨 온 것입니다.


(rev 1d46270eb038)