This question already has answers here:
Is floating point math broken?
(31 answers)
PHP - Floating Number Precision [duplicate]
(8 answers)
Closed 4 years ago.
In one of my wordpress theme function, this code is being used to calculate total billable amount: ceil(($cost * (1 + ($charges / 100))) * 100);
There is a little miscalculation happening for below scenario.
Scenario:
$charges = 9;
$cost = 100;
echo ceil(($cost * (1 + ($charges / 100))) * 100);
The above code outputs 10901 whereas it should be 10900.
It works fine for other scenarios like:
$charges = 4;
$cost = 90.7;
echo ceil(($cost * (1 + ($charges / 100))) * 100);
//outputs 9433, which is fine because manual calculation results 9432.8
Question:
Why is that happening?
How can I prevent that?
Any alternate function to round to next nearest integer? (only if amount is floating value)
The problem is that you are applying ceil to the outer expression. Try to rewrite it as:
$charges = 9;
$cost = 100;
echo ($cost + ceil($cost * $charges / 100)) * 100;
This outputs 10900 as expected.
UPDATE
As #cars10m suggested, simplifying the expression does help:
echo ceil($cost * 100 + $cost * $charges);
UPDATE 2
You can also use BCMath library to do precise math:
bcscale(6);
echo ceil(bcadd(bcmul($cost, 100), bcmul($cost, $charges)));
Related
This question already has answers here:
Convert a string containing a number in scientific notation to a double in PHP
(8 answers)
Closed 1 year ago.
I want to trim my decimal into something like 8.063 instead of the original which is 8.0638304611694E-9. I have implemented a function for it but it doesn't work when there is E-9 in it. Which part should I modify??
public function setPrecision($number, $decimals = 0)
{
$negation = ($number < 0) ? (-1) : 1;
$coefficient = 10 ** $decimals;
return $negation * floor((string)(abs($number) * $coefficient)) / $coefficient;
}
EDIT
The current implementation gave me 0 when I try to call the function.
setPrecision(8.0638304611694E-9, 3); // 0
In PHP, there are (at the moment of writing) 8519 builtin functions. One of them probably does the trick!
You could use log10() and round() in your function:
function setPrecision($number, $precision = 0)
{
$exponent = floor(log10($number)) - 1;
return round($number, -$exponent + $precision - 1);
}
Relative rounding with a certain number of digits can easily be done with sprintf.
$round = (float)sprintf('%0.3E', 8.0638304611694E-9);
var_dump($round); //float(8.064E-9)
On this basis I have this function which rounds float values with a certain relative decimal precision.
/*
* #return Float-Value with reduced precision
* #param $floatValue: input (float)
* #param $overallPrecision: 1..20 (default 10)
*/
function roundPrecision($floatValue, $overallPrecision = 10)
{
$p = min(20,max(0,$overallPrecision-1));
$f =(float)sprintf('%.'.$p.'e',$floatValue);
return $f;
}
example 1
$float = 0.0000123456789;
$newFloat = roundPrecision($float,5);
printf('%0.10f',$newFloat); //0.0000123460
example 2
$float = 3456.7891234;
$newFloat = roundPrecision($float,5);
printf('%0.10f',$newFloat); //3456.8000000000
This question already has answers here:
Show a number to two decimal places
(25 answers)
Closed 2 years ago.
I have a problem with a ceil of a number.
The number is calculated like this. (The actual values comes from other places, this is just to show what is happening. The values in the example are correct to what's happening in the application)
$price = 400;
$multiPlierA = 1;
$multiPlierB = 1.1;
ceil($price * $multiPlierA * $multiPlierB);
which should give me 440. But since $price * $multiPlierA * $multiPlierB ends up being 440.00000000000006 it will of course ceil it to 441. That little floating 6 at the end comes from lovely complementary php magic.
Is there a simple way to get get php to just do this calculation using the first two decimals? I want to trim this off before ceiling 440.00[000000000006....]
You can use number format before ceiling. https://www.php.net/manual/en/function.number-format.php
$price = 400;
$multiPlierA = 1;
$multiPlierB = 1.1;
$result = number_format($price * $multiPlierA * $multiPlierB, 2, '.', '');
ceil($result);
This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 3 years ago.
$amount = (256.34 * 100);
echo (int) ($dollor_amount);
// out should be 25634 but this giving 25633, not sure why?
$amount = (255.34 * 100);
echo (int) ($dollor_amount);
// For 255.34 it returning fine output 25534
is there any limit issue? it behaving unexpected only after 256 number.
Used float instead of int. you will get your desired result as par your question.
$amount = (256.34 * 100);
echo (float) ($amount);
// out should be 25634 but this giving 25633, not sure why?
$amount = (255.34 * 100);
echo (float) ($amount);
This question already has answers here:
How do I format a number to a dollar amount in PHP
(7 answers)
Closed 9 years ago.
I am using the following code to add VAT (20%) on to prices.
$VATrate = 20;
echo($row_products['price'] *= (1 + $VATrate / 100));
This works well except for when the price has a zero on the end - for example I have an item with ex. VAT price of £249 with VAT added the price is £298.80 - the problem is that the output of that is £249.8 and therefore missing the zero - I don't want to go and add a zero to everything as some prices are £29.95 so do not need a zero on the end.
Is it possible to do this? I hope the question makes sense.
You can use the formatting capabilities of printf()...
$VATrate = 20;
$total_price = $row_products['price'] *= (1 + $VATrate / 100);
printf("%.2f", $total_price);
This should be what your looking for :)
$number = ($row_products['price'] *= (1 + $VATrate / 100);
$price = number_format($number, 2, '.', '');
echo $price;
number_format((float)$number, 2, '.', '');
This question already has answers here:
Print numeric values to two decimal places
(6 answers)
Closed 11 months ago.
Lets say I divide 14 / 15 times it by 100 to get the percentage which is 93.33333333333333 how can I display it as 93.3% using php?
Here is the code.
$percent = ($avg / 15) * 100;
The sprintf function is made for this (see also the manual):
echo sprintf('%.1f%%', $percent);
PHP has a number_format function which lets you specify the number of decimals, what to use for the decimal separator, and what to use for the thousands separator:
$percent = ($avg / 15) * 100;
echo number_format($percent, 1) . '%'; // => 93.3%