숫자

숫자 (Numbers)

Racket의 숫자 체계는 복소수·실수·유리수·정수라는 계층과 정확(exact)/부정확(inexact)이라는 또 다른 축이 교차하는 구조예요. 이 절은 그 숫자 체계 전반과 각종 숫자 연산 기능을 개관합니다.

출처: Racket Reference - Numbers

본문

모든 *숫자(number)*는 *복소수(complex number)*예요. 그중 일부는 *실수(real number)*이고, 표현 가능한 실수는 모두 *유리수(rational number)*이기도 합니다. 다만 +inf.0(양의 무한대), +inf.f(read-single-flonum으로 활성화된 단정밀도 변형), -inf.0(음의 무한대), -inf.f(활성화된 단정밀도 변형), +nan.0(not-a-number), +nan.f(활성화된 단정밀도 변형)는 예외예요. 유리수 가운데 일부는 *정수(integer)*인데, 그 숫자에 round를 적용하면 같은 숫자가 나오기 때문입니다.

이 범주들과 직교하게, 각 숫자는 *정확한 숫자(exact number)*이거나 *부정확한 숫자(inexact number)*이기도 해요. 달리 명시하지 않으면, 부정확한 숫자가 포함된 계산은 부정확한 결과를 만들어 냅니다. 다만 부정확한 숫자에 대한 어떤 연산은 정확한 숫자를 만들어 내기도 하는데, 예를 들어 부정확한 숫자에 정확한 0을 곱하는 경우가 있어요. 어떤 유리수 인자에 대해 수학적으로 무리수를 만들어 내는 연산(예: sqrt)은 정확한 인자에 대해서도 부정확한 결과를 만들어 낼 수 있습니다.

복소수의 경우, 실수부와 허수부가 둘 다 같은 정밀도의 정확한 숫자이거나 같은 정밀도의 부정확한 숫자이거나, 아니면 정확한 0 실수부와 부정확한 허수부를 갖습니다. 정확한 0 허수부를 가진 복소수는 실수예요.

부정확한 실수는 배정밀도 IEEE 부동소수점 숫자(일명 flonum) 또는 단정밀도 IEEE 부동소수점 숫자(일명 single-flonum)로 구현됩니다. Single-flonum은 (single-flonum-available?)#t라고 보고할 때만 지원돼요. +inf.f, -inf.f, +nan.f라고 써서 single-flonum을 뜻하지만, read-single-flonum이 기본적으로 #f이므로 그 형태들은 기본적으로 배정밀도 flonum으로 읽힙니다. Single-flonum이 지원될 때도 부정확한 숫자는 기본적으로 여전히 flonum으로 표현되며, 단정밀도는 계산이 single-flonum으로 시작할 때만 사용됩니다.

부정확한 숫자는 정확한 형태로 강제 변환(coerce)될 수 있어요. 다만 +inf.0, +inf.f, -inf.0, -inf.f, +nan.0, +nan.f는 정확한 형태가 없어서 예외입니다. 숫자를 정확한 0으로 나누면 예외가 발생해요. +nan.0이나 +nan.f가 아닌 0이 아닌 숫자를 부정확한 0으로 나누면 피제수의 부호와 정밀도에 따라 +inf.0, +inf.f, -inf.0, -inf.f가 반환됩니다. +nan.0 값은 자기 자신과 = 하지 않지만, +nan.0은 자기 자신과 eqv? 합니다. +nan.f도 마찬가지로 eqv? 하지만 = 하지 않아요. 반대로 (= 0.0 -0.0)#t인데 (eqv? 0.0 -0.0)#f이고, 0.0f0-0.0f0(단정밀도 변형)도 마찬가지입니다. 데이터 -nan.0+nan.0과 같은 상수를 가리키고, -nan.f+nan.f와 같습니다.

무한대를 포함한 계산은 IEEE가 결과를 지정한 곳에서는 IEEE 배정밀도 또는 단정밀도 부동소수점과 일치하는 결과를 만들어 내요. IEEE가 명세를 주지 않는 경우에는 무한대로 접근하는 극한(limit)에 해당하는 결과를 내거나, 그런 극한이 없으면 +nan.0 또는 +nan.f를 만들어 냅니다.

정확한 숫자의 정밀도와 크기는 가용 메모리(그리고 무리수를 만들어 낼 수 있는 연산의 정밀도)에 의해서만 제한돼요. 특히 정확한 숫자의 덧셈·곱셈·뺄셈·나눗셈은 항상 정확한 결과를 만들어 냅니다.

fixnum은 2의 보수 표현이 32비트 플랫폼에서는 30 또는 31비트(Racket 변형에 따라), 64비트 플랫폼에서는 61 또는 63비트(Racket 변형에 따라)에 들어맞는 정확한 정수예요. fixnum으로 계산할 때는 할당이 필요 없습니다. 아래의 racket/fixnum 모듈도 함께 보세요.

= 하면서 같다고 판정된 두 fixnum은 eq?로도 같습니다. 그 외에는 두 숫자에 eq?를 적용한 결과가 정의되어 있지 않아요. 다만 read-syntax 모드의 기본 리더가 만들어 낸 숫자들은 인턴(intern)되어서 eqv? 하면 eq? 하기도 합니다.

두 실수는 둘 다 같은 정밀도의 부정확한 숫자이거나 둘 다 정확한 숫자이면서 = 할 때 eqv? 해요(+nan.0, +nan.f, 0.0, +0.0f0, -0.0, -0.0f0은 위에서 언급한 대로 예외). 두 복소수는 실수부와 허수부가 eqv? 할 때 eqv? 합니다. 두 숫자는 eqv? 할 때 equal? 하죠.

숫자를 read하는 방법은 Reading Numbers, print하는 방법은 Printing Numbers를 참고하세요.

이 절은 다음 하위 절들로 구성됩니다:

  • 4.3.1 숫자 타입 (Number Types)
  • 4.3.2 일반 수치 연산 (Generic Numerics)
    • 4.3.2.1 산술 (Arithmetic)
    • 4.3.2.2 숫자 비교 (Number Comparison)
    • 4.3.2.3 거듭제곱과 근 (Powers and Roots)
    • 4.3.2.4 삼각 함수 (Trigonometric Functions)
    • 4.3.2.5 복소수 (Complex Numbers)
    • 4.3.2.6 비트 연산 (Bitwise Operations)
    • 4.3.2.7 난수 (Random Numbers)
    • 4.3.2.8 기타 난수 유틸리티 (Other Randomness Utilities)
    • 4.3.2.9 숫자–문자열 변환 (Number–String Conversions)
    • 4.3.2.10 추가 상수와 함수 (Extra Constants and Functions)
  • 4.3.3 Flonum
    • 4.3.3.1 Flonum 산술 (Flonum Arithmetic)
    • 4.3.3.2 Flonum 벡터 (Flonum Vectors)
  • 4.3.4 Fixnum
    • 4.3.4.1 Fixnum 산술 (Fixnum Arithmetic)
    • 4.3.4.2 Fixnum 벡터 (Fixnum Vectors)
    • 4.3.4.3 Fixnum 범위 (Fixnum Range)
  • 4.3.5 Extflonum
    • 4.3.5.1 Extflonum 산술 (Extflonum Arithmetic)
    • 4.3.5.2 Extflonum 상수 (Extflonum Constants)
    • 4.3.5.3 Extflonum 벡터 (Extflonum Vectors)
    • 4.3.5.4 Extflonum 바이트 문자열 (Extflonum Byte Strings)

더 알아보기