php의 플로트 비교
다음 샘플 코드와 같이 PHP에서 두 개의 플로트를 비교하고 싶습니다.
$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';
}
에서는 이드음음, 음음음음음 of of of of 의 결과를 합니다.else
" " 가 "if
즉 "", "", "", "",$a
★★★★★★★★★★★★★★★★★」$b
★★★★★를 취급한 방법이 ?PHP로 플로트를 취급/비교하는 특별한 방법이 있습니까?
만약 그렇다면 이 문제를 해결할 수 있도록 도와주세요.
아니면 서버 설정에 문제가 있나요?
이렇게 하면 똑같을 거예요.그러나 부동소수점 값의 특징은 같은 값을 얻을 수 있다고 생각되는 계산이 실제로 동일할 필요는 없다는 점에 유의하십시오.그래서 만약에$a
는 문자 의 자자그 is a a a a a이다..17
★★★★★★★★★★★★★★★★★」$b
두 가지 모두 같은 값을 표시하지만 계산을 통해 서로 다를 수 있습니다.
일반적으로 부동소수점 값은 다음과 같이 비교하지 않습니다. 허용 가능한 최소 차이를 사용해야 합니다.
if (abs(($a-$b)/$b) < 0.00001) {
echo "same";
}
그런 거.
먼저 설명서의 빨간색 경고를 읽으십시오.평등함을 위해 수레를 비교해서는 안 된다.엡실론 기술을 사용해야 합니다.
예를 들어 다음과 같습니다.
if (abs($a-$b) < PHP_FLOAT_EPSILON) { … }
서 ''는PHP_FLOAT_EPSILON
(72 ).
또는 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)
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.
2개의 오퍼랜드가 같으면 0, left_operand가 right_operand보다 크면 1, 그렇지 않으면 -1을 반환합니다.
앞에서 설명한 바와 같이 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)로 반올림하면 예상된 결과가 발생합니다.
부동소수점 값을 동등과 비교할 수 있는 경우 OS, 언어, 프로세서 등의 내부 반올림 전략의 위험을 피하기 위한 간단한 방법은 값의 문자열 표현을 비교하는 것입니다.
다음 중 하나를 사용하여 원하는 결과를 얻을 수 있습니다.https://3v4l.org/rUrEq
스트링 타입 캐스팅
if ( (string) $a === (string) $b) { … }
문자열 연결
if ('' . $a === '' . $b) { … }
스트립 함수
if (strval($a) === strval($b)) { … }
스트링 표현은 플로트보다 훨씬 덜 까다롭습니다.
이것은 PHP 5.3.27에서 동작합니다.
$payments_total = 123.45;
$order_total = 123.45;
if (round($payments_total, 2) != round($order_total, 2)) {
// they don't match
}
허용 가능한 소수점 수가 적은 경우 다음 사항이 적절하게 작동합니다(단, 엡실론 솔루션보다 성능이 느리더라도).
$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';
}
부동소수점 또는 소수점 비교에 대한 해법은 다음과 같습니다.
//$fd['someVal'] = 2.9;
//$i for loop variable steps 0.1
if((string)$fd['someVal']== (string)$i)
{
//Equal
}
adecimal
to 에 variable 。string
괜찮을 거야
PHP 7.2의 경우 PHP_FLOAT_EPSILON(http://php.net/manual/en/reserved.constants.php )을 사용할 수 있습니다.
if(abs($a-$b) < PHP_FLOAT_EPSILON){
echo 'a and b are same';
}
이렇게 쓰면 아마 효과가 있을 것 같아서 질문을 간단하게 했을 거예요.(그리고 질문을 단순하고 간결하게 하는 것은 보통 매우 좋은 일입니다.)
하지만 이 경우 한 가지 결과는 계산이고 다른 한 가지 결과는 상수라고 생각합니다.
이는 부동소수점 프로그래밍의 기본 규칙을 위반합니다.평등 비교는 절대 하지 마세요.
그 이유는 다소1 미묘하지만 기억해야 할 중요한 것은 그것들이 보통 작동하지 않는다는 것과( 아이러니하게도, 적분값의 경우는 제외), 그 대안은 다음과 같은 점에서 애매한 비교라는 것입니다.
if abs(a - y) < epsilon
1. 주요 문제 중 하나는 프로그램에서 숫자를 쓰는 방식과 관련이 있습니다.소수 문자열로 쓰기 때문에 대부분의 분수는 정확한 기계 표현을 가지고 있지 않습니다.그들은 2진법으로 반복되기 때문에 정확한 유한 형태를 가지고 있지 않다.모든 기계 분수는 x/2 형식의n 유리수입니다.이제 상수는 십진수이고 모든 십진수 상수는 x/(2n * 5m) 형식의 유리수입니다.5개의m 숫자가 홀수이기 때문에 어느 숫자에도 2개의 계수가 없습니다n.m == 0일 때만 분수의 이항 및 십진수 확장 모두에 유한한 표현이 있습니다.따라서 1.25는 5/(20*5)이므로2 정확하지만 0.1은 1/(2*51)이므로0 정확하지 않습니다.실제로 시리즈 1.01, 1.99에서는 1.25, 1.50 및 1.75의 3개의 숫자만 정확하게 나타낼 수 있습니다.
플로트의 등식을 비교하는 것은 순진한 O(n) 알고리즘입니다.
각 플로트 값을 문자열로 변환한 다음 정수 비교 연산자를 사용하여 각 플로트의 문자열 표현 왼쪽에서 시작하는 각 숫자를 비교해야 합니다.PHP는 비교하기 전에 각 인덱스 위치의 숫자를 정수로 자동 캐스트합니다.첫 번째 숫자가 다른 숫자보다 크면 루프가 끊어지고 루프가 속한 플로트가 두 자리 중 큰 자리라고 선언됩니다.평균적으로 1/2 * n 비교가 이루어집니다.서로 같은 플로트의 경우 n개의 비교가 있습니다.이것은 알고리즘의 최악의 시나리오입니다.가장 좋은 시나리오는 각 플로트의 첫 번째 숫자가 달라서 하나의 비교만 발생시키는 것입니다.
유용한 결과를 생성하기 위해 원시 부동 값에는 INTEGER Comparison 연산자를 사용할 수 없습니다.정수를 비교하지 않기 때문에 이러한 연산의 결과는 의미가 없습니다.의미 없는 결과를 생성하는 각 연산자의 도메인을 위반하고 있습니다.이것은 델타 비교에도 유효합니다.
정수 비교 연산자는 정수 비교 연산자를 사용합니다.
심플한 솔루션:
<?php
function getRand(){
return ( ((float)mt_rand()) / ((float) mt_getrandmax()) );
}
$a = 10.0 * getRand();
$b = 10.0 * getRand();
settype($a,'string');
settype($b,'string');
for($idx = 0;$idx<strlen($a);$idx++){
if($a[$idx] > $b[$idx]){
echo "{$a} is greater than {$b}.<br>";
break;
}
else{
echo "{$b} is greater than {$a}.<br>";
break;
}
}
?>
2019
TL;DR
아래와 같이 내 기능을 사용하세요.if(cmpFloats($a, '==', $b)) { ... }
- 읽기/쓰기/변경 용이:
cmpFloats($a, '<=', $b)
대bccomp($a, $b) <= -1
- 의존관계는 불필요합니다.
- 모든 PHP 버전에서 작동합니다.
- 음수에 대응합니다.
- 상상할 수 있는 가장 긴 소수점에서도 작동합니다.
- 단점:bccomp()보다 약간 느리다
요약
신비를 공개하겠습니다.
$a = 0.17;
$b = 1 - 0.83;// 0.17 (output)
// but actual value internally is: 0.17000000000000003996802888650563545525074005126953125
if($a == $b) {
echo 'same';
} else {
echo 'different';
}
// Output: different
따라서 아래를 시험해 보면 다음과 같습니다.
if($b == 0.17000000000000003) {
echo 'same';
} else {
echo 'different';
}
// Output "same"
플로트의 실제 값을 얻는 방법은?
$b = 1 - 0.83;
echo $b;// 0.17
echo number_format($a, 100);// 0.1700000000000000399680288865056354552507400512695312500000000000000000000000000000000000000000000000
어떻게 비교할 수 있죠?
- BC 산술 함수를 사용합니다.(wtf-aha-gotcha의 많은 순간을 얻을 수 있습니다)
- PHP_FLOAT_EPSILON(PHP 7.2)을 사용하여 @Gladhon의 답변을 시도할 수 있습니다.
- 플로트와 비교한 경우
==
그리고.!=
, 문자열에 타이프 캐스트 할 수 있습니다.완벽하게 동작합니다.
문자열이 있는 형식 캐스트:
$b = 1 - 0.83;
if((string)$b === (string)0.17) {
echo 'if';
} else {
echo 'else';
}
// it will output "if"
또는 다음과 같이 타입캐스트할 수 있습니다.number_format()
:
$b = 1 - 0.83;
if(number_format($b, 3) === number_format(0.17, 3)) {
echo 'if';
} else {
echo 'else';
}
// it will output "if"
경고:
플로트를 수학적으로 조작(곱하기, 나누기 등)한 후 비교하는 솔루션은 피합니다.대부분은 문제를 해결하고 다른 문제를 발생시킵니다.
권장 솔루션
순수 PHP 함수를 만들었습니다(디펜디세이션/라이브러리/확장 불필요).각 숫자를 확인하고 문자열로 비교합니다.음수에도 대응합니다.
/**
* Compare numbers (floats, int, string), this function will compare them safely
* @param Float|Int|String $a (required) Left operand
* @param String $operation (required) Operator, which can be: "==", "!=", ">", ">=", "<" or "<="
* @param Float|Int|String $b (required) Right operand
* @param Int $decimals (optional) Number of decimals to compare
* @return boolean Return true if operation against operands is matching, otherwise return false
* @throws Exception Throws exception error if passed invalid operator or decimal
*/
function cmpFloats($a, $operation, $b, $decimals = 15) {
if($decimals < 0) {
throw new Exception('Invalid $decimals ' . $decimals . '.');
}
if(!in_array($operation, ['==', '!=', '>', '>=', '<', '<='])) {
throw new Exception('Invalid $operation ' . $operation . '.');
}
$aInt = (int)$a;
$bInt = (int)$b;
$aIntLen = strlen((string)$aInt);
$bIntLen = strlen((string)$bInt);
// We'll not used number_format because it inaccurate with very long numbers, instead will use str_pad and manipulate it as string
$aStr = (string)$a;//number_format($a, $decimals, '.', '');
$bStr = (string)$b;//number_format($b, $decimals, '.', '');
// If passed null, empty or false, then it will be empty string. So change it to 0
if($aStr === '') {
$aStr = '0';
}
if($bStr === '') {
$bStr = '0';
}
if(strpos($aStr, '.') === false) {
$aStr .= '.';
}
if(strpos($bStr, '.') === false) {
$bStr .= '.';
}
$aIsNegative = strpos($aStr, '-') !== false;
$bIsNegative = strpos($bStr, '-') !== false;
// Append 0s to the right
$aStr = str_pad($aStr, ($aIsNegative ? 1 : 0) + $aIntLen + 1 + $decimals, '0', STR_PAD_RIGHT);
$bStr = str_pad($bStr, ($bIsNegative ? 1 : 0) + $bIntLen + 1 + $decimals, '0', STR_PAD_RIGHT);
// If $decimals are less than the existing float, truncate
$aStr = substr($aStr, 0, ($aIsNegative ? 1 : 0) + $aIntLen + 1 + $decimals);
$bStr = substr($bStr, 0, ($bIsNegative ? 1 : 0) + $bIntLen + 1 + $decimals);
$aDotPos = strpos($aStr, '.');
$bDotPos = strpos($bStr, '.');
// Get just the decimal without the int
$aDecStr = substr($aStr, $aDotPos + 1, $decimals);
$bDecStr = substr($bStr, $bDotPos + 1, $decimals);
$aDecLen = strlen($aDecStr);
//$bDecLen = strlen($bDecStr);
// To match 0.* against -0.*
$isBothZeroInts = $aInt == 0 && $bInt == 0;
if($operation === '==') {
return $aStr === $bStr ||
$isBothZeroInts && $aDecStr === $bDecStr;
} else if($operation === '!=') {
return $aStr !== $bStr ||
$isBothZeroInts && $aDecStr !== $bDecStr;
} else if($operation === '>') {
if($aInt > $bInt) {
return true;
} else if($aInt < $bInt) {
return false;
} else {// Ints equal, check decimals
if($aDecStr === $bDecStr) {
return false;
} else {
for($i = 0; $i < $aDecLen; ++$i) {
$aD = (int)$aDecStr[$i];
$bD = (int)$bDecStr[$i];
if($aD > $bD) {
return true;
} else if($aD < $bD) {
return false;
}
}
}
}
} else if($operation === '>=') {
if($aInt > $bInt ||
$aStr === $bStr ||
$isBothZeroInts && $aDecStr === $bDecStr) {
return true;
} else if($aInt < $bInt) {
return false;
} else {// Ints equal, check decimals
if($aDecStr === $bDecStr) {// Decimals also equal
return true;
} else {
for($i = 0; $i < $aDecLen; ++$i) {
$aD = (int)$aDecStr[$i];
$bD = (int)$bDecStr[$i];
if($aD > $bD) {
return true;
} else if($aD < $bD) {
return false;
}
}
}
}
} else if($operation === '<') {
if($aInt < $bInt) {
return true;
} else if($aInt > $bInt) {
return false;
} else {// Ints equal, check decimals
if($aDecStr === $bDecStr) {
return false;
} else {
for($i = 0; $i < $aDecLen; ++$i) {
$aD = (int)$aDecStr[$i];
$bD = (int)$bDecStr[$i];
if($aD < $bD) {
return true;
} else if($aD > $bD) {
return false;
}
}
}
}
} else if($operation === '<=') {
if($aInt < $bInt ||
$aStr === $bStr ||
$isBothZeroInts && $aDecStr === $bDecStr) {
return true;
} else if($aInt > $bInt) {
return false;
} else {// Ints equal, check decimals
if($aDecStr === $bDecStr) {// Decimals also equal
return true;
} else {
for($i = 0; $i < $aDecLen; ++$i) {
$aD = (int)$aDecStr[$i];
$bD = (int)$bDecStr[$i];
if($aD < $bD) {
return true;
} else if($aD > $bD) {
return false;
}
}
}
}
}
}
$a = 1 - 0.83;// 0.17
$b = 0.17;
if($a == $b) {
echo 'same';
} else {
echo 'different';
}
// Output: different (wrong)
if(cmpFloats($a, '==', $b)) {
echo 'same';
} else {
echo 'different';
}
// Output: same (correct)
사용할 소수 자릿수를 결정하고 사용할 수 있습니다.number_format
$a = 0.17;
$b = 1 - 0.83; //0.17
$dec = 2;
if (number_format($a, $dec) == number_format($b, $dec)) {
echo 'a and b are same';
} else {
echo 'a and b are not same';
}
이것은, 2개의 변수의 타입이 혼재하고 있는 경우(스트링 캐스트등의 다른 방식과는 달리), 다음과 같이 동작합니다.
$a = '1.0000'; // Fetched from a DECIMAL db column
$b = 1;
@evilReiko의 기능에는 다음과 같은 버그가 있습니다.
cmpFloats(-0.1, '==', 0.1); // Expected: false, actual: true
cmpFloats(-0.1, '<', 0.1); // Expected: true, actual: false
cmpFloats(-4, '<', -3); // Expected: true, actual: true
cmpFloats(-5.004, '<', -5.003); // Expected: true, actual: false
제 함수에서는 이러한 버그를 수정했습니다만, 어쨌든 이 함수는 잘못된 답을 반환하는 경우가 있습니다.
cmpFloats(0.0000001, '==', -0.0000001); // Expected: false, actual: true
cmpFloats(843994202.303411, '<', 843994202.303413); // Expected: true, actual: false
cmpFloats(843994202.303413, '>', 843994202.303411); // Expected: true, actual: false
비교 플로트 고정 기능
function cmpFloats($a, $operation, $b, $decimals = 15)
{
if ($decimals < 0) {
throw new Exception('Invalid $decimals ' . $decimals . '.');
}
if (!in_array($operation, ['==', '!=', '>', '>=', '<', '<='])) {
throw new Exception('Invalid $operation ' . $operation . '.');
}
$aInt = (int)$a;
$bInt = (int)$b;
$aIntLen = strlen((string)$aInt);
$bIntLen = strlen((string)$bInt);
// We'll not used number_format because it inaccurate with very long numbers, instead will use str_pad and manipulate it as string
$aStr = (string)$a;//number_format($a, $decimals, '.', '');
$bStr = (string)$b;//number_format($b, $decimals, '.', '');
// If passed null, empty or false, then it will be empty string. So change it to 0
if ($aStr === '') {
$aStr = '0';
}
if ($bStr === '') {
$bStr = '0';
}
if (strpos($aStr, '.') === false) {
$aStr .= '.';
}
if (strpos($bStr, '.') === false) {
$bStr .= '.';
}
$aIsNegative = strpos($aStr, '-') !== false;
$bIsNegative = strpos($bStr, '-') !== false;
// Append 0s to the right
$aStr = str_pad($aStr, ($aIsNegative ? 1 : 0) + $aIntLen + 1 + $decimals, '0', STR_PAD_RIGHT);
$bStr = str_pad($bStr, ($bIsNegative ? 1 : 0) + $bIntLen + 1 + $decimals, '0', STR_PAD_RIGHT);
// If $decimals are less than the existing float, truncate
$aStr = substr($aStr, 0, ($aIsNegative ? 1 : 0) + $aIntLen + 1 + $decimals);
$bStr = substr($bStr, 0, ($bIsNegative ? 1 : 0) + $bIntLen + 1 + $decimals);
$aDotPos = strpos($aStr, '.');
$bDotPos = strpos($bStr, '.');
// Get just the decimal without the int
$aDecStr = substr($aStr, $aDotPos + 1, $decimals);
$bDecStr = substr($bStr, $bDotPos + 1, $decimals);
$aDecLen = strlen($aDecStr);
//$bDecLen = strlen($bDecStr);
// To match 0.* against -0.*
$isBothZeroInts = $aInt == 0 && $bInt == 0;
if ($operation === '==') {
return $aStr === $bStr ||
($isBothZeroInts && $aDecStr === $bDecStr && $aIsNegative === $bIsNegative);
} elseif ($operation === '!=') {
return $aStr !== $bStr ||
$isBothZeroInts && $aDecStr !== $bDecStr;
} elseif ($operation === '>') {
if ($aInt > $bInt) {
return true;
} elseif ($aInt < $bInt) {
return false;
} else {// Ints equal, check decimals
if ($aIsNegative !== $bIsNegative) {
return (!$aIsNegative && $bIsNegative);
}
if ($aDecStr === $bDecStr) {
return false;
} else {
for ($i = 0; $i < $aDecLen; ++$i) {
$aD = (int)$aDecStr[$i];
$bD = (int)$bDecStr[$i];
if ($aIsNegative && $bIsNegative) {
if ($aD < $bD) {
return true;
} elseif ($aD > $bD) {
return false;
}
} else {
if ($aD > $bD) {
return true;
} elseif ($aD < $bD) {
return false;
}
}
}
}
}
} elseif ($operation === '>=') {
if ($aInt > $bInt ||
$aStr === $bStr ||
$isBothZeroInts && $aDecStr === $bDecStr) {
return true;
} elseif ($aInt < $bInt) {
return false;
} else {// Ints equal, check decimals
if ($aIsNegative !== $bIsNegative) {
return (!$aIsNegative && $bIsNegative);
}
if ($aDecStr === $bDecStr) {// Decimals also equal
return true;
} else {
for ($i = 0; $i < $aDecLen; ++$i) {
$aD = (int)$aDecStr[$i];
$bD = (int)$bDecStr[$i];
if ($aIsNegative && $bIsNegative) {
if ($aD < $bD) {
return true;
} elseif ($aD > $bD) {
return false;
}
} else {
if ($aD > $bD) {
return true;
} elseif ($aD < $bD) {
return false;
}
}
}
}
}
} elseif ($operation === '<') {
if ($aInt < $bInt) {
return true;
} elseif ($aInt > $bInt) {
return false;
} else {// Ints equal, check decimals
if ($aIsNegative !== $bIsNegative) {
return ($aIsNegative && !$bIsNegative);
}
if ($aDecStr === $bDecStr) {
return false;
} else {
for ($i = 0; $i < $aDecLen; ++$i) {
$aD = (int)$aDecStr[$i];
$bD = (int)$bDecStr[$i];
if ($aIsNegative && $bIsNegative) {
if ($aD > $bD) {
return true;
} elseif ($aD < $bD) {
return false;
}
} else {
if ($aD < $bD) {
return true;
} elseif ($aD > $bD) {
return false;
}
}
}
}
}
} elseif ($operation === '<=') {
if ($aInt < $bInt ||
$aStr === $bStr ||
$isBothZeroInts && $aDecStr === $bDecStr) {
return true;
} elseif ($aInt > $bInt) {
return false;
} else {// Ints equal, check decimals
if ($aIsNegative !== $bIsNegative) {
return ($aIsNegative && !$bIsNegative);
}
if ($aDecStr === $bDecStr) {// Decimals also equal
return true;
} else {
for ($i = 0; $i < $aDecLen; ++$i) {
$aD = (int)$aDecStr[$i];
$bD = (int)$bDecStr[$i];
if ($aIsNegative && $bIsNegative) {
if ($aD > $bD) {
return true;
} elseif ($aD < $bD) {
return false;
}
} else {
if ($aD < $bD) {
return true;
} elseif ($aD > $bD) {
return false;
}
}
}
}
}
}
}
질문에 대한 답변
$a = 1 - 0.83;// 0.17
$b = 0.17;
if($a == $b) {
echo 'same';
} else {
echo 'different';
}
// Output: different (wrong)
if(cmpFloats($a, '==', $b)) {
echo 'same';
} else {
echo 'different';
}
// Output: same (correct)
간단한 답변:
if( floatval( (string) $a ) >= floatval( (string) $b) ) { //do something }
이것은 부동 소수점 숫자를 다루는 데 제 개인 라이브러리의 유용한 수업입니다.원하는 대로 트윗하여 클래스 메서드에 원하는 솔루션을 삽입할 수 있습니다:-).
/**
* A class for dealing with PHP floating point values.
*
* @author Anthony E. Rutledge
* @version 12-06-2018
*/
final class Float extends Number
{
// PHP 7.4 allows for property type hints!
private const LESS_THAN = -1;
private const EQUAL = 0;
private const GREATER_THAN = 1;
public function __construct()
{
}
/**
* Determines if a value is an float.
*
* @param mixed $value
* @return bool
*/
public function isFloat($value): bool
{
return is_float($value);
}
/**
* A method that tests to see if two float values are equal.
*
* @param float $y1
* @param float $y2
* @return bool
*/
public function equals(float $y1, float $y2): bool
{
return (string) $y1 === (string) $y2;
}
/**
* A method that tests to see if two float values are not equal.
*
* @param float $y1
* @param float $y2
* @return bool
*/
public function isNotEqual(float $y1, float $y2): bool
{
return !$this->equals($y1, $y2);
}
/**
* Gets the bccomp result.
*
* @param float $y1
* @param float $y2
* @return int
*/
private function getBccompResult(float $y1, float $y2): int
{
$leftOperand = (string) $y1;
$rightOperand = (string) $y2;
// You should check the format of the float before using it.
return bccomp($leftOperand, $rightOperand);
}
/**
* A method that tests to see if y1 is less than y2.
*
* @param float $y1
* @param float $y2
* @return bool
*/
public function isLess(float $y1, float $y2): bool
{
return ($this->getBccompResult($y1, $y2) === self::LESS_THAN);
}
/**
* A method that tests to see if y1 is less than or equal to y2.
*
* @param float $y1
* @param float $y2
* @return bool
*/
public function isLessOrEqual(float $y1, float $y2): bool
{
$bccompResult = $this->getBccompResult($y1, $y2);
return ($bccompResult === self::LESS_THAN || $bccompResult === self::EQUALS);
}
/**
* A method that tests to see if y1 is greater than y2.
*
* @param float $y1
* @param float $y2
* @return bool
*/
public function isGreater(float $y1, float $y2): bool
{
return ($this->getBccompResult($y1, $y2) === self::GREATER_THAN);
}
/**
* A method that tests to see if y1 is greater than or equal to y2.
*
* @param float $y1
* @param float $y2
* @return bool
*/
public function isGreaterOrEqual(float $y1, float $y2): bool
{
$bccompResult = $this->getBccompResult($y1, $y2);
return ($bccompResult === self::GREATER_THAN || $bccompResult === self::EQUALS);
}
/**
* Returns a valid PHP float value, casting if necessary.
*
* @param mixed $value
* @return float
*
* @throws InvalidArgumentException
* @throws UnexpectedValueException
*/
public function getFloat($value): float
{
if (! (is_string($value) || is_int($value) || is_bool($value))) {
throw new InvalidArgumentException("$value should not be converted to float!");
}
if ($this->isFloat($value)) {
return $value;
}
$newValue = (float) $value;
if ($this->isNan($newValue)) {
throw new UnexpectedValueException("The value $value was converted to NaN!");
}
if (!$this->isNumber($newValue)) {
throw new UnexpectedValueException("The value $value was converted to something non-numeric!");
}
if (!$this->isFLoat($newValue)) {
throw new UnexpectedValueException("The value $value was not converted to a floating point value!");
}
return $newValue;
}
}
?>
언급URL : https://stackoverflow.com/questions/3148937/compare-floats-in-php
'programing' 카테고리의 다른 글
WSO2 API Manager 1.10은 Maria를 지원합니까?DB (0) | 2022.12.27 |
---|---|
특정 순서로 PHPUnit 테스트 실행 (0) | 2022.12.27 |
Javascript에서 난수 생성기 시드하기 (0) | 2022.12.27 |
MySQL - 일대일 관계 (0) | 2022.12.27 |
json_encode/json_decode - PHP의 어레이 대신 stdClass를 반환합니다. (0) | 2022.12.27 |