2014-11-18 10 views
4
예를 들어

의 뺄셈의 결과 ... PHP. 두 개의 부동 소수점 수

$aa = 10694994.89; 
$bb = 10696193.86; 
$ab = $aa - $bb; 
// result is:-1198.9699999988 not the -1198,97 

그러나이 exampe에서

:

$cc = 0.89; 
$dd = 0.86; 
$cd = $cc - $dd; 
//Result is: 0.03 

왜 예와의 차이점은 무엇입니까? 정밀도가 떨어 집니까?

+7

다시 한번 : http://floating-point-gui.de/ –

+0

예제와의 차이점은 무엇입니까? –

+0

@AndreyK. 이 링크를 참조하십시오 : http://php.net/manual/en/language.types.float.php!'부동 소수점 숫자의 정밀도는 제한되어 있습니다 .' – Rizier123

답변

3

없음은 이진 부동 포인트에 정확히를 표시 할 수 없습니다. 그들은 모두 어떻게 든 둥근 있습니다. 문제는 왜 결과 중 하나가 (겉으로보기에는) 2 자리 10 진수로 반올림되고 다른 하나는 반올림되지 않은 이유입니다. 그 대답은 정밀도정확도의 부동 소수점 숫자와 정밀도 PHP가이를 인쇄하는 데 사용되는 차이입니다.

부동 소수점 수는 2의 거듭 제곱과 곱하여 스케일링 범위 [1, 2)에서, 유효수 (또는 가수)으로 표현된다. (이것은 부동 소수점에서 "부동"이 의미하는 것입니다.) 숫자의 정밀도유효 숫자의 자릿수로 결정됩니다. 정확도은 실제로 해당 숫자 중 몇 개가 맞는지에 따라 결정됩니다. 자세한 내용은 How are floating point numbers are stored in memory?을 참조하십시오. PHP에서 부동 소수점 숫자 당신 echo, 그들은 처음

정말 무슨 일이 일어나고 있는지 보려면 (Zend/zend_operators.c에서) (14)을 기본값 precision 구성 설정을 사용하여 문자열로 변환됩니다

, 당신은 인쇄해야

$aa = 10694994.89; 
$bb = 10696193.86; 
$ab = $aa - $bb; 

printf ("\$aa: %.20G\n", $aa); 
printf ("\$bb: %.20G\n", $bb); 
printf ("\$ab: %.20G\n\n", $ab); 

$cc = 0.89; 
$dd = 0.86; 
$cd = $cc - $dd; 

printf ("\$cc: %.20G\n", $cc); 
printf ("\$dd: %.20G\n", $dd); 
printf ("\$cd: %.20G\n", $cd); 

출력 :

$aa: 10694994.890000000596 
$bb: 10696193.859999999404 
$ab: -1198.9699999988079071 

$cc: 0.89000000000000001332 
$dd: 0.85999999999999998668 
$cd: 0.030000000000000026645 
더 큰 정밀도를 사용하여 번호

초기 숫자의 정밀도는 약 16 ~ 17 자입니다. $aa-$bb을 빼면 처음 4 자리가 서로 취소됩니다. 결과 (여전히 약 16 ~ 17 자릿수의 정밀도를 가짐)는 이제 정확도 인 ~ 약 12 ​​자리입니다. 이 낮은 정확도는 결과가 14 자리 정밀도로 인쇄 될 때 나타납니다.

다른 빼기 ($cc-$dd)는 14 자리 정밀도로 인쇄 할 때 눈에 띄지 않는 한 자리 수의 정확도 만 손실됩니다.

1

이 당신을 위해 작동합니다 :

는 (당신은 당신의 결과를 반올림 해!) 코드의 숫자의

$aa = 10694994.89; 
$bb = 10696193.86; 
echo $ab = round($aa - $bb, 2); 
+0

나는 이것을 반올림 할 수 있지만, 왜 두 가지 예? –

+0

@AndreyK. 간단합니다 : 예 :'100/3' ='3.33333 ....'AND'10-5' = '5'! – Rizier123

+1

내가 게시 한 링크를 읽고 컴퓨터가 부동 소수점 숫자를 처리하는 방법을 이해합니다. –