array_sum PHP wrong result [duplicate] - php

This question already has answers here:
Why does floating-point arithmetic not give exact results when adding decimal fractions?
(31 answers)
Closed 3 years ago.
the result of this should be zero!
echo array_sum([-61.50,50.00,10.50,1.00,0.00,50.00,-16.73,-20.00,-55.75,42.48]);
Why is giving -7.105427357601E-15?

Just try round(), you will get the same result.
echo round(array_sum([-61.50,50.00,10.50,1.00,0.00,50.00,-16.73,-20.00,-55.75,42.48]));

Because floating point values (which you have here when you use decimals) are not exact. They're approximations.
The error in that approximation comes out to -7.105427357601E-15 when summing these values.

It's because of floats. If you want to calculate something with precision 2 (for this example) you should use something like this:
$el = [-61.50,50.00,10.50,1.00,0.00,50.00,-16.73,-20.00,-55.75,42.48];
$sum = 0;
foreach ($el as $e) {
$sum += $e * 100;
}
echo $sum / 100;
You should never trust to float values. Another example from Javascript (Google developer Console):

Related

Why is < less than condition hitting when values are the same? [duplicate]

This question already has answers here:
Comparing floats - same number, but does not equal? [duplicate]
(3 answers)
Is floating point math broken?
(31 answers)
Closed 2 months ago.
dump($available_funds);
dump($meal_price);
if ($available_funds < $meal_price) {
dd('hit');
return false;
}
$available_funds and $meal_price are both 'double' values set to 2.78
Why would the if statement be hit when the values are the same?
I have attempted to (float) the variables and floatval() to try and update the types to see if this would resolve the condition but had no luck.
The problem may be due to the precision of the double data type. double values can have up to 15 decimal digits of precision, but in some cases, the actual value stored may not have the same precision as the declared type. This can cause problems when comparing double values, as the values may not be exactly equal even if they appear to be the same.
One solution to this problem is to use the round() function to round the values to a specific number of decimal places before comparing them. For example, you could use the following code to compare the values with two decimal places of precision:
$available_funds = round($available_funds, 2);
$meal_price = round($meal_price, 2);
if ($available_funds < $meal_price) {
dd('hit');
return false;
}

PHP show one decimal place issue [duplicate]

This question already has answers here:
Delete digits after two decimal points, without rounding the value
(15 answers)
Closed 3 years ago.
I'm trying to show one decimal place for rating number I have
but it returns unexpected value.
I used number_format and the round functions and both have the same issue, or i'm doing something wrong.
I tried to make this number show one decimal number
4.96 and it always returns 5 instead of 4.9
number_format(4.96, 1)
round(4.96, 1)
round(4.96, 1,PHP_ROUND_HALF_DOWN)
both functions returns 5 instead of 4.9
I searched all answers but couldn't find anything helpful.
Rounding 4.96 will round .9 up, so it will be 5 in all cases. If you want to do it without rounding, you may have to tweak it a bit to fool it:
floor(4.96 * 10) / 10; // 4.9
Here's a function you can use to achieve this.
function convertToSingleDecimal($num, $precision = 2) {
return floor($num) . substr(str_replace(floor($num), '', $num), 0, $precision + 1);
}
print convertToSingleDecimal("4.96", 1);

Round number down the to the nearest hundredth using php [duplicate]

This question already has answers here:
How to round up a number to nearest 10?
(16 answers)
Closed 4 years ago.
I'm probably not looking hard enough but the common question about php rounding is rounding up, not down.
For example I am trying round this..
<?php $roundDown = 768; ?>
Down to..
<?php var_dump($roundDown) /* 700 */ ?>
Whats the simplest method to do this, or is it because the number is closer to 800 that it's not technically rounding?
Whats the function that I need to do this if it's not rounding?
A little point in the right direction would be much appreciated.
You can try ceil() and floor() function.
echo floor(768 / 100) * 100; // Output:700
echo ceil(768 / 100) * 100; // Output:800

PHP function 'pow' weird result [duplicate]

This question already has answers here:
Compare floats in php
(17 answers)
Closed 7 years ago.
I was working on a code and I could not understand the weird result I was getting.
<?php
$a = 0.01;
$p = pow(0.1, 2); // result: 0.01
if( $a < $p ){
echo "true";
}
?>
The result of this condition is always "true" while both of the variables have same value, but the result coming from pow is changing something internally. Seems like I would not be able to rely on this function. Would someone please help me figuring this out ?
its because of float inaccuracy,
take a look at answered question mentioned in comment by b0s3
Read the red warning first
http://www.php.net/manual/en/language.types.float.php. You must never
compare floats for equality. You should use the epsilon technique.
For example:
if (abs($a-$b) < EPSILON) { … } where EPSILON is constant representing
a very small number (you have to define it)
https://stackoverflow.com/a/3149007/4998045
so you can trust pow function but you cant trust float comparsion
PHP Docs said:
base raised to the power of exp. If both arguments are non-negative integers and the result can be represented as an integer, the result will be returned with integer type, otherwise it will be returned as a float.
Maybe you need to convert all to int or all to float.
if( (float)$a < (float)$p ){
echo "true";
}
See it run:
http://phpfiddle.org/main/code/2hv5-n2fw

PHP floating point multiplication and comparison issue [duplicate]

This question already has answers here:
Why does floating-point arithmetic not give exact results when adding decimal fractions?
(31 answers)
Closed 3 years ago.
I have a simple comparison in my code:
[simplified]
if (1.7 >= 17 * 0.1) {
echo '1.7 is greater than or equal to ' . 17 * 0.1;
} else {
echo '1.7 is NOT greater than or equal to ' . 17 * 0.1;
}
It gives the result:
1.7 is NOT greater than or equal to 1.7
I wonder can anybody explain this?
This is because native operator are indeed interpreted in base 2, and most base 10 decimal converts badly in base 2.
If you need precision, you need to either only manipulate integers (converts perfectly to base 2) or use a dedicated lib such as bcmath (I wrote a wrapper to ease bcmath usage Math)

Categories