2010-11-27 13 views
0

여전히 정확한 결과를 얻을 수 없습니다. 최대치 란 무엇입니까? 가능한 한 정확하도록하려면 소수점 이하 자릿수를 표시해야합니까?최대 값은 무엇입니까? float에 대해 표시해야하는 십진수의 크기? (PHP)

일부 코드 (복사 - 붙여 넣기 및 테스트 될 준비) :

// Test with 5 decimals 
$a = 0.00001; 
echo bcadd($a,$a,5) . '<br/>'; 
echo bcadd($a,$a,6) . '<br/>'; 
echo number_format(bcadd($a,$a,5),5) . '<br/>'; 
echo number_format(bcadd($a,$a,5),6) . '<br/>'; 
echo bcadd(0.00001,0.00001,20) . '<br/>'; 
echo number_format(bcadd($a,$a,20),5) . '<br/>'; 
echo number_format(bcadd($a,$a,20),21) . '<br/><br/>'; 

/* Output: 
0.00000 
0.000000 
0.00000 
0.000000 
0.00000000000000000000 
0.00000 
0.000000000000000000000 
*/ 

// Test with 4 decimals 
$a = 0.0001; 
echo bcadd($a,$a,5) . '<br/>'; 
echo bcadd($a,$a,6) . '<br/>'; 
echo number_format(bcadd($a,$a,5),5) . '<br/>'; 
echo number_format(bcadd($a,$a,5),6) . '<br/>'; 
echo bcadd(0.00001,0.00001,20) . '<br/>'; // wtf? this outputs 0 too? 
echo number_format(bcadd($a,$a,20),5) . '<br/>'; 
echo number_format(bcadd($a,$a,20),21) . '<br/>'; 

/* Output: 
0.00020 
0.000200 
0.00020 
0.000200 
0.00000000000000000000 
0.00020 
0.000200000000000000010 
*/ 

내가 대답은 4 유추해야 ??? 하지만 여전히 코멘트가있는 줄에 문제가 있습니다.

편집 : 아무도 내 테스트를 이해하지 못했습니다. 수레가 부정확하다는 것을 알고 있습니다. 하지만 한가지는 1! = 0.98990123이고 다른 것은 1! = 0.0000입니다. bc * 함수의 정밀도를 4로 설정하면, 0.0000이 아니라, 0.9899 이상이 될 것으로 예상됩니다 (완전한 대답이 1 인 경우). 한 가지는 '무한 정밀도에 대해서는 완벽하게 정확하지 않습니다'이고, 다른 것은 '완전히 쓸모가 없습니다'입니다.

편집 2 : @Michael Borgwardt은 최대 무엇 솔루션

+2

는 당신이 필요로하는만큼, 정말 문제가 무엇인지 이해하지 않습니다. 플로트 숫자는 바이너리로 변환되기 때문에 절대로 정확하지 않습니다. –

+1

주석 처리 된 행은 5 개의 소수를 사용합니다. – vakio

답변

2

문제의 주요 원인은 부동 소수점 리터럴을 사용하고 있다는 점이다. 이로 인해 코드가 컴파일되거나 해석되어 binary fraction으로 변환 될 때 반올림 오류가 발생합니다.

그 시점에서, 이미 잃어버린 것입니다 - bc 수학 함수를 사용하면 도움이되지 않습니다. 제대로들을 사용하려면 문자열 리터럴을 사용할 수 있습니다

echo bcadd('0.00001','0.00001',20); 

인쇄됩니다

0.00002000000000000000 
+0

감사합니다. 당신은 내 문제를 이해 한 유일한 사람입니다 =) – HappyDeveloper

4

있습니다. 가능한 한 정확하도록하려면 소수점 이하 자릿수를 표시해야합니까?

문제는 부동 소수점 계산에서 정확한 값을 얻으려고 시도하는 것으로 시작됩니다. 표현 오류 때문에 일반적으로 부동 소수점 계산에서 정확한 값을 얻을 수 없습니다. 값 0.0001은 2 진 부동 소수점으로 정확하게 표현 될 수 없으므로 실제 저장된 값은 0.0001과 약간 다를 수 있으며 이미 부정확합니다. 최하위 숫자가 부정확 할 것이라고 예상해야합니다. 십진수를 더 많이 표시한다고해서 계산이 더 정확 해지는 것은 아닙니다. 단지 고유 한 부정확성을 더 잘 보여줍니다.

정확성이 필요하면 다른 데이터 유형 (bcadd는 문자열을 허용하지만 문자열에서 문자열로의 변환은 여전히 ​​부정확 함을 나타낼 수 있음)을 사용하거나 프로그램을 변경하여 정확한 대답.

유용한 답변을 표시하려는 경우 응용 프로그램에 적합한 정밀도로 표시 할 수 있습니다. 칠면조를 요리하기 위해 오븐을 설정하기 위해 온도를 계산하는 경우 중요한 숫자의 몇 자리를 반올림하는 것이 좋습니다. 과학 계산을하는 경우 3, 4 또는 그 이상의 유효 숫자로 답변을 표시 할 수 있습니다. 100 % 정확도가 필요한 경우 디자인을 재고해야합니다.

+1

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

+0

@Alberto : http://floating-point-gui.de/ –

3

"bcadd"에는 3 개의 인수가 필요합니다. 처음 두 개는 왼쪽과 오른쪽 피연산자를 나타내는 문자열과 결과의 소수 자리를 나타내는 정수입니다. 이 함수는 문자열을 출력합니다. 다섯 번째 결과 에코 대신 정수 대신 문자열 값을 사용하십시오. (PHP.net부터) 부동 소수점의 정확도에 관한 또

:

약 14 진수의 정밀도 ~ 1.8e308 최대이더라도 플로트의 크기는 플랫폼 의존 공통 값 (64 비트 IEEE 형식).

+0

+1 @HappyDeveloper : 매뉴얼 페이지는 [http : // 여기에 있습니다.] php.net/manual/en/language.types.float.php). – netcoder

+0

당신의 대답은 괜찮지 만, bcadd가 이미 3 개의 args를 사용하고있을 때 3 개의 args를 취한다는 말로 시작하지 말았어야합니다. 어쨌든 고마워! – HappyDeveloper

+0

@HappyDeveloper : 처음 두개는 문자열이어야한다는 사실을 보완하고있었습니다. –

-1

BCMath 라이브러리를 사용해보십시오. 기본적으로 숫자를 문자열로 저장하지만 산술을 수행 할 수 있습니다.

Handling Very Large or Very Small Numbers

+0

그는 bc 수학 함수를 사용하고 있습니다 - 그냥 잘못되었습니다. –

+0

그는 BCMath 라이브러리를 사용 중입니다. 그러므로 "bcadd". –