genespos
genespos

Reputation: 3311

PHP incorrect precision while rounding off number

I need to round some numbers and get modifying value.

I've tried:

$Num=12.456;
$RoundDiff=$Num-round($Num,2);
$Num=round($Num,2);
echo $Num.'<br/>'.$RoundDiff;

but I've got:

12.46
-0.0040000000000013

while my expected result was:

12.46
-0.004

What's wrong?
How can I get what I need?

Upvotes: 0

Views: 66

Answers (1)

Touheed Khan
Touheed Khan

Reputation: 2151

Try below code. It will give you the expected result. I have just rounded off the difference.

$Num       = 12.456;
$RoundDiff = $Num-round($Num,2);
$Num       = round($Num,2);
echo $Num.'<br/>'.round($RoundDiff,3);

CodePad

There is issue in precision of floating point values. Refer this article for reference - The PHP floating point precision is wrong by default

If you want exact precision you can use bcmath or gmp.

Because internally, computers use a format (binary floating-point) that cannot accurately represent a number like 0.1, 0.2 or 0.3 at all.

When the code is compiled or interpreted, your “0.1” is already rounded to the nearest number in that format, which results in a small rounding error even before the calculation happens. — floating point guide

Another Reference :

Given that the implicit precision of a (normal) IEEE 754 double precision number is slightly less than 16 digits 3, this is a serious overkill. Put another way, while the mantissa is composed of 52 bits plus 1 implicit bit, 100 decimal digits can carry up to 100*log2(10) =~ 332 bits of information, around 6 times more.

Given this, I propose changing the default precision to 17 (while the precision is slightly less than 16, a 17th digit is necessary because the first decimal digit carries little information when it is low). — source

BCMATH : As requested in comments

$a = 12.456;
$b = round($a,2);
echo 'a ='.$a.'<br>';
echo 'b ='.$b.'<br>';
echo bcsub($a, $b, 3);

Upvotes: 2

Related Questions