부동소수점 숫자는 변환 과정에서 오류가 발생하므로 부동소수점 숫자의 크기를 직접 비교할 수는 없습니다. 일반적으로 두 부동소수점 숫자를 비교할 때는 두 숫자의 차이가 다음 이내이면 차이를 비교합니다. 허용 가능한 범위 내에 있으면 두 부동 소수점 숫자가 동일한 것으로 간주합니다. 이번 글에서는 참고값이 좋은 php 부동 소수점 수 비교 방법을 주로 소개합니다. 아래 편집기로 살펴보겠습니다
부동소수점 연산의 정확성 문제
먼저 예를 살펴보세요:
<?php $a = 0.1; $b = 0.9; $c = 1; var_dump(($a+$b)==$c); var_dump(($c-$b)==$a); ?>
$a+$b==$c가 true를 반환합니다. 정답입니다
$c- $b==$a false 반환, 오류
왜 이런 일이 발생하나요?
연산 후 정밀도가 20자리일 때 실제 반환되는 내용은 다음과 같습니다.
<?php $a = 0.1; $b = 0.9; $c = 1; printf("%.20f", $a+$b); // 1.00000000000000000000 printf("%.20f", $c-$b); // 0.09999999999999997780 ?>
$c-$b는 0.0999999999999997780이므로 0.1과 비교하면 false가 반환됩니다.
이 문제는 부동 소수점 계산 때문에 발생합니다. 정밀도가 관련됩니다. 부동 소수점 숫자를 이진수로 변환하면 정밀도가 손실될 수 있습니다.
부동 소수점 수를 이진수로 변환하는 방법
정수 부분은 을 2로 나누어 나머지를 구합니다.method
소수 부분은2를 곱하여 반올림합니다method
예: 숫자 8.5를 이진수로 변환
정수 부분은 8입니다.
8/2=4 8%2=04/2=2 4%2=0
2/2 =1 2%2=0
1000
소수 부분은 0.5
0.5x2입니다. = 1.0반올림 후의 소수 부분이 0이므로 더 이상 계산할 필요가 없습니다 십진수 0.5의 이진법은 0.18.5이진법은 1000.1
이진법 계산 0.9
0.9x2=1.80.8x2 =1.6
0.6x2=1.2
0.2x2=0.4
0.4x2=0.8
0.8x2=1.6
위의 예에서는 바이너리로 변환하면 정밀도 0.9가 손실되어 비교 시 오류가 발생합니다.
그러므로 부동 소수점 숫자가 마지막 숫자까지 정확하다고 믿지 말고 두 부동 소수점 숫자가 같은지 비교하지 마세요.부동소수점 숫자를 올바르게 비교하는 방법
1. 라운드 방식을 사용하여 처리한 후 비교
예:
<?php $a = 0.1; $b = 0.9; $c = 1; var_dump(($c-$b)==$a); // false var_dump(round(($c-$b),1)==round($a,1)); // true ?>
먼저 작업을 수행합니다. 고정밀 계산 방법을 사용할 때 정확도가 손실되지 않는지 확인할 수 있습니다.
고정밀도 연산 방법은 다음과 같습니다.bcadd
두 개의 고정밀도 숫자 추가bccomp
두 개의 고정도 숫자를 비교하여 -1,0을 반환하고, 1bcp
두 개의 고정밀 숫자 나누기bcmod
고정밀 숫자의 나머지 구하기bcmul
두 개의 고정밀 숫자 곱하기bcpow
높이 탐색 정밀 숫자 powerbcpowmod 고정밀 숫자 거듭제곱 및 모듈러스 찾기
bcscale Linux
bc에서 "scale="과 동일하게 기본 소수점 이하 자릿수를 구성합니다. bcsqrt 고정밀 숫자 제곱근 요청
bcsub 두 개의 고정밀 숫자 빼기
예:<?php $a = 0.1; $b = 0.9; $c = 1; var_dump(($c-$b)==$a); // false var_dump(bcsub($c, $b, 1)==$a); // true ?>
위 내용은 PHP에서 부동 소수점 숫자를 비교하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!