부동소수점 연산
2010. 11. 4. 15:50ㆍ99. 정리전 - IT/11. Java
http://kin.naver.com/qna/detail.nhn?d1id=1&dirId=1040202&docId=111685795&qb=amF2YXNjcmlwdCDsl7DsgrA=&enc=utf8§ion=kin&rank=2&search_sort=0&spq=0&pid=gL5SYloi5T8sscE3a/0sss--380142&sid=TNJVvpBO0kwAAHm3CaU
1년에 두세번 나올까 말까하는 질문이네요.
님께서도 웹언어를 꽤 다루셨던 분인 것 같습니다.
그만큼 알면서도 질문 안하시는 분들이 대부분이었고, 이제는 알고자하는 여유 같은 것도 있는 것 같습니다.
자바스크립트를 하다보면, "자바스크립트 뭐, 이래" 이런 말을 종종하는 경우가 있었을 겁니다.
다들 처음에는 버그정도로 간주하면서도, 나중에야 자바스크립트의 진실에 다가서는 것은 아닌가 싶네요.
아래 주소에서 보다 자세한 내용을 참고해보시고요..
http://www.merlyn.demon.co.uk/js-maths.htm
http://www.merlyn.demon.co.uk/js-round.htm
간단히 코드를 보여 드리면 아래와 같이 하시면 됩니다.
자바스크립트는 부동소수점 방식(floating point)으로 계산을 하며 IEEE Standard 754규격을 따릅니다.
그리고 실수의 변환을 위해 53bit의 연산을 합니다.
정수인 경우에는 해당 기억공간의 범위안에서 정확한 결과를 나타내는데,,
실수인 경우에는 기억공간의 범위를 벗어나는 결과가 나타나면 나머지수를 버립니다.
컴퓨터가 연산을 위해 소수점 이하의 자릿수를 이진수로 변환하는 과정이 존재합니다.
0.3 을 이진수로 바꾸는 예를 보겠습니다.
0.3 * 2 = 0.6
0.6 * 2 = 1.2
0.2 * 2 = 0.4
0.4 * 2 = 0.8
0.8 * 2 = 1.6
0.6.. <== 다시 0.6이 나와,, 0.0100110011001.... 와 같이 무한히 반복하게 됩니다.
0.3의 이진수처럼 기억공간의 한계를 벗어나는 결과치가 나오는 경우에는
부정확한(최대한 가까운?) 연산을 하게 되는 것입니다.
이해가 되셨는지 모르겠네요..
예 )
alert(2*(1e-1));//0.2 ==> 0.2
alert(3*(1e-1));//0.3 ==> 0.30000000000000004
javascript로 산술식을 하는데 0.6과 0.3을 더하면 정확하게 계산이 안되서 올려봅니다.
alert(0.6+0.3);
해보시면 저와 같이 0.8999999가 나오는걸 확인 할 수 있을것입니다.
0.9의 값을 받고 싶습니다.
alert(0.6+0.3);
해보시면 저와 같이 0.8999999가 나오는걸 확인 할 수 있을것입니다.
0.9의 값을 받고 싶습니다.
1년에 두세번 나올까 말까하는 질문이네요.
님께서도 웹언어를 꽤 다루셨던 분인 것 같습니다.
그만큼 알면서도 질문 안하시는 분들이 대부분이었고, 이제는 알고자하는 여유 같은 것도 있는 것 같습니다.
자바스크립트를 하다보면, "자바스크립트 뭐, 이래" 이런 말을 종종하는 경우가 있었을 겁니다.
다들 처음에는 버그정도로 간주하면서도, 나중에야 자바스크립트의 진실에 다가서는 것은 아닌가 싶네요.
아래 주소에서 보다 자세한 내용을 참고해보시고요..
http://www.merlyn.demon.co.uk/js-maths.htm
http://www.merlyn.demon.co.uk/js-round.htm
간단히 코드를 보여 드리면 아래와 같이 하시면 됩니다.
var a=0.6;
var b=0.3;
var T=Number('1e'+1);
alert(Math.round((a+b)*T)/T);
[설 명]var b=0.3;
var T=Number('1e'+1);
alert(Math.round((a+b)*T)/T);
자바스크립트는 부동소수점 방식(floating point)으로 계산을 하며 IEEE Standard 754규격을 따릅니다.
그리고 실수의 변환을 위해 53bit의 연산을 합니다.
정수인 경우에는 해당 기억공간의 범위안에서 정확한 결과를 나타내는데,,
실수인 경우에는 기억공간의 범위를 벗어나는 결과가 나타나면 나머지수를 버립니다.
컴퓨터가 연산을 위해 소수점 이하의 자릿수를 이진수로 변환하는 과정이 존재합니다.
0.3 을 이진수로 바꾸는 예를 보겠습니다.
0.3 * 2 = 0.6
0.6 * 2 = 1.2
0.2 * 2 = 0.4
0.4 * 2 = 0.8
0.8 * 2 = 1.6
0.6.. <== 다시 0.6이 나와,, 0.0100110011001.... 와 같이 무한히 반복하게 됩니다.
0.3의 이진수처럼 기억공간의 한계를 벗어나는 결과치가 나오는 경우에는
부정확한(최대한 가까운?) 연산을 하게 되는 것입니다.
이해가 되셨는지 모르겠네요..
예 )
alert(2*(1e-1));//0.2 ==> 0.2
alert(3*(1e-1));//0.3 ==> 0.30000000000000004
<script>
var a = 0.6;
var b = 0.3;
var Result = a+b;
alert(Result.toFixed(1)); //소수 1째짜리까지 표현
</script>
var a = 0.6;
var b = 0.3;
var Result = a+b;
alert(Result.toFixed(1)); //소수 1째짜리까지 표현
</script>