Zabs
Zabs

Reputation: 14142

Abs() - issue with absolute value function in PHP

Can anyone explain why this code does this in regards to abs() (absolute value) - In my code it will display 'GREATER' - although 0.50 is never GREATER than 0.5, am I missing out something here with the abs function?

$logic = abs(1.83333333333 - 2.33333333333);  // 0.50
$limit = 0.50;

if ($logic > $limit) {
    echo 'IS GREATER';
} else {
    echo 'IS NOT GREATER';
}

Upvotes: 2

Views: 5682

Answers (4)

Alnitak
Alnitak

Reputation: 339786

Due to the way floating point math works, your absolute value $logic results in this value:

0.50000000000000022204

which is greater than 0.5

NB: above evaluated using Javascript which uses double precision math for all numbers:

Math.abs(1.83333333333 - 2.33333333333).toFixed(20)

Upvotes: 1

Chapter2
Chapter2

Reputation: 102

Never compare floats by equality - user the epsilon technique instead PHP: Floating Point Numbers

define('EPSILON', 1.0e-8);
$logic = abs(1.83333333333 - 2.33333333333);  // 0.50
$limit = 0.50;
$diff = $logic - $limit;
if (abs($diff) < EPSILON)
   echo 'IS EQUAL';
else
   echo 'IS NOT EQUAL';

Upvotes: 0

WWW
WWW

Reputation: 9860

If you don't want to round as suggested by @Aldo's answer and your server supports the GMP math functions, you could use gmp_abs() instead. This way you don't run into PHP's inherent floating point problems.

Upvotes: 1

Aldo Stracquadanio
Aldo Stracquadanio

Reputation: 6237

Passing floating point numbers to abs you will get a floating point number as result. In that case you can experience problems with the floating point representation: a floating point is never absolutely precise, thus you are most likely getting a number that is not exactly 0.50 but something like 0.500000...01. You could try to round the result to the desired precision (in your case I guess it is two) with the php round function.

Upvotes: 6

Related Questions