Python / float() / 자료형을 실수로 변환하는 함수
Python의 float()은 숫자나 지원되는 숫자 형식의 문자열을 부동소수점 수인 float로 변환합니다. 인수를 생략하면 0.0을 반환하지만 빈 문자열이나 None을 자동으로 0으로 바꾸지는 않습니다. 변환에 성공해도 값이 유한한지, 필요한 십진 정밀도를 만족하는지는 별도로 확인해야 합니다.
기본 변환과 원래 값의 자료형
float(value)는 변환 결과를 반환하며 원래 변수의 자료형을 바꾸지 않습니다. 부동소수점 수는 소수점이 있는 수 등을 유한한 비트로 근사해 표현하는 수치 형식입니다. 단순히 화면에 소수점이 보이는지로 자료형이나 정밀도를 판단하지 않습니다. 허용되는 입력과 변환 규칙은 float() 공식 문서를 참고합니다.
아래는 Python 3와 표준 라이브러리만 사용하는 전체 예제입니다. UTF-8의 float_example.py로 저장한 뒤 python float_example.py로 실행합니다. 환경에 따라 python3을 사용합니다. 이후 예제도 파일 내용을 교체해 각각 독립적으로 실행할 수 있습니다.
value = 3
converted = float(value)
print(converted, type(converted).__name__)
print(value, type(value).__name__)
print(float(" -2.5 "))
print(float("1e3"))
print(float())
print(float(True))
예상 결과는 다음과 같습니다.
3.0 float
3 int
-2.5
1000.0
0.0
1.0
정수 value는 그대로이며 새 결과만 float입니다. 앞뒤 공백과 부호가 있는 문자열, 지수 표기 1e3도 해석합니다. True는 수치 변환에서 1.0이 되므로, 불리언을 허용하지 않는 입력이라면 별도 검사해야 합니다.
문자열 형식과 ValueError·TypeError
일반적인 문자열 소수점은 .을 사용합니다. 천 단위 구분 쉼표나 지역별 소수점 쉼표, 통화 기호를 자동으로 해석하지 않습니다. 숫자 형식이 아닌 문자열에는 ValueError, None처럼 지원하지 않는 객체에는 TypeError가 발생합니다.
for value in ("1,234.5", "2,5", "", None):
try:
print(float(value))
except (ValueError, TypeError) as error:
print(type(error).__name__)
ValueError
ValueError
ValueError
TypeError
쉼표를 무조건 삭제하면 2,5가 의도와 다른 25가 될 수 있습니다. 입력 파일의 형식과 지역 규칙을 먼저 정하고, 확인된 규칙으로 정규화한 뒤 변환합니다. 빈 입력은 필수값 오류로 처리할지 결측값으로 둘지 정하며, 무조건 0으로 바꾸어 실제 0과 구분을 잃지 않도록 합니다.
0.1과 0.2의 합이 정확히 0.3이 아닌 이유
대부분의 환경에서 float는 이진 부동소수점으로 저장됩니다. 0.1 같은 일부 십진 소수는 이진수로 유한하게 나타낼 수 없어 가까운 값으로 저장됩니다. 이는 문자열 변환이 실패한 것이 아니라 표현 방식의 한계입니다. Python 부동소수점 설명에 원리가 정리되어 있습니다.
import math
from decimal import Decimal
result = 0.1 + 0.2
print(result)
print(result == 0.3)
print(math.isclose(result, 0.3))
print(Decimal("0.1") + Decimal("0.2"))
0.30000000000000004
False
True
0.3
근삿값 비교에는 math.isclose()를 사용할 수 있지만 허용 오차는 단위와 요구 정확도에 맞춰야 합니다. 0 근처에서는 절대 허용 오차인 abs_tol도 검토합니다. 정확한 십진 계산이 필요하면 Decimal을 원래 십진 문자열에서 생성하는 방법을 고려합니다. Decimal(0.1)은 이미 만들어진 이진 근삿값을 가져오므로 같은 출발점이 아닙니다.
NaN·무한대와 범위 초과 확인
float()는 nan과 inf도 허용합니다. NaN은 Not a Number의 약자로 일반적인 유효 숫자 결과가 아님을 나타내며, inf는 무한대입니다. 변환 성공만으로 유효한 측정값이 되지 않으므로 유한한 수가 필요하면 math.isfinite()로 검사합니다.
import math
for text in ("nan", "inf", "-inf", "2.5"):
number = float(text)
print(text, math.isfinite(number))
nan False
inf False
-inf False
2.5 True
범위를 크게 벗어난 지수 문자열은 무한대가 될 수 있고, 아주 큰 정수를 변환할 때는 OverflowError가 날 수 있습니다. 또한 NaN은 자기 자신과도 같다고 비교되지 않으므로 x == float("nan")으로 검출하지 않습니다. NaN만 확인하려면 math.isnan()을 사용합니다.
print(float("1e400"))
try:
print(float(10 ** 400))
except OverflowError:
print("OverflowError")
print(float("nan") == float("nan"))
inf
OverflowError
False
유한한 숫자만 받는 함수 만들기
입력 검증에는 변환 예외 처리와 유한성 검사를 함께 사용합니다. 다음 함수는 숫자 형식이 잘못된 경우와 유한하지 않은 경우를 구분하고, 성공한 경우에만 float를 반환합니다. 코드의 영문 메시지는 예제의 오류 설명이며 서비스에서는 사용자에게 맞는 문구로 바꿀 수 있습니다.
import math
def finite_number(text):
try:
number = float(text)
except (ValueError, TypeError) as error:
raise ValueError("not a number") from error
if not math.isfinite(number):
raise ValueError("not finite")
return number
for text in ("2.5", "nan", "abc"):
try:
print(finite_number(text))
except ValueError as error:
print(error)
2.5
not finite
not a number
이 함수는 유한성까지만 확인합니다. 나이·수량·비율처럼 허용 범위가 정해진 값은 변환 뒤 상한·하한과 필요하면 정수 여부도 추가로 검사합니다. 어떤 실패도 정상적인 0.0으로 덮어쓰지 않아야 잘못된 입력과 실제 영을 구분할 수 있습니다.




