Enjoy an ad free experience by logging in. Not a member yet? Register.

Results 1 to 4 of 4
Thread: if inside for

04122012, 04:28 PM #1
 Join Date
 Nov 2011
 Posts
 97
 Thanks
 2
 Thanked 0 Times in 0 Posts
if inside for
Hello, I wrote this php code for show a string when a variable is equal to 3, but it print 3 instead of the string, do you know why?
Thank you!
PHP Code:<?php
for($a=0.03;$a<=9;$a=$a+0.03)
{
if($a==3)
echo "Equal to 3";
else
echo $a. " ";
}
?>
04122012, 04:54 PM
#2
 Join Date
 Sep 2002
 Location
 Saskatoon, Saskatchewan
 Posts
 16,987
 Thanks
 4
 Thanked 2,660 Times in 2,629 Posts
This is a precision error (defined by IEEE standards and requires knowledge of floating point arithmetic and how a machine represents floats).
Effectively, you need to calculate based to epsilon, or a "close enough" number. Alternatively, treat it as an integer for all steps, and display it as a float of the int / 100 when it comes time to display.
For a bit more info refer here: http://www.php.net/manual/en/languag...oat.comparison and here: http://en.wikipedia.org/wiki/Machine_epsilonPHP Code:
function cmpFloat($f1, $f2, $epsilon)
{
return abs($f1  $f2) < $epsilon; // ie: our number is "close enough"
}
$epsilon = pow(2, 24);
for($a=0.03;$a<=9;$a=$a+0.03)
{
if(cmpFloat($a, 3.0, $epsilon))
{
echo "Equal to 3" . PHP_EOL;
}
else
{
echo $a . " " . PHP_EOL;
}
}
04122012, 09:37 PM
#3
 Join Date
 Nov 2011
 Posts
 97
 Thanks
 2
 Thanked 0 Times in 0 Posts
So it require the number to be rounded and limited?
Why does this code work without any other operations?
PHP Code:
$a= 3.03;
if($a==3.03)
echo "Ok";
04132012, 12:51 AM
#4
 Join Date
 Sep 2002
 Location
 Saskatoon, Saskatchewan
 Posts
 16,987
 Thanks
 4
 Thanked 2,660 Times in 2,629 Posts
No, the numbers are not rounded explicitly, but must be checked for a close enough result. This is a flaw with binary representation of floats and how they are limited in the mantissa and exponent values, and is an inherit flaw in all languages as its the limitation in its storage, not that of the calculation.
We won't go into this as its quite complicated and I don't think I still have my old math notes. Floats are stuck to 24 bits of precision: 1 bit sign, 8 bit exponent and 23 bit mantissa. So the limitation here is 23 bits before it starts truncating. Stack onto it the approximation (base 10 cannot divide 1/3 to an even number; binary cannot divide 1/10 for the same reason; therefore 0.1 is not actually representable in binary as you end up with 1100110011001100), and you start seeing loss during arithmetic calculations. It compensates with a truncation.
You cannot trust an accurate comparison between a calculated result of 3.03 and a value of 3.03. You must use a comparison value to determine if its close enough (known as the machine epsilon, which in PHP should be 2^24). So long as its different isn't out by more than that value, its considered to be the same value.