PHP Rounding Error

PHP rounding error

This is because the number 1111111.505 can't be represented exactly in floating point notation. The closest it can get is 1111111.5049999999. So what ends up happening is that it converts the number in your code to 1111111.50499999999 and then it does the rounding. Which results in 1111111.5. Floating point numbers have problems in that they can't represent a lot of even seemingly simple decimal numbers with complete accuracy. For instance. the number 0.1 cannot be accurately represented using binary floating numbers. Using Python, if you type in 0.1, it returns 0.10000000000001. Plus or minus a few zeros. This is the reason that some languages such as .Net provide a "Decimal" data type which is able to represent all decimal values within a certain range and number of decimal places. The downside of the decimal data type is that it is slower, and each number takes more space to store.

PHP decimal rounding error

echo number_format($milliseconds,6);

http://php.net/manual/en/function.number-format.php

Rounding error when casting from float to int

It could be a floating point error.

In php, a float value like 255 could actually be something like 254.9999991. You can round the value before converting to int.

echo (int) ( round( (float) '2.55' * 100 ) );

This will result to

255

From PHP Doc:

Warning Floating point precision Floating point numbers have limited
precision. Although it depends on the system, PHP typically uses the
IEEE 754 double precision format, which will give a maximum relative
error due to rounding in the order of 1.11e-16. Non elementary
arithmetic operations may give larger errors, and, of course, error
propagation must be considered when several operations are compounded.

http://php.net/manual/en/language.types.float.php

PHP rounding error with simple multiplication

Things can get hairy when you're dealing with floats, floating point math (and problems involved) are well understood, but can crop up when you're not expecting them. As seems to have happened here. You could read up on the rules extensively, or use language provided tools when handling floating point arithmetic.

When you care about the precision involved you should use the bcmul() function. It's an "optional" extension, but if you care about precision it starts being required rather quickly.

Example:

multiplier = 100000000;
$value = 0.01020637;
echo (int)($value*$multiplier);
echo "\n";
echo bcmul($value, $multiplier, 0);

Sample: http://ideone.com/Wt9kKb

Floating point rounding error php ...how can I make sure it works correctly?

I think you are doing what is mentioned on php floating help page. To quote it directly :

To test floating point values for equality, an upper bound on the
relative error due to rounding is used. This value is known as the
machine epsilon, or unit roundoff, and is the smallest acceptable
difference in calculations.

$a and $b are equal to 5 digits of precision.

<?php
$a = 1.23456789;
$b = 1.23456780;
$epsilon = 0.00001;

if(abs($a-$b) < $epsilon) {
echo "true";
}
?>

So in your case:

(to_currency_no_money($this->sale_lib->get_total()) - $total_payments) > 1e-6

relative error due to rounding should not be great than 1e-6 or 0.000001

if you are not sure about left operand being greater than right 100% time,then you should add abs() e.g for correctness.

$relative_error=to_currency_no_money($this->sale_lib->get_total()) - $total_payments;
if(abs($relative_error) > 1e-6){
return false
}
return true;

PHP - Converting a String float to an Integer - Wrong value

First of all, read Is floating point math broken?

8.54 happens to be one of those numbers which can be written precisely in decimal, but not in binary, so (float)"8.54" will actually create a number very very close to, but slightly under, 8.54.

Multiplying that by 100 will create a number very very close to, but slightly under, 854. And casting to int will find the next smallest integer (e.g. 853.9 becomes 853, not 854).

I can think of two solutions:

  • After multiplying by 100, round to the nearest whole number, then convert to integer. Unlike 8.54, 854 itself can be represented precisely in floating point, so round(8.54 * 100) will give a number that is exactly 854, rather than slightly under it. So (int)round((float)"8.54" * 100) will give 854 as an integer.
  • Instead of multiplying by 100, remove the . from the string, and convert to int directly, e.g. (int)str_replace(".", "", "8.54"));

Improper rounding with PHP round() and a 14 decimal float

You're seeing expected behavior:

php>  echo round(10.50499999999977);
11
php > echo round(10.50499999999977, 1);
10.5
php > echo round(10.50499999999977, 2);
10.5
php > echo round(10.50499999999977, 3);
10.505
php > echo round(10.50499999999977, 4);
10.505
php > echo round(10.50499999999977, 6);
10.505
php > echo round(10.50499999999977, 7);
10.505

As per the docs:

PHP_ROUND_HALF_UP Round val up to precision decimal places away from zero, when it is half way there. Making 1.5 into 2 and -1.5 into -2.

...049999 isn't "half-way there". it's below 0.5, so php rounds down.

PHP wrong round precision

i guess the code is working fine, but the result you are looking for is different, if you wanna round a number to hundredths, you have to take the third decimal on the number, for example: 53.974

So, the new number it's going to be 53.97 because the third decimal doesnt allow you to aproximate the number to 53.98

take a look

If you want to do something like:
the decimal n approximates the decimal n-1 and so on.

you can try something like this

`

$test = 53.974999994;

function round_with_n_decimals($number, $decimals, $decimals_to_count){
while($decimals_to_count >= $decimals){
$number = round($number, $decimals_to_count);
$decimals_to_count--;
}
return $number;
}

echo round_with_n_decimals($test, 2, 3);

`

PHP 7.0 - rounding and/or casting float to int gives incorrect values

The best answer you'll find to your question is that computers don't handle floats all that well. Internally, the number 72.57 is actually figured to 72.569999999999999999999, which in most cases will calculate okay, but will cause you to run into exactly what you ran into, where if you multiply by 100 (7256.999999999999) then use FLOOR, you get 7256.

There are entire articles on the problems computers have with handling floats, but the best solution when accuracy is important is to avoid the use of numbers to the right of the decimal point, where possible.

This article talks about the issue in Python, but it applies to all languages: https://www.geeksforgeeks.org/floating-point-error-in-python/#:~:text=It's%20a%20problem%20caused%20when,leads%20to%20small%20roundoff%20errors.



Related Topics



Leave a reply



Submit