PEP 791 – math.integer — 정수 전용 수학 함수 서브모듈
- Author:
- Neil Girdhar <misterhsheik at gmail.com>, Sergey B Kirpichev <skirpichev at gmail.com>, Tim Peters <tim.peters at gmail.com>, Serhiy Storchaka <storchaka at gmail.com>
- Sponsor:
- Victor Stinner <vstinner at python.org>
- Discussions-To:
- Discourse thread
- Status:
- Final
- Type:
- Standards Track
- Created:
- 12-May-2025
- Python-Version:
- 3.15
- Post-History:
- 12-Jul-2018, 09-May-2025, 19-May-2025
- Resolution:
- 23-Oct-2025
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain or CC0-1.0, whichever is more permissive 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
초록
이 PEP는 math.gcd() 또는 math.isqrt()와 같이 정수 인자에 대해 정의된 수론적, 조합론적 및 기타 함수를 위한 새로운 서브모듈을 제안합니다.
동기
관련 math 문서에는 다음과 같이 쓰여 있습니다. “이 모듈은 C 표준에서 정의한 수학 함수에 접근할 수 있게 합니다.” 그러나 시간이 지나면서 이 모듈에는 C 표준이나 부동 소수점 산술과 관련이 없는 함수들이 추가되었습니다. 이제 모듈의 범위, 내용 및 인터페이스(반환값 또는 허용되는 인자)를 설명하기가 훨씬 더 어려워졌습니다.
예를 들어 문서의 다음 문장은 다음과 같습니다. “명시적으로 달리 언급하지 않는 한 모든 반환값은 부동 소수점 수입니다.” 이는 더 이상 사실이 아닙니다. 문서의 Number-theoretic functions 하위 섹션에 나열된 함수 중 None도 부동 소수점 수를 반환하지 않지만, 문서에는 이에 대한 설명이 없습니다. 제안된 math.integer 서브모듈의 문서에서는 “모든 반환값은 정수입니다”라는 문장이 정확할 것입니다. 이와 유사하게 새로운 서브모듈과 math모두에 있는 함수가 허용하는 인자에 대한 설명도 단순화할 수 있습니다.
이제 모듈의 내용에 대한 사람들의 기대를 충족하기가 훨씬 더 어려워졌습니다. 예를 들어 math.factorial(100)이 정확한 답을 반환할 것이라고 기대해야 할까요? 많은 언어, Python 패키지(예: scipy) 또는 휴대용 계산기에는 동일하거나 유사한 이름의 함수가 있으며, 이 예에서는 근삿값에 불과한 부동 소수점 값을 반환합니다.
분명히 math 모듈은 수학 함수의 모든 것을 담는 장소로 사용할 수 없습니다. 이미 cmath 및 statistics 모듈도 있기 때문입니다. 정수와 관련된 함수에도 같은 방식을 적용합시다. 이렇게 하면 공통 컨텍스트가 제공되어 문서의 장황함과 개념적 부담이 줄어듭니다. 또한 관련 함수를 그룹화하여 검색 가능성을 높이고 IDE(예: 새로운 CPython의 REPL) 제안도 더욱 유용하게 만듭니다.
현재 CPython의 math 모듈 코드는 약 4200LOC이며, 이 중 새로운 모듈의 코드는 대략 3분의 1(1300LOC)입니다. 이는 cmath(1340LOC)와 비슷하며, math 모듈의 대부분 함수와 마찬가지로 libm의 단순한 래퍼가 아닙니다.
그리고 이러한 상황은 악화되는 경향이 있습니다. 모듈을 분할하자는 제안이 처음 제시되었을 때에는 정수와 관련된 함수가 두 개뿐이었습니다. 즉, factorial()(모듈의 다른 함수와 마찬가지로 float도 허용)과 gcd()(fractions 모듈에서 이동됨)였습니다. 그런 다음 isqrt(), comb() 및 perm()이 추가되었고, 새로운 모듈을 추가하자는 제안이 두 번째로 제시되었으므로 모든 새로운 함수는 math 네임스페이스를 어지럽히지 않고 곧바로 해당 모듈에 추가될 예정이었습니다. 이제 함수가 여섯 개이며 factorial()은 더 이상 float를 허용하지 않습니다.
초기 논의 스레드와 python/cpython#81313 이슈에서 제안된 것 중 추가할 수 있는 항목은 다음과 같습니다.
c_div()및n_div()— 양의 무한대 방향으로 반올림하는 정수 나눗셈(올림 나눗셈)과 가장 가까운 정수로 반올림하는 정수 나눗셈을 위한 함수입니다. 관련 논의 스레드를 참조하십시오. 이는 표준 라이브러리에서 여러 차례 재구현되어 있으며, 예를 들어datetime및fractions에 있습니다. 해당 스레드에서 보여 주었듯이 이를 잘못 구현하기도 쉽습니다.gcdext()— 두 변수에 대한 선형 디오판토스 방정식을 풀기 위한 함수입니다(int구현에는 실제로 확장 유클리드 알고리즘이 포함되어 있습니다).isqrt_rem()— 정수 제곱근과 나머지를 모두 반환하는 함수입니다(정수가 완전제곱이 아닌 경우에만 나머지가 0이 아닙니다).ilog()— 정수 로그입니다.math.log()에는 정수 인자에 대한 특별한 처리가 있습니다. 이는 다른 모듈 함수와 비교할 때 고유한 기능이며 지금까지 문서화되지 않았습니다. python/cpython#120950 이슈를 참조하십시오.fibonacci()— 피보나치 수열입니다.
분리된 네임스페이스는 기존 math의 모듈 함수와 발생할 수 있는 이름 충돌을 제거합니다. 예를 들어, 정수 올림 나눗셈에 사용할 수 있는 ceil_div() 또는 ceildiv()라는 이름은 ceil()과 충돌합니다. 이 함수는 float에 사용되며, sometimes 정수 나눗셈에 우연히 올바르게 작동하기도 하지만 — usually not 그렇지는 않습니다.
근거
이것이 모두 문서화에 관한 문제라면, 대신 수정하지 않는 이유는 무엇입니까? 아닙니다. 물론 모듈 서문에서 훨씬 더 모호하게(즉, 대략적으로 “the math module contains some mathematical functions”라고) 설명하고, 각 함수의 입력/출력과 동작을 정확하게 설명할 수 있습니다(예를 들어 factorial()의 출력이 기본적으로 정확한지 여부를 scipy.special.factorial처럼 설명할 수 있습니다).
그러나 가장 큰 문제는 현재 모듈이 서로 다르고 거의 상호 연관되지 않은 응용 분야를 뒤섞고 있다는 점입니다. 문서를 더 추가하면 이 문제가 부각될 뿐이며, 최종 사용자에게는 읽거나 건너뛰어야 할 텍스트가 늘어나 문제가 더 악화됩니다. 또한 함수의 검색 가능성 문제도 해결하지 못합니다. 어떤 모듈에서 함수를 찾아야 하는지, 해당 함수가 존재하는지 알려면 모듈의 모든 함수를 살펴봐야 하기 때문입니다. 탭 완성 문제도 해결하지 못합니다.
사양
이 PEP는 다음 정수 관련 함수들을 math.integer라는 새 하위 모듈로 옮길 것을 제안합니다.
해당 별칭은 math에서 soft deprecated 상태가 됩니다. 이 PEP는 하위 호환성을 깨는 변경 사항을 도입하지 않습니다.
모듈 함수는 정수와 __index__() 메서드를 구현하는 객체를 인자로 받으며, 이 메서드는 객체를 정수로 변환하는 데 사용됩니다. 적절한 함수는 충분한 시간과 메모리가 주어지면 정확하게 계산되어야 합니다.
PyPI에서 제공되는 intmath 패키지는 이전 Python 버전에 새 하위 모듈 콘텐츠를 제공합니다.
가능한 확장
Motivation 절에서 언급한 것과 같은 새 함수는 이 제안에 포함되지 않습니다.
다만 GMP와 같이 잘 지원되는 수학 라이브러리에 바인딩을 제공할 수 없다면 하위 모듈의 범위를 제한해야 한다는 점은 언급해야 합니다. 예를 들어 소수성 테스트와 인수분해는 포함하지 않습니다. 품질이 높은 구현을 만들려면 기여자에게 상당한 수학적 배경 지식이 필요하며, 이러한 기능은 전문 라이브러리에 더 적합하기 때문입니다.
제안된 함수가 이미 gmpy2에 존재하는 경우에는 표준 라이브러리에서 호환 가능한 인터페이스를 우선해야 합니다.
하위 호환성
해당 별칭은 math에서 무기한 유지되므로(사용은 권장되지 않지만), 코드가 중단되는 일은 예상되지 않습니다.
이 내용을 가르치는 방법
새 하위 모듈은 1) int와 유사한 인자를 받아 정수를 반환하고, 2) 임의 정밀도 정수 산술 분야에 속하며, 플랫폼의 부동 소수점 형식이나 동작 및/또는 플랫폼 수학 라이브러리(libm)에 의존하지 않는 함수들을 위한 장소가 됩니다.
사용자는 대부분의 기본 사용 사례를 다루는 int의 메서드(예: int.bit_length() 메서드)를 먼저 살펴보는 것이 자연스러우며, 표준 라이브러리의 전용 장소를 찾는 것보다 이 방법이 더 적절합니다.
참조 구현
거부된 아이디어
isqrt() 이름 변경
새 네임스페이스에서 math.isqrt()를 sqrt로 노출하는 방안이 cmath.sqrt()가 math.sqrt()의 복소수 버전인 것과 같은 방식으로 잠시 논의되었습니다. 그러나 isqrt은 궁극적으로 다른 함수입니다. 이는 제곱근의 바닥값입니다. 다른 서브모듈에서 동일한 이름을 부여하면 혼란을 초래할 수 있습니다.
모듈 이름
설문 조사 결과 intmath가 가장 인기 있는 후보였으며, imath가 두 번째로 많이 선택된 후보였습니다.
제안된 다른 이름으로는 SymPy의 서브모듈과 같은 ntheory, integermath, zmath, dmath 및 imaths가 있습니다.
그러나 SC는 새로운 최상위 모듈보다는 서브모듈을 선호합니다. 가장 인기 있는 math의 서브모듈 이름 후보는 integer, discrete 또는 ntheory입니다.
감사의 말
이 PEP를 후원해 주신 Victor Stinner 님께 감사드립니다. discuss.python.org에서 진행된 토론에 참여하고 피드백을 제공해 주신 모든 분께 감사드리며, 특히 Oscar Benjamin, Steve Dower 및 Paul Moore 님께 감사드립니다.
Copyright
This document is placed in the public domain or under the CC0-1.0-Universal license, whichever is more permissive.