이 샘플 코드와 같이 PHP에서 두 개의 float를 비교하고 싶습니다.
$a = 0.17;
$b = 1 - 0.83; //0.17
if($a == $b ){
echo 'a and b are same';
}
else {
echo 'a and b are not same';
}
이 코드에서 그것의 결과를 반환 else
조건 대신에 if
, 비록 조건을 $a
와 $b
동일합니다. PHP에서 float를 처리 / 비교하는 특별한 방법이 있습니까?
그렇다면이 문제를 해결하도록 도와주세요.
또는 서버 구성에 문제가 있습니까?
답변
당신이 이것을 이렇게하면 그들은 동일 해야 합니다. 그러나 참고 부동 소수점 값의 특성은 계산 것을 보인다 실제로 동일 할 필요는 없습니다 같은 값이 발생할 수 있습니다. 따라서 $a
리터럴 .17
이고 $b
계산을 통해 도착하면 둘 다 동일한 값을 표시하지만 서로 다를 수 있습니다.
일반적으로 부동 소수점 값이 같은지 비교하지 않습니다. 허용 가능한 가장 작은 차이를 사용해야합니다.
if (abs(($a-$b)/$b) < 0.00001) {
echo "same";
}
그런 것.
답변
먼저 설명서 의 빨간색 경고 를 읽으십시오 . 플로트가 평등인지 비교해서는 안됩니다. 엡실론 기술을 사용해야합니다.
예를 들면 다음과 같습니다.
if (abs($a-$b) < PHP_FLOAT_EPSILON) { … }
PHP_FLOAT_EPSILON
매우 작은 수를 나타내는 상수는 어디 입니까 (7.2 이전의 PHP 버전에서는 정의해야합니다)
답변
또는 bc 수학 함수를 사용하십시오.
<?php
$a = 0.17;
$b = 1 - 0.83; //0.17
echo "$a == $b (core comp oper): ", var_dump($a==$b);
echo "$a == $b (with bc func) : ", var_dump( bccomp($a, $b, 3)==0 );
결과:
0.17 == 0.17 (core comp oper): bool(false)
0.17 == 0.17 (with bc func) : bool(true)
답변
앞에서 언급했듯이 PHP에서 부동 소수점 비교 (동일, 초과 또는 미만)를 수행 할 때는 매우주의하십시오. 그러나 소수의 유효 숫자에만 관심이 있다면 다음과 같이 할 수 있습니다.
$a = round(0.17, 2);
$b = round(1 - 0.83, 2); //0.17
if($a == $b ){
echo 'a and b are same';
}
else {
echo 'a and b are not same';
}
소수점 이하 2 자리 (또는 3 또는 4)로 반올림을 사용하면 예상 된 결과가 발생합니다.
답변
네이티브 PHP 비교 를 사용하는 것이 좋습니다 .
bccomp($a, $b, 3)
// Third parameter - the optional scale parameter
// is used to set the number of digits after the decimal place
// which will be used in the comparison.
두 피연산자가 같으면 0을, left_operand가 right_operand보다 큰 경우 1을, 그렇지 않으면 -1을 리턴합니다.
답변
동등성과 비교할 부동 소수점 값이있는 경우 OS, 언어, 프로세서 등 의 내부 반올림 전략의 위험을 피하는 간단한 방법 은 값 의 문자열 표현 을 비교하는 것 입니다.
다음 중 하나를 사용하여 원하는 결과를 얻을 수 있습니다. https://3v4l.org/rUrEq
끈 유형 주물
if ( (string) $a === (string) $b) { … }
문자열 연결
if ('' . $a === '' . $b) { … }
strval 함수
if (strval($a) === strval($b)) { … }
문자열 표현은 동등성을 검사 할 때 수레보다 훨씬 덜 까다 롭습니다.
답변
허용되는 소수의 한정된 소수점 수가있는 경우 다음은 훌륭하게 작동합니다 (엡실론 솔루션보다 성능이 느리지 만).
$a = 0.17;
$b = 1 - 0.83; //0.17
if (number_format($a, 3) == number_format($b, 3)) {
echo 'a and b are same';
} else {
echo 'a and b are not same';
}