PEP 242 – 숫자 종류(Numeric Kinds)
- Author:
- Paul F. Dubois <paul at pfdubois.com>
- Status:
- Withdrawn
- Type:
- Standards Track
- Created:
- 17-Mar-2001
- Python-Version:
- 2.2
- Post-History:
- 17-Apr-2001
Table of Contents
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
초록
이 제안은 사용자에게 수치 계산의 정밀도와 범위에 대한 선택적 제어권을 부여하여, 계산을 한 번 작성하면 어디서든 최소한 원하는 정밀도와 범위로 실행될 수 있도록 합니다. 이는 기존 코드와 하위 호환성을 가집니다. 십진 리터럴의 의미가 명확해집니다.
근거
현재 Fortran 90을 제외한 모든 언어에서는 부동소수점을 사용하면서 플랫폼과 무관하게 대략 동일한 답을 얻는(또는 그것이 불가능할 경우 컴파일을 거부하는) 이식 가능한 방식으로 프로그램을 작성하는 것이 불가능합니다. Python은 현재 부동소수점 타입을 하나만 가지고 있으며, 이는 C 구현에서 C의 double과 동일합니다.
“single float”나 “quad float”에 해당하는 타입은 존재하지 않습니다. 그러한 타입을 직접 도입하려 하면 언어가 복잡해지고, 이후 그 사용은 이식성이 없게 됩니다. 이 제안은 Fortran 90의 “kind” 해법을 Python 환경에 맞게 적용한 것과 유사합니다. 이 기능을 사용하면 한 줄만 변경하여 전체 계산을 하나의 정밀도 수준에서 다른 수준으로 전환할 수 있습니다. 특정 머신에서 원하는 정밀도가 존재하지 않는 경우, 프로그램은 잘못된 답을 얻는 대신 실패합니다. 이런 방식으로 코딩하면 실패할 루틴을 초반에 호출하게 되므로, 이는 컴파일되지 않는 것 다음으로 차선책입니다.
지원되는 정수 및 부동소수점 종류(Kind)
복소수는 Python이 이 기능 없이도 빌드될 수 있으므로 아래에서 별도로 다룹니다.
각 Python 컴파일러는 원하는 만큼 많은 정수 및 부동소수점 수의 “종류(kind)”를 정의할 수 있지만, 기존의 int와 long에 해당하는 최소 두 가지 정수 종류를 지원해야 하고, 현재의 float와 동등한 부동소수점 수 종류를 최소 한 가지 지원해야 합니다.
이러한 필수 종류의 범위와 정밀도는 현재와 마찬가지로 프로세서에 의존적이지만, 임의의 정수를 담을 수 있는 “long integer” 종류는 예외입니다.
내장 함수 int(), long(), float()는 현재와 마찬가지로 입력을 이러한 기본 종류로 변환합니다. (유니코드 문자열은 사실상 다른 “종류”의 문자열이며, 충분히 지식이 있는 사람이라면 이 경우를 포함하도록 이 PEP를 확장할 수 있을 것이라는 점에 유의하십시오.)
각 타입(정수, 부동소수점) 내에서 컴파일러는 선형으로 정렬된 종류 집합을 지원하며, 그 순서는 더 넓은 범위 및/또는 더 높은 정밀도의 수를 담을 수 있는 능력에 따라 결정됩니다.
종류(Kind) 객체
“kinds”라는 이름의 모듈에 두 개의 새로운 표준 함수가 정의됩니다. 이들은 종류 객체(kind object)라고 불리는 호출 가능 객체를 반환합니다. 각 정수 또는 부동소수점 종류 객체 f는 result = f(x) 시그니처를 가지며, 각 복소수 종류 객체는 result = f(x, y=0.) 시그니처를 가집니다.
int_kind(n)- 정수 인자
n >= 1에 대해, 열린 구간 (-10**n,10**n) 안의 정수를 담을 정수 종류인 결과를 반환하는 호출 가능 객체를 반환합니다. 이 종류 객체는 long형을 포함하여 정수인 인자를 받아들입니다.n == 0이면, Python 리터럴 0에 해당하는 종류 객체를 반환합니다. float_kind(nd, n)nd >= 0이고n >= 1인 경우, 적어도 nd자리의 정밀도와 닫힌 구간[-n, n]안의 밑이 10인 지수를 갖는 부동소수점 수를 담을 부동소수점 종류인 결과를 반환하는 호출 가능 객체를 반환합니다. 이 종류 객체는 정수 또는 부동소수점수인 인자를 받아들입니다.nd와 n이 모두 0이면, Python 리터럴 0.0에 해당하는 종류 객체를 반환합니다.
컴파일러는 원하는 속성을 갖는, 해당 타입에 사용 가능한 종류 집합 중 가장 작은 종류에 해당하는 종류 객체를 반환합니다. 주어진 구현에 원하는 특성을 가진 종류가 존재하지 않으면 OverflowError 예외가 발생합니다. 종류 함수는 인자를 대상 종류로 변환하지만, 결과가 대상 종류의 범위에 들어맞지 않으면 OverflowError 예외가 발생합니다.
호출 가능 객체로서의 동작 외에도, kind 객체는 해당 kind의 특성을 나타내는 속성을 가지고 있습니다.
name은 종류의 이름입니다. 표준 종류는 int, long, double이라고 불립니다.typecode는 이 종류의 배열을 만들기 위해Numeric이나array모듈과 함께 사용하기에 적합한 한 글자 문자열입니다. 표준 타입들의 typecode는 각각 ‘i’, ‘O’, ‘d’입니다.- 정수 종류에는 다음과 같은 추가 속성이 있습니다:
MAX는 이 종류에서 허용되는 최대 정수와 같으며, long 종류의 경우None입니다.MIN은 이 종류에서 허용되는 가장 작은(음의 방향으로 가장 큰) 정수와 같으며, long 종류의 경우None입니다. - 부동소수점 종류에는 표준 헤더 파일 “float.h”의 해당 C 타입 값과 속성이 동일한 다음과 같은 추가 속성이 있습니다.
MAX,MIN,DIG,MANT_DIG,EPSILON,MAX_EXP,MAX_10_EXP,MIN_EXP,MIN_10_EXP,RADIX,ROUNDS(float.h의FLT_RADIX,FLT_ROUNDS와 동일). 이 값들은 정수 타입이며, 다만MAX,MIN,EPSILON은 해당 종류에 대응하는 파이썬 부동소수점 타입입니다.
kinds 모듈의 속성
int_kinds는 사용 가능한 정수 종류들의 목록이며, 가장 낮은 종류부터 가장 높은 종류 순으로 정렬되어 있습니다. 정의상, int_kinds[-1]은 long 종류입니다.
float_kinds는 사용 가능한 부동소수점 종류들의 목록이며, 가장 낮은 종류부터 가장 높은 종류 순으로 정렬되어 있습니다.
default_int_kind는 파이썬 리터럴 0에 대응하는 종류 객체입니다.
default_long_kind는 파이썬 리터럴 0L에 대응하는 종류 객체입니다.
default_float_kind는 파이썬 리터럴 0.0에 대응하는 종류 객체입니다.
복소수
지원되는 경우, 복소수는 동일한 종류의 부동소수점 수인 실수부와 허수부를 가집니다. 파이썬 컴파일러가 복소수를 조금이라도 지원한다면, 자신이 지원하는 각 부동소수점 종류에 대응하는 복소수 아날로그를 지원해야 합니다.
복소수가 지원되는 경우, kinds 모듈에서 다음을 사용할 수 있습니다:
complex_kind(nd, n)- 결과가 복소수 종류(complex kind)인 호출 가능 객체를 반환하며, 이 복소수 종류는 각 성분(.real, .imag)이
float_kind(nd, n)종류인 복소수를 담습니다. 이 종류 객체는 정수, 실수, 복소수 종류 중 하나인 인자 하나를 받거나, 각각 정수 또는 실수인 인자 두 개를 받습니다.
complex_kinds는 사용 가능한 복소수 종류들의 목록이며, 낮은 종류에서 높은 종류 순으로 정렬되어 있습니다.
default_complex_kind는 파이썬 리터럴 0.0j에 해당하는 종류 객체입니다. 이 종류의 이름은 doublecomplex이며, 타입코드는 ‘D’입니다.
복소수 종류 객체는 다음과 같은 추가 속성을 가집니다:
floatkind는 해당 실수 타입의 종류 객체입니다.
예제
myprecision.py 모듈에서:
import kinds
tinyint = kinds.int_kind(1)
single = kinds.float_kind(6, 90)
double = kinds.float_kind(15, 300)
csingle = kinds.complex_kind(6, 90)
나머지 코드에서:
from myprecision import tinyint, single, double, csingle
n = tinyint(3)
x = double(1.e20)
z = 1.2
# builtin float gets you the default float kind, properties unknown
w = x * float(x)
# but in the following case we know w has kind "double".
w = x * double(z)
u = csingle(x + z * 1.0j)
u2 = csingle(x+z, 1.0)
myprecision.py의 인자를 변경하는 것만으로 전체 코드를 더 높은 정밀도로 바꿀 수 있다는 점에 주목하십시오.
주석: single != double이 보장되는 것은 아니지만, double(1.e20)이 15자리 십진수 정밀도와 10**300까지의 범위를 가진 숫자를 담거나, 그렇지 않으면 float_kind 호출이 실패한다는 것은 보장됩니다.
미해결 문제
현재까지 제기된 미해결 문제는 없습니다.
Copyright
This document has been placed in the public domain.