2010-01-04 4 views
7

ColdFusion 코드에서 이러한 값이 발생했지만 Google 계산기에서 차이가 0이 아닌 동일한 "버그"가있는 것으로 보입니다.이 빼기가 0이 아닌 이유는 무엇입니까?

416582.2850-411476.8100 - 5105.475 = -2.36468622461E-011 긴/플로트에 이러한 JavaCast'ing

http://www.google.com/search?hl=en&rlz=1C1GGLS_enUS340US340&q=416582.2850+-+411476.8100+-+5105.475&aq=f&oq=&aqi=

가/더블 도움말 -하지 않습니다는 0이 아닌 차이가 발생합니다.

+16

SO에서 계정을 만들 때 부동 소수점 퀴즈가 있어야합니다. 나는이 사이트에서 가장 많이 묻는 질문이라고 생각합니다. – recursive

+3

@ 재귀 : http://meta.stackexchange.com/questions/26621/whats-themost-repeated-question-on-stackoverflow/26633#26633 –

+1

프로그래밍을 배울 때 부동 소수점 숫자의 정밀도가 부족합니다. 부동 소수점이 논의 된 최초의시기와 그 이후에 여러 번 언급되었습니다. 더 이상하지 않니? –

답변

16

이것은 10 진수를 "둘러 보거나"2 진수 (부동 소수점 숫자를 나타내는 데 사용되는 컴퓨터)에서 정확히 표현할 수없는 10 진수이기 때문입니다. 이 문제 및 해결 방법에 대한 자세한 설명은 What Every Computer Scientist Should Know About Floating-Point Arithmetic 문서를 참조하십시오.

+1

5105.475는 정확히 이중으로 표시 할 수없는 번호입니다. PrecisionEvaluate는 필자가 필요로하는 ColdFusion 함수입니다. –

+0

실제로 이들 숫자 중 어느 것도 배정 밀도 값으로 정확하게 표현할 수 없습니다. –

+0

+1 훌륭한 참고 자료, GL Steele의 "Floating-Point Numbers를 정확히 인쇄하는 법"을 확인하십시오 –

7

부동 소수점 부정확성 (부동 소수점 실수가 있고이를 표현할 수있는 32 또는 64 비트 숫자가 한정되어 있음).

작은 오류를 처리 할 수없는 경우 BigDecimal을 사용해야합니다.

+1

참조 : http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems –

+0

하지만 416582.2850 - 411476.8100은 * 정확하게 * 5105.475로 표시 될 수 있습니다. 숫자는 소수 만 4 자리이며 반복되지 않습니다. 4 자리수가 너무 정확하게 맞습니까? –

+2

유한 수가되어야하는 10 진수 표현은 아니며 기본 2 표현입니다. 바이너리로 정확하게 표현할 수있는 분수에 대한 설명은 http://en.wikipedia.org/wiki/Binary_numeral_system#Fractions_in_binary를 참조하십시오 (분모의 소수 요소로 2를 갖는 분수 만). –

1

문제는 부동 소수점 유형이 정확하지 않다는 점입니다. 이들은 부동 소수점으로 정확하게 표현 될 수 없기 때문에 연산의 작은 오류를 초래하는 정밀도 손실이 발생합니다. 일반적으로 부동 소수점을 사용하여 결과가 약간의 작은 에피소드 (오류 요인) 내의 다른 값과 같은지 비교하려고합니다.

2

컴퓨터는 숫자를 이진수로 저장하기 때문에 부동 소수점 숫자는 부정확합니다. 1E-11은이 10 진수를 가장 가까운 표현 가능한 2 진수로 반올림하여 작은 차이가 있습니다.

2

이 "버그"는 버그가 아닙니다. 그것은 부동 소수점 계산이 작동하는 방법입니다. 참조 :

자바에서 임의의 정밀도를 원하는 경우 http://docs.sun.com/source/806-3568/ncg_goldberg.htmlBigDecimal를 사용

BigDecimal a = new BigDecimal("416582.2850"); 
    BigDecimal b = new BigDecimal("411476.8100"); 
    BigDecimal c = new BigDecimal("5105.475"); 
    System.out.println(a.subtract(b).subtract(c)); // 0.0 
1

이 점 문제를 떠 그것을 해결됩니다 BigDecimal을 사용하고 있습니다.

뺄셈 순서를 변경하면 Google에서도 0이됩니다.

416582.2850 - 5105.475 - 411476.8100 = 0 
5

ColdFusion에서의 사용 PrecisionEvaluate() (은 자바 BigDecimal를 사용합니다)를

zero = PrecisionEvaluate(416582.2850 - 411476.8100 - 5105.475); 

Evaulate() 달리, 아니 ""필요합니다.

+1

+1 실제 감기 융해 용액 – Kip

관련 문제