0

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?

2 Answers2

1

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.

sectus
  • 15,605
  • 5
  • 55
  • 97
1

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.
Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • Thanks Eric, I am now in the way to improve current application, it uses round to 10 and then uses < for comparison, however, after changing mysql wrap class to PDO, I want also to change that part to native php function. but it seems that there is no chance... –  Feb 24 '13 at 16:37