开发者

Very simple PHP addition problem

I think I have been looking at this for too long. Why is this code printing 'no', it should be printing 'y开发者_StackOverflow社区es' shouldn't it? I've tried it on PHP 5.3 and PHP 5.2 and both print 'no'.

<?php

$total = 14.05;
$var1 = 0;
$var2 = 0.11;
$var3 = 13.94;

if(($var1 + $var2 + $var3) == $total)
{
    echo 'yes';
}
else
{
    echo 'no';
}

?>


See Comparing floating point numbers.

This doesn't work because floating point numbers are not represented exactly. A small rounding error is enough for the equality operator to fail.


Like everybody else say, dont compare floats directly. Just do a if (abs($float1-$float2)<0.0000001)

or similair

In your case

<?php

$total = 14.05;
$var1 = 0;
$var2 = 0.11;
$var3 = 13.94;

if (abs(($var1 + $var2 + $var3)-$total)<0.000001)
{
    echo 'yes';
}
else
{
    echo 'no';
}

?>


As mentioned in other answers, be careful when comparing floats. Try this instead:

echo ((int)(($var1+$var2+$var3)-$total)==0)?"yes":"no";


A very lazy way around this:

$var4 = $var1 + $var2 + $var3;
$var4 = number_format($var4, 2);
$total = number_format($total, 2);

if($var4 == $total)
{
    echo 'yes';
}
else
{
    echo 'no';
}

http://php.net/number_format


If you need to do precise floating point math a lot, it's worth using a library like GMP or BCMath


Because .. thou shalt not compare floats for equality ... it's a rounding issue ... something like 14.05 is actually represented as 14.0499999... all you could do would be comparing with a certain tolarence, e.g. t=0.01 then a=b would be considered true if a+t >= b >= a-t.


I suspect that this is due to floating point precision.

Basically floating point numbers can't be stored with full precision and sometimes results are not what you expect. In order to compare floating point numbers you should allow some tolerance. If you are sure that each number has exactly two decimal places you could multiply by 100 to make them integer values and compare the total then.


This is caused by floating point precision. Floating point number represent the actual value, but only to a certain precision. Try the following instead:

<?
$total = 14.05;
$var1 = 0;
$var2 = 0.11;
$var3 = 13.94;

if((($var1 + $var2 + $var3) > ($total - 0.0000001)) && (($var1 + $var2 + $var3) < ($total + 0.0000001)))
{
    echo 'yes';
}
else
{
    echo 'no';
}
?>


It's a basic floating point maths problem.

Computers work with binary maths. For integer values, there's no problems. But for decimals it uses a technique called floating point maths. The trouble is that while floating points are good, the don't map directly to decimal values; even relatively simple decimal values may not be possible to represent precisely in binary.

If you're always working with two decimal places - eg for currencies - it is often a better idea to deal with your values as integers (eg store cents rather than dollars, or pence rather than pounds), so that all your maths is done using integers and the results will be accurate. You only need it as a decimal for display purposes, which you can do at the point when you need it.


Floating point values have a limited precision. Hence a value might not have the same string representation after any processing. That also includes writing a floating point value in your script and directly printing it without any mathematical operations.

If you would like to know more about "floats" and what IEEE 754 is, read this:

http://docs.sun.com/source/806-3568/ncg_goldberg.html

you can use number_formattig or string casting before comperation

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜