>백엔드 개발 >PHP 튜토리얼 >PHP에서 부동 소수점 숫자를 비교하는 방법은 무엇입니까?

PHP에서 부동 소수점 숫자를 비교하는 방법은 무엇입니까?

怪我咯
怪我咯원래의
2017-07-11 13:58:494161검색

부동소수점 숫자는 변환 과정에서 오류가 발생하므로 부동소수점 숫자의 크기를 직접 비교할 수는 없습니다. 일반적으로 두 부동소수점 숫자를 비교할 때는 두 숫자의 차이가 다음 이내이면 차이를 비교합니다. 허용 가능한 범위 내에 있으면 두 부동 소수점 숫자가 동일한 것으로 간주합니다. 이번 글에서는 참고값이 좋은 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=0

4/2=2 4%2=0
2/2 =1 2%2=0

1은 2보다 작으므로 계산할 필요가 없습니다. 정수 8의 이진 표현은

1000

소수 부분은 0.5

0.5x2입니다. = 1.0

반올림 후의 소수 부분이 0이므로 더 이상 계산할 필요가 없습니다

십진수 0.5의 이진법은 0.1

8.5이진법은 1000.1

이진법 계산 0.9

0.9x2=1.8

0.8x2 =1.6
0.6x2=1.2
0.2x2=0.4
0.4x2=0.8
0.8x2=1.6

… 정확성 N이면 N 다음의 숫자는 반올림되어 정확도가 떨어집니다.

위의 예에서는 바이너리로 변환하면 정밀도 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
?>

2.

먼저 작업을 수행합니다. 고정밀 계산 방법을 사용할 때 정확도가 손실되지 않는지 확인할 수 있습니다.

고정밀도 연산 방법은 다음과 같습니다.

bcadd

두 개의 고정밀도 숫자 추가

bccomp

두 개의 고정도 숫자를 비교하여 -1,0을 반환하고, 1

bcp

두 개의 고정밀 숫자 나누기

bcmod

고정밀 숫자의 나머지 구하기

bcmul

두 개의 고정밀 숫자 곱하기

bcpow

높이 탐색 정밀 숫자 power

bcpowmod 고정밀 숫자 거듭제곱 및 모듈러스 찾기

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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.