* 바쁘신 분들을 위한 빠른 해결법
import sys
sys.set_int_max_str_digits(7000) ## 7000보다 더 높은 숫자 입력도 가능
Python의 int는 overflow되지 않는다?
Python의 int는 보통의 상식선인 4bytes 크기가 아닌 28bytes나 소모하고 있습니다. 메모리 공간을 많이 차지하는 대신에 overflow에 걱정이 없다는 사실 알고 계셨나요??
* 자세한 글은 https://tyoon9781.tistory.com/entry/python-int-size-28bytes를 참조해 주세요
python의 int는 C/C++의 int와는 비교가 안될 정도로 큰 수를 다룰 수 있습니다. 그렇지만 혹시 의도적이지 않게 큰 숫자를 만들어 버리고 출력하면 시스템에 무리가 갈 가능성이 있습니다. 그래서 Console내 표현 가능한 숫자의 제한을 4300자로 제한하고 있습니다.
Console에서 숫자를 표현한다는 것은?
숫자를 표현한다는 것은 Computer에 있는 2진법(binary)를 10진법(decimal)으로 표현한다는 것입니다. 그리고 그 10진법으로 표현된 데이터는 컴퓨터가 실제로 관리하는 binary data가 아닌 string data입니다.
그리고 python은 기본적으로 이 string의 길이를 4300자로 제한하고 있습니다. 아래 코드예제를 통해 제한 길이를 확인해봅시다
>>> a = int('9'*4300) ## 9가 4300개 있는 숫자이다 정확히는 10^4301 - 1
>>> a ## a를 출력해도 문제 없다.
99999999999999999999999999 ... 999
>>> a += 1 ## a를 증가시켰다. 동작에 문제는 없다.
>>> a ## 하지만 출력에 문제가 된다.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Exceeds the limit (4300) for integer string conversion;
use sys.set_int_max_str_digits() to increase the limit
만약에 4300자 이상의 출력을 원하신다면 sys.set_int_max_str_digits() 함수를 사용해서 제한을 풀면 됩니다. 넉넉하게 2배 좀 안되는 7000으로 잡거나, 개발자 본인이 원하는 limit값을 새로 설정합시다.
>>> import sys ## sys library를 불러온다
>>> sys.set_int_max_str_digits(7000) ## 길이제한을 7000으로 올린다.
>>> a ## 문제없이 출력된다.
100000000000000...000
CPython에서 4300길이를 설정하는 부분은 Include/internal/pycore_long.h에 있습니다.
#ifndef Py_INTERNAL_LONG_H
#define Py_INTERNAL_LONG_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef Py_BUILD_CORE
# error "this header requires Py_BUILD_CORE define"
#endif
#include "pycore_global_objects.h" // _PY_NSMALLNEGINTS
#include "pycore_runtime.h" // _PyRuntime
/*
* Default int base conversion size limitation: Denial of Service prevention.
*
* Chosen such that this isn't wildly slow on modern hardware and so that
* everyone's existing deployed numpy test suite passes before
* https://github.com/numpy/numpy/issues/22098 is widely available.
*
* $ python -m timeit -s 's = "1"*4300' 'int(s)'
* 2000 loops, best of 5: 125 usec per loop
* $ python -m timeit -s 's = "1"*4300; v = int(s)' 'str(v)'
* 1000 loops, best of 5: 311 usec per loop
* (zen2 cloud VM)
*
* 4300 decimal digits fits a ~14284 bit number.
*/
#define _PY_LONG_DEFAULT_MAX_STR_DIGITS 4300
맨 밑의 4300이란 숫자가 매크로 형태로 선언된 것을 확인할 수 있습니다.
*reference
https://docs.python.org/ko/3/library/stdtypes.html#int-max-str-digits
'Python > Error Handling' 카테고리의 다른 글
TypeError: method() takes no keyword arguments (0) | 2023.03.26 |
---|