0.1 과 같은 숫자는 2진법으로 나타내기가 어렵다.
0.1(10진법) => 0.00110011001100...(2진법)
>>>0.2 * 3 == 0.6
False
그러므로 Equality Test는 사전에 정의된 정밀도 범위 내에서 수행되어야 한다. 한가지 예시로는 unittest모듈의 assertAlmostEqual()메서드를 사용하면 된다.
또는 메모리에서 비트 패턴으로 비교할 수 있다. 먼저, 부호 비교를 별도로 처리한다. 두 숫자가 음수면 부호를 뒤집고, 숫자를 반전하여 비교한다. 지수패턴이 같으면 가수를 비교한다.
>>>1.25.as_integer_ratio()
(5, 4)
z = 3 + 4j
와 같이 생긴 부동소수점 한 쌍을 갖는 불변형(immutable)이다.정확한 10진법의 부동소수점 숫자가 필요한 경우, 불변형(immutable)인 decimal.Decimal을 사용할 수 있다.
Decimal() 메서드는 정수 또는 문자열을 인수로 취한다.
>>>sum(0.1 for i in range(10)) == 1.0
False
>>> from decimal import Decimal
>>> sum(Decimal("0.1") for i in range(10)) == Decimal("1.0")
True
math와 cmath 모듈처럼 Decimal에도 Decimal.exp(x)와 같은 내장 함수가 있다. 차이점으로는 decimal 모듈을 사용하는게 더 정확도가 높다.
def convert_to_decimal(number, base):
multiplier, result = 1, 0
while number > 0:
result += number % 10 * multiplier
multiplier *= base
number = number // 10
return result
def test_convert_to_decimal():
number, base = 1001, 2
assert convert_to_decimal(1001, 2) == 9, "다른 결과가 나옴"
print("테스트 통과")
if __name__ == "__main__":
test_convert_to_decimal()
테스트 통과
def convert_from_decimal(number, base):
multiplier, result = 1, 0
while number > 0:
result += number % base * multiplier
multiplier *= 10
number = number // base
return result
def test_convert_from_decimal():
number, base = 9, 2
assert convert_from_decimal(number, base) == 1001, "다른 결과가 나옴"
print("테스트 통과")
if __name__ == "__main__":
test_convert_from_decimal()
테스트 통과