fastsol Posted November 9, 2018 Share Posted November 9, 2018 I'm fighting with a very simple round() that isn't giving me the correct output. In the example below the first var_dump shows the value of the calculation performed. The calculation is correct. Next it runs through the round() native function and comes out incorrect. Then I run a round() again but set another var to the same value as the first calculation but by simply setting the number rather than letting php do the math. Then run it through the round() and it comes out to what I expect it should be. So why is the first one not coming out right? $num = 583.00; $rate = 1.05500; $t = (($num * $rate) - $num); var_dump($t); //comes out 32.065 float CORRECT $just_tax = round($t, 2); var_dump($just_tax); //comes out 32.06 float INCORRECT should be 32.07 $t2 = 32.065; //Explicitly set the same value as $t above $just_tax2 = round($t2, 2); var_dump($just_tax2); //comes out 32.07 float CORRECT Quote Link to comment Share on other sites More sharing options...
requinix Posted November 9, 2018 Share Posted November 9, 2018 Welcome to the world of floating-point arithmetic. $t is not actually 32.065. It's some value that's very close but not precisely that. Apparently just short of 32.065, which is why it's rounding down instead of up. Increase your precision to see what it really is. $ php -r 'var_dump(583.0*1.055-583.0);' float(32.065) $ php -d precision=20 -r 'var_dump(583.0*1.055-583.0);' float(32.064999999999940883) When dealing with floating-point numbers, do all your calculations and then round to a precision that is a couple places more than you need. This gets the number into a state closer to what you expected it to be. Then round to any shorter precision you want. $ php -r 'var_dump(round(583.0*1.055-583.0,2));' float(32.06) $ php -r 'var_dump(round(round(583.0*1.055-583.0,7),2));' float(32.07) Quote Link to comment Share on other sites More sharing options...
fastsol Posted November 9, 2018 Author Share Posted November 9, 2018 Thank you for the explanation. It's certainly something I've not encountered. This was supposed to be a simple sales tax couple functions that someone found that under certain sets of numbers it was off by 1 cent cause it wasn't rounding up for those instances. I messed around a bit more and got this to work so far and seems to product the correct amounts for a few different values. The functions are identical to what I was running before except I changed the 2nd param of the round() to a 3 instead of 2. Unless you feel this will cause other major issues, I'll probably run with this until I can implement a money type library. // Returns formatted number with sales tax added function addSalesTax($num, $rate) { return number_format(round(($num * $rate), 3), 2); } // Returns just the tax amount function calculateTax($num, $rate) { return number_format(round((($num * $rate) - $num), 3), 2); } $num = 635.00; $num2 = 583.00; $rate = 1.05500; echo addSalesTax($num, $rate); echo '<br>'; echo calculateTax($num, $rate); echo '<br><br>'; echo addSalesTax($num2, $rate); echo '<br>'; echo calculateTax($num2, $rate); Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.