요즘 유튜브 '코딩애플'을 즐겨 본다. 썸네일에서 0.1 + 1.1 == 1.2이 틀렸다는 이유를 보고 '메모리 문제인가?', '주소 때문인가?', '변수 타입이 없어서 메모리에 저장되는 주소 문제인가?' 등등의 생각을 하게 되었고, 명확한 답변이 생각나지 않아 유튜브를 보았는데, 좀 더 간단히 정리해 보면 좋을 것 같아 벨로그를 작성하게 되었다.
우선, 컴퓨터가 실수를 어떻게 표현하고 계산하는지를 알아야 한다. 컴퓨터는 실수를 부동소수점 방식으로 표현하는데, 이는 실수를 근사값으로 표현하는 것이다. 무한히 많은 소수를 정확히 표현할 수 없기 때문에 근사값을 사용하는 것이다.
0.1과 1.1을 컴퓨터가 저장할 때, 이진수로 정확히 저장할 수 없다. 그래서 가장 가까운 이진수로 저장한다(근사값으로 저장).
그렇기 때문에 부동소수점 수의 덧셈 연산도 근사값으로 나오게 되고, 1.2에 근접하지만 정확한 1.2가 되지는 않는 것이다.
이를 자바를 통해 확인해 보았고, 이론과 마찬가지로 결과가 출력되는 것을 알 수 있었다.
그렇다면, 이 문제를 해결할 순 없을까?
부동소수점 문제를 해결하기 위해서는 허용 오차(Math.abs())를 사용하면 된다.
public class example {
public static void main(String[] args){
double a = 0.1;
double b = 1.1;
double c = 1.2;
double epsilon = 1e-9; // 허용 오차
boolean isEqual = Math.abs((a + b) - c) < epsilon;
System.out.println("0.1 + 1.1 == 1.2는 맞는 수식인가? : " + isEqual);
}
}
위의 방식은 부동소수점 수의 특성 때문에 발생하는 작은 오차를 허용하여 비교를 가능하도록 하는 방식이다.
요즘 영양가 없는 숏츠만 봐서 삶이 참 지루했는데, 재미있는 유튜브를 발견하게 되어 정말 기쁘다.