0

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?

3
  • 2
    0.30000000000000004.com Commented Feb 20, 2018 at 13:30
  • 2
    Nothing is wrong. 1/3 is not the same as 0.33333 no matter how many 3 we put after the decimal dot. In practice we usually tend to think they are the same thing but the latter is an approximation of the former. Computers work the same, only the numbers that can be written as m/n where n is a power of 2 can be represented exactly. All the other are approximated. It all depends how much of the error you choose to ignore. Commented Feb 20, 2018 at 13:39
  • @genespos : is your problem resolved with my answer? Commented Feb 21, 2018 at 5:57

1 Answer 1

2

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); 
Sign up to request clarification or add additional context in comments.

4 Comments

Sorry, for late reply. I'm trying to use bcmath or gmp but I haven't yet reached my goal (I'm afraid to use the "easy and fast way") I need "rounded" + "difference" = "original Num". At the moment +1 for the explaining. If you could add code for bcmath or gmp I'll be happy to accept ;)
I have updated answer.. can you give example of what is expected.
Thanks, for extra time! Finally I used: bcsub($Num, round($Num,2), 20);
great. happy to help :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.