user1646111
user1646111

Reputation:

PHP function for float or double comarision (bccomp and gmp_cmp)

PHP Suggested to use these function for floating point number comparison [here]

bccomp — Compare two arbitrary precision numbers

int bccomp ( string $left_operand , string $right_operand [, int $scale ] )

gmp_cmp — Compare numbers

int gmp_cmp ( resource $a , resource $b )

I used bccomp but I cant still get correct result:

<?php
$n1 = bcdiv(1, 2.36, 4);
$n2 = bcdiv(4237288, 10000000, 4);
echo bccomp( $n1, $n2, 4); // 0! must be 1

echo "<br>\n";
var_dump(bcdiv(1, 2.36, 4)); // string(6) "0.4237" 

echo "<br>\n";
var_dump(bcdiv(4237288, 10000000, 4)); // string(6) "0.4237" 

?>

So far, I knew that the result of 1/2.36 is equal to (0.4237288135593220338983050847457627118644067796610169491525423728813559322033898305084745762711864406......)

Then, how to I know that the number of decimals is great like this?

The possible solution:

$n1 = bcdiv(1, 2.36, 400);
$n2 = bcdiv(4237288, 10000000, 400);
echo bccomp( $n1, $n2, 400); //1

I think this solution is till not more usable.

Any suggestion?

Upvotes: 0

Views: 2236

Answers (2)

Eric Postpischil
Eric Postpischil

Reputation: 223101

First, if you want to compare floats, you can use the built-in comparison operators such as <, as mentioned under the heading “Comparing float” on the page you linked to.

Second, if you do not want a direct comparison of the floating-point values (but want some sort of tolerance or partial comparison), you have not specified what comparison you actually want. For the needs of your application, under precisely what circumstances should a comparison return less-than, equal-to, and greater-than?

Third, bccomp is an atrocious way to compare floating-point values:

  • By default, it attempts to use the “number of digits” in the values to determine the tolerance to compare. However, binary floating-point values do not have a number of decimal digits in the way this code tries to measure them.
  • Even if they did, the amount of error that could be present in floating-point values after various operations is not a function of the number of decimal digits in the number, so the number of digits is not a good measure of how much tolerance should be accepted.
  • Once you determine how much error tolerance is acceptable, a digit-by-digit comparison fails to allow for that tolerance. E.g,, if you want to accept as equal two values if they differ by less than .01 but you compare the values 3.4951 and 3.4949 by comparing their two-digit representations “3.50” and “3.49”, they will be reported as unequal even though they differ by only .0002.

Upvotes: 1

sectus
sectus

Reputation: 15464

When you comparing float numbers you MUST choose comparing scale. If 400 is nessary, so it's your scale.

Or... you can try to define your own divide function and compare result on every step of scaling of division. It might be a recursive function.

Upvotes: 1

Related Questions