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
Convert PHP Array String into an Array
Need Response Body of Http 500 with File_Get_Contents (Php)
Submit Multiple Forms with One Button
Getting Warning "Header May Not Contain More Than a Single Header, New Line Detected"
Display an Array in a Readable/Hierarchical Format
Replacing Spaces with Underscores
Laravel Middleware Return Variable to Controller
How to Use PHP to Connect to SQL Server
How to Fix 'Creating Default Object from Empty Value' Warning in PHP
Populate Select Drop Down from a Database Table
Fatal Error: Call to a Member Function Prepare() on a Non-Object In