HOWTO · Python

Python에서 Float 자르기

이 튜토리얼은 파이썬에서 float를 자르는 방법을 설명합니다.

이 페이지의 내용

Python의 float는 자릿수가 고정된 십진 문자열이 아니라 이진 부동소수점 값이므로 제자리에서 자릿수를 줄일 수 없습니다. 지정한 소수 자릿수 뒤의 숫자를 버리려면 숫자의 십진 텍스트로 Decimal를 만들고 ROUND_DOWN로 양자화하세요. 정수가 필요하면 math.trunc() 또는 int()를 사용하세요. 이 연산들은 0 방향으로 절삭합니다. round()와 숫자 서식 지정은 다르게 동작합니다.

절삭과 반올림 중 선택하기

절삭은 정한 위치 뒤의 숫자를 버리고 0 방향으로 이동합니다. 반올림은 반올림 규칙에 따라 가까운 값을 선택합니다. Python의 round(number, ndigits)는 반올림을 수행하며 절삭하지 않습니다. 예를 들어 round(3.146, 2)는 3.15로 반올림되지만, 소수점 이하 두 자리까지 절삭하면 3.14가 됩니다. Python 내장 round()는 정확히 중간에 놓인 값에 ties-to-even 규칙을 적용하므로 일반적인 십진 절삭 방법으로 사용해서는 안 됩니다.

float를 지정한 소수 자릿수까지 절삭하기

지정한 소수 자릿수를 유지하려면 Decimal를 사용하세요. 문자열 표현으로 객체를 만든 다음 ROUND_DOWN를 지정해 quantize()를 호출합니다. decimal 모듈에서 ROUND_DOWN는 0 방향으로 절삭합니다. 즉, 숫자를 0 방향으로 버리므로 음수도 더 작은 음수 쪽이 아니라 0 쪽으로 이동합니다. "3.14159"와 같은 문자열을 전달하면 의도한 십진 입력값이 보존됩니다. 반면 float에서 Decimal를 직접 만들면 해당 float의 이진 근삿값이 담깁니다.

다음 예제를 실행하세요:

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

from decimal import Decimal, ROUND_DOWN

values = ("3.14159", "-3.14159", "0", "2.1")
places = 2
quantum = Decimal("1").scaleb(-places)
for text in values:
    print(Decimal(text).quantize(quantum, rounding=ROUND_DOWN))
3.14
-3.14
0.00
2.10

처음 두 결과는 음수 입력을 포함해 양수와 음수 모두 0 방향으로 절삭되는 것을 보여 줍니다. 양자화는 요청한 소수 자릿수도 유지하므로 0은 0.00이 되고 2.1은 2.10이 됩니다. 이미 float가 있고 입력값으로 가장 짧게 표시되는 십진 표현을 사용하려면 Decimal(str(value))를 사용하세요. 다만 float를 만들기 전에 손실된 십진 정보까지 복원할 수는 없습니다. 금액처럼 정확한 십진수가 필요한 값은 처음부터 십진 텍스트를 입력받거나 정수와 문자열로 Decimal를 만드는 편이 좋습니다. 자세한 내용은 decimal 모듈 문서를 참고하세요.

0 방향으로 정수까지 절삭하기

소수 자릿수를 고정하는 대신 정수를 얻으려면 math.trunc()를 사용하세요. 이 함수는 0 방향으로 정수 부분을 반환합니다. 내장 함수 int()도 float를 변환할 때 같은 방식으로 동작합니다. 예를 들어 math.trunc(5.67)은 5이고 math.trunc(-3.45)는 -3입니다. 두 방법 모두 소수 자릿수를 유지하지 않습니다. 결과에 고정된 소수 자릿수가 필요하면 Decimal.quantize()를 사용하세요. math.trunc()는 __trunc__()을 구현한 숫자형도 받으며, 이 메서드가 절삭에 사용할 정수 값을 제공합니다.

float에 스케일을 적용하면 예상과 다른 결과가 나올 수 있는 이유

흔히 쓰는 간편한 방법은 float에 10의 거듭제곱을 곱하고, 그 결과를 정수로 변환한 다음 다시 나누는 것입니다. 일부 값에서는 잘 작동하지만, 이진 부동소수점은 많은 십진 소수를 정확히 표현할 수 없습니다. 따라서 곱셈 결과가 의도한 십진 값보다 약간 작거나 클 수 있고, int(value * 100) / 100을 사용하면 예상과 다른 자릿수가 버려질 수 있습니다. 이 연산은 또 다른 float를 반환하므로 이진 표현의 한계도 여전히 남습니다. 십진 정밀도가 중요한 작업에서는 이 방법에 의존하지 말고 텍스트 입력과 함께 Decimal를 사용하세요. 본질적으로 근삿값을 다루는 계산이라면 출력된 숫자를 정확한 값으로 간주하지 말고 정밀도 한계를 고려해 float를 사용하세요.

목적에 맞는 방법 선택하기

  • 고정된 소수 자릿수까지 절삭하려면 십진 텍스트로 만든 Decimal와 quantize(..., rounding=ROUND_DOWN)를 사용하세요.
  • 소수 부분을 버리고 0 방향의 정수를 반환하려면 math.trunc() 또는 int()를 사용하세요.
  • 절삭이 아니라 반올림이 목적일 때는 round()를 사용하세요.
  • 화면에 표시되는 텍스트만 조정하려면 서식 지정을 사용하세요. f"{value:.2f}"와 같은 f-string은 문자열을 만들고 표시되는 값을 반올림합니다. 원래 float를 변경하거나 절삭하지는 않습니다.

필요한 결과가 정해진 정밀도의 십진 값인지, 정수인지, 반올림한 값인지, 아니면 서식이 지정된 문자열인지에 따라 방법을 선택하세요.