'니콜라스 자카스' 상당히 좋아하는 저자이지만, 역시 두꺼운 책(1,186페이지)은 읽기 어려운 것 같습니다. 손이 정말 잘 가지 않습니다. 그런데 오늘 퇴근 10분정도 남겨두고 잠깜 보고 갈까했는데, 아주 좋은 내용을 읽어서 이렇게 블로그에 정리해봅니다.
물음표의 값은 무엇일까요?, 당연히 우리는 0.3이라고 하겠지만 실제 JavaScript, C, Python, 등등 저희가 사용하는 대부분 모든 언어에서는 0.3이라고 나오지 않습니다.0.1 + 0.2 = ?
크롬을 사용한다면 지금 F12를 눌러 Console탭에서 확인해보세요.
( sublime text를 사용한다면 ctrl+` )
JavaScript ( Chrome Console ) |
Python ( Sublime Text 3 ) |
자 이쯤되면 알고계신 분들이라면 고개를 끄덕이며 "당연한거 아냐"하시겠지만, 저처럼 정확한 이유를 모르시는 분들은 '머가 문제야!' 혹은 '왜!!'하면서 더운데 더 덥게한다면서 짜증을 내면서 컴퓨터를 끌지도 모르겠습니다.
( 한국전력 헌정 블로그였습니다. -_- )
노랑책(자바스크립트 프로그램밍)에서는 부동소수점 사칙연산은 정수 사칙연산보다 부정확하며, 오류가 아니라 IEEE-754에서 정의한 방식대로 계산했기 때문이라고 합니다. (계속 한국 전력 헌정 블로그입니다. -_-; )
컴퓨터에서 정보를 저장하기 위해서 비트형태 변환하여 저장한다는 사실은 거이 모두 알고 계실것 같습니다. 그리고 정수를 저장할 때는 이진법으로 오차없이 저장을 하게됩니다.
하지만 부동소수점(실수)를 저장할 때는 어떻게 저장할 까요?
IEEE-754에서 부동소수점을 저장하기 위해서는 아래의 그림 처럼 부호, 지수, 가수로 분리하여 저장합니다.
32비트에서는 부호 1비트, 지수 8비트, 가수 23비트로 저장한다고 합니다. 이제 0.1를 IEEE-754에서 정의한 방법으로 저장해봅시다. 그런데 부동소수점 이진법으로 어떻게 변경하는지 아세요?
곱하기2를 해서 1보다 크면 1, 작으면 0으로해서 변경합니다.
( 간단히 말해서 정수반대죠 )
0.1 x 2 = 0.2 이므로 1보다 작으니 0
0.2 x 2 = 0.4 이므로 1보다 작으니 0
0.4 x 2 = 0.8 이므로 1보다 작으니 0
0.8 x 2 = 1.6 드디어 커졌네요. 1, 그리고 0.6은 다시 반복
0.6 x 2 = 1.2 1보다 크므로 1
0.2 x 2 = 0.4 이므로 0 ( 앗 다시 0.4가 나왔네요. 아주 반갑네요. 사실 손 슬슬 아파 오거든요 )
따라서 0.1를 이진수로 변경하면 0.000110011... 이렇게 된다는 것을 알 수 있습니다.
암산으로 0.2도 계산해보면 0.00110011... 입니다.
( 0.2는 0.1에서 한칸씩 당겨져 있습니다. )
32비트에서 제일 큰 부분인 가수부분은 0.1, 0.2 둘다 '10011001100110011001101'이것으로 들어갑니다. 음 그렇쿤하고 넘어가셨는지 모르겠지만 실제 2진수 지수법으로 표기해 보면 아래와 같습니다.
2진수 지수법은 특성상 항상 맨앞이 1인 것을 알 수 있습니다. 그래서 조금이라도 더 많이 더 정확히 저장하기 위해 맨앞의 1은 저장하지 않습니다. 그러면 '10011001100110011001100'이 저장되어야 하는데 뒤부분이 '1100...'으로 무한 반복되기 때문에 반올림되어 '10011001100110011001101'이 저장됩니다.
즉 0.1, 0.2 모두 이 반올림 때문에 0.3 보다 조금 큰 실수가 나오게 됩니다. 자바스크립트로 확인을 해보면 아래와 같습니다.
더 자세한 내용은 참고자료를 링크걸어둡니다.
참고자료
http://en.wikipedia.org/wiki/IEEE_floating_point
http://pub.mearie.org/ieee_754 : IEEE 754 옛날 영문 위키를 번역, 첫 링크에가면 추가된 내용이 많이 있습니다.
http://www.tipssoft.com/bulletin/board.php?bo_table=FAQ&wr_id=177 : 소수점을 이진수로 변경하는 방법이 있음
http://itguru.tistory.com/199 : 모든 컴퓨터 과학자가 알아야 할 부동 소수점의 모든 것, 번역본이 있음.
댓글 1개:
좋은 글 감사합니다. 많은 도움 되었어요^^
댓글 쓰기