쾌락코딩

console.log(0.1 + 0.2 == 0.3); 의 결과는?

|

Front-end-Developer-Interview-Questions에서 본 질문이다. 처음엔 == 와 === 를 비교하는 문제인가 싶었는데 아니었다.

숫자

이 문제는 컴퓨터 내부 원리에 대해 아주 살짝의 이해가 필요했다. 젼혀 겁먹을 것은 아니고 진법 변환에 대한 내용이다. 컴퓨터는 우리가 주로 사용하는 10진수를 내부적으로 2진수로 변환시켜 계산을 한다. 컴퓨터는 0과 1로 모든 것을 처리하기 때문이다. 예를 들어 10진수 3은 2진수 11, 10진수 4는 2진수 100. 이렇게 변환되는 것이다.

소수점을 처리할 경우에도 마찬가지인데, 몇몇 소수는 특이하게도 무한하게 긴 2진수가 된다고 한다. 당연히 컴퓨터 메모리는 용량이 정해져 있기 때문에 무한한 2진수는 적절하게 자를 수 밖에 없고, 이렇게 자르게 됨으로써 아주 미세한 숫자 차이(오차)가 생기게 된다.

console.log(0.1 + 0.3) // 0.4
console.log(0.1 + 0.2) // 0.30000000000000004

코드에서 보듯이 0.1 + 0.3은 우리가 기대한 것처럼 0.4 가나온다. 이는 0.1 과 0.3 모두 2진수로 변환했을 때 무한한 숫자가 아니기 때문에 그런 것이다. 반면 0.1 + 0.2는 아주 아주 미세한 차이로 우리가 기대한 0.3과 다른 값을 출력한다. 이 것은 0.2가 2진수로 변환되었을 때 무한한 숫자가 되어 내부적으로 유한한 숫자로 바꾸기 위해 끝 부분을 자름으로써 오차가 발생했기 때문이다.

True가 되게 하는 방법

toFixed() 라는 함수가 있다.

(0.1+ 0.2).Fixed(1); // "0.3"

이렇게 매개변수로 받은 숫자만큼의 소수자리까지 반올림해서 출력한다.

숫자관련 메소드 사용시 주의사항

아주 중요한 것은 아니지만 주의해야 할 사항이 있다.

1.toFixed(2) // SyntaxError: Invalid or unexpected token

위의 코드를 실행하면 “1.00”이 나올 줄 알았는데 에러가 난다. 반면

1.232.toFixed(2) // "1.23"

이 코드는 정상 출력된다. toFixed() 함수가 float형태의 숫자에서만 가능해서 그런게 아니다. js가 멍청해서 그런 것이다….(?) js는 숫자 부분에서 . 이 나오면 당연히 소숫점이라 생각해서 . 뒤에 소수가 올 것이라 생각한다. 그런데 1.toFixed(2); 같은 경우에는 .뒤에 숫자가 아니라 함수가 와버려서 js가 당황한 나머지 에러를 뿜어준 것이다. 반면

1.232.toFixed(2) // "1.23"

이 코드가 정상 출력된 이유는, 숫자에 . 이 두번오는 경우는 없으니 첫번째 . 은 소수점으로 이해한 것이고, 두 번째 오는 . 에서는 함수가 올 것을 예상한 것이다.

그럼

1.toFixed(2) // SyntaxError: Invalid or unexpected token

이 코드를 정상 수행 하고 싶다면,

1. toFixed(2) // "1.00"

이렇게 1. 뒤에 의도적으로 뛰어쓰기를 하면 된다.

참고자료

Comments