2010-08-09 7 views
32

가능한 중복 :
Is JavaScript’s Math broken?
Javascript에서 두 소수를 추가하면 왜 잘못된 결과가 나타 납니까?

왜이 간단한 수학을 JS 망치는 무엇입니까?

document.write(.1 + .2) // 0.3000000000000004 
document.write(.3 + .6) // 0.8999999999999999 

첫 번째 예는 올바른 결과보다 크고 두 번째 예는 적습니다. ??? !! 이걸 어떻게 고치 죠? 조작을 수행하기 전에 항상 소수로 변환해야합니까? 테스트 추가시 (* 및/또는 동일한 문제가없는 것으로 보일뿐) 걱정할 필요가 있습니까?

나는 여러 곳에서 답을 찾았다. 장바구니 양식과 같은 일부 자습서에서는 문제가 존재하지 않고 단순히 가치를 더하는 것처럼 보입니다. 전문가는 다양한 수학 함수에 대한 복잡한 루틴을 제공하거나 JS가 지나치게 "부적절한 작업"이라고 말했지만 아직 설명을 보지 못했습니다.

+0

이 질문에 대한 답변을 확인하십시오 : http://stackoverflow.com/questions/588004/is-javascripts-math-broken –

+0

수천 개의 질문과 가능한 모든 프로그래밍 관련 포럼의 중복 가능성이 있습니다. –

+0

다시?! 우리는 정말로 FAQ를 작성해야합니다. –

답변

6

이것은 자바 스크립트의 제한 사항이 아니며 모든 부동 소수점 계산에 적용됩니다. 문제는 0.1과 0.2와 0.3은 javascript (또는 C 또는 Java 등)가 떠 다니는 것처럼 정확하게 표현할 수 없다는 것입니다. 따라서보고있는 출력은 그 부정확 함 때문입니다.

특히 2의 제곱의 특정 합계 만 정확하게 나타낼 수 있습니다. 0.5 = 0.1b = 2^(- 1), 0.25 = 0.01b = (2^-2), 0.75 = 0.11b = (2^-1 + 2^-2) 모두 괜찮습니다. 하지만 1/10 = 0.000110001100011..b는 무한한 2의 거듭 제곱으로 만 표현 될 수 있습니다.이 무한한 합은 언어가 어느 시점에서 절단됩니다. 이것으로 인해 약간의 오류가 발생합니다. The Floating-Point Guide에서

4

:

왜 나의 숫자, 0.1 + 0.2 멋진 라운드 0.3을 추가하고, 대신 내가 0.30000000000000004 같은 이상한 결과를 얻을처럼?

내부적 때문에 컴퓨터 정확하게 모든 0.1, 0.2 또는 0.3와 같은 다수 를 나타낼 수 없다는 포맷 (이진 부동 소수점)를 사용한다. 코드를 컴파일

또는 해석 , 당신의 "0.1"이미 계산이 발생하기도 전에 오류를 반올림 작은 결과 그 형식으로 가장 가까운 숫자로 반올림 입니다.

사이트에는 자세한 설명과 문제 해결 방법 및 문제가 있는지 여부를 결정하는 방법에 대한 정보가 있습니다.

+0

간단한 답변. – hamzox

15

이것은 JS 문제가 아니라보다 일반적인 컴퓨터 문제입니다.그들은 예를 들어 진 에 물건을 저장하기 때문에 부동 수는 제대로 모든 진수를 저장할 수 없습니다 :

0.5 is store as b0.1 
but 0.1 = 1/10 so it's 1/16 + (1/10-1/16) = 1/16 + 0.0375 
0.0375 = 1/32 + (0.0375-1/32) = 1/32 + 00625 ... etc 

so in binary 0.1 is 0.00011... 

을하지만 그게 끝입니다. 컴퓨터를 어느 시점에서 중지해야한다는 점을 제외하면. 따라서 예제에서 0.00011에 멈 추면 0.1 대신 0.09375가됩니다.

어쨌든 요점은 언어에 따라 다르지 않지만 컴퓨터에 달려 있다는 점입니다. 언어에 따라 달라지는 것은 숫자를 표시하는 방법입니다. 일반적으로 언어는 수를 허용 가능한 표현으로 반올림합니다. 분명히 JS 않습니다.

그렇다면 (메모리의 숫자는 정확합니다.) 텍스트로 변환 할 때 JS를 "멋지게"번호를 둥글게 말하십시오.

sprintf 함수를 사용하면 숫자를 표시하는 방법을 미세하게 제어 할 수 있습니다.

관련 문제