简体   繁体   中英

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?

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM