Floating points return wierd value [duplicate] - php

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Practices to limit floating point accuracy problems
When I am adding a list of new totalSubs to a running total, PHP returns a weird value.
I have generated the below output (see line 40):
1 The total currently '0' (integer) + new TotalSub '-26969.55' type(double) = total '-26969.55'
2 The total currently '-26969.55' (double) + new TotalSub '249.6' type(double) = total '-26730.05'
...
39 The total currently '-164.89' (double) + new TotalSub '61.95' type(double) = total '-112.94'
40 The total currently '-102.94' (double) + new TotalSub '98.71' type(double) = total '-5.3300000000009'
41 The total currently '-5.3300000000009' (double) + new TotalSub '50' type(double) = total '45.769999999999'
The PHP generating is:
echo ($count++) . " The total currently '$totalTrans' (".gettype($totalTrans).") + new TotalSub '$totalVar' type(".gettype($totalVar).") = total '" . ($totalTrans + $totalVar) ."'<br />";
How can I fix the 00000000009?

From what I can see.
Try multiplying the input data by 100 and then dividing the totals by 100 at the end.
Multiplting by 1 or 10 will most likely not correct it which might be due to the 2 decimals and by using 100 the values are now whole numbers (ints)
Remember floating-point data types (such as DOUBLE) do not represent exact numbers and are approximate.
You could use bcmath() for maths calculations in the future as using number_format() is no different than using round() without returning it as a string.
http://php.net/manual/en/book.bc.php

Use printf to solve that problem and make your code presentable at the same time:
printf("%d The total currently '%.2f' (%s) + new TotalSub '%.2f' (%s) = total (%.2f)<br />",
$count++,
$totalTrans,
gettype($totalTrans),
$totalVal,
gettype($totalVar),
$totalTrans + $totalVar);

Related

Shopping cart calculating total

Good day, below is a piece of code that increments the total cost for each product in the session array. My problem is displaying 0 at the end of the total when the last peny = 0.
Example 1, 2.20 + 2.20 = 4.40 but only 4.4 is shown
Example 2, 2.20 + 2.25 = 4.45 and 4.45 is shown
$total = 0;
if (isset($_SESSION['cartItems'])){
foreach ($_SESSION['cartItems'] as $product){
$total += $product['cost'];
}
}
echo $total;
Any advice on how to show/include when a 0 is entered?
This was already answered in a comment by WebCode.ie but here is a detailed answer that may help those facing the same problem:
To customize a number format, you can use the PHP Function string number_format() , that accepts either one, two, or four parameters, this way:
$my_number=25200;
$number_decimals=2;
$dec_separator=".";
$thousands_separator=" ";
echo number_format($my_number , $number_decimals, $dec_separator, $thousands_separator);
// This will output 25 200.00
The number you want to format
The number of decimals
The decimal separator
The thousands separator
Please also note that you can only use 1, 2 or 4 parameters.

Calculate a given number to a percentage between two given numbers [duplicate]

This question already has answers here:
Negative & Positive Percentage Calculation
(6 answers)
Closed 1 year ago.
I'm trying to work out a percentage between two numbers by providing the number of which the percentage should be based (can't find this on Stack overflow - only percentage between two numbers).
Let me explain:
$start_number = 14700
$end_number = 14900
// This is the number to calculate a percentage for
// in this basic example this should come to 50%
$percentage_number = 14800
I know what I need to do but can't figure out how to write it:
Where $start_number is 0%
And $end_number is 100%
$percentage_number = X%
$difference = $end_number - $start_number; // 200
$difference_from_start = $end_number - $percentage_number; // 100
$percentage = $difference_from_start / $difference; // 0.5 (50%)
Is it what you want?
Well this is quite simple:
$start_number = 14700;
$end_number = 14900;
$percentage_number = 14800;
$result = (($end_number - $percentage_number) * 100) / ($end_number - $start_number);
echo $result;
OUTPUT:
50
I thik that the solution formula would be:
percentage = 100 * (percentage_number - start_number) / (end_number - start_number)
In that case $percentage_number should not be less than $start_number else the percentage will calculated in negative.
You can use the below formula:
( ($percentage_number - $start_number) / ($end_number - $start_number) ) * 100 ;
Hope it'ill help you.
Let's say you have two numbers, 40 and 30.
30/40*100 = 75.
So 30 is 75% of 40.
40/30*100 = 133.
So 40 is 133% of 30.
The percentage increase from 30 to 40 is:
(40-30)/30 * 100 = 33%
The percentage decrease from 40 to 30 is:
(40-30)/40 * 100 = 25%.
These calculations hold true whatever your two numbers.
In PHP
$oldFigure = 14;
$newFigure = 12.50;
$percentChange = (1 - $oldFigure / $newFigure) * 100;
echo $percentChange;
diff = $end_number - $start_number
(diff is now = 200)
mid = $end_number - (your number)
(mid is now = 100)
res = (mid / diff) * 100
(res is now = 50%)
If the scale begins at $start_number and ends at $end_number, its size is $end_number-$start_number. If $percentage_number is in the scale, it's $percentage_number-$start_number units from the start into the scale. Therefore, the relative ratio in the scale being:
($percentage_number-$start_number)/($end_number-$start_number)
Multiply by 100 and you'll get the percentage.

PHP rounding issue

I am getting a rounding issues, I have a database of 3 charities with different amounts.. then in the front I have the 3 charities displaying there percentage based on the amount assigned to them and the total percentage always needs to add to 100%.. currently if each charity has 1 assigned to it, it displays 33% on each which equals 99% where i need to cheat it in a way to always be equal to 100%..
Here is the PHP
$charity = $_POST['charity'];
$sql = "SELECT amount FROM charities";
$result = mysqli_query($con, $sql);
while($row = mysqli_fetch_array($result)) {
$total += $row['amount'];
}
$sql_individual = "SELECT * FROM charities WHERE charity='$charity'";
$result_individual = mysqli_query($con, $sql_individual);
while($row = mysqli_fetch_array($result_individual)) {
$charity = $row['amount'];
}
echo round($charity / $total * 100,0) . "%";
I found a maths solution for this.. but.. my maths isn't all that great.. but.. okay in all honesty i do not understand this fully:
c = 100 - (a + b) - e,g 34 = 100 - (33 + 33)
any Help Greatly Appreciated..
There are no rounding issues, You just round to an integer numbers, that means that if You have 5 values like these:
12,25%
13,25%
20,25%
30,25%
34,00%
after using round($x, 0) on them they will be rounded to these values:
12
13
20
30
34
After summing these rounded values You get the value of 99.
It is best to round at least to two decimal places when working with percentages - and only for displaying purposes. You shouldn't round any values that will be used for further math operation...

Voting percentage calculation error [duplicate]

This question already has answers here:
How to deal with the sum of rounded percentage not being 100?
(5 answers)
Closed 9 years ago.
I have created a php program where user can can vote on polls and after that, the poll result will displayed with only percentage, however I am facing an error in my program. Code which I am using for percentage calculation is <?php echo round(($num_votes / $total_votes) * 100) ?>
Now If we talk about a sample poll result, assume we have five options
option A - 4 votes
option B - 2 votes
option C - 4 votes
option D - 1 votes
option E - 0 votes
Total votes = 11
In this scenario the percentage result generating is
option A - 36%
option B - 18%
option C - 36%
option D - 9%
option E - 0%But the total of percentage is 99% instead of 100%. What I want is total should always be 100% Any help would be appreciated
Thanks.
If you are working with rounded numbers, you can indeed end up with...rounded numbers. And the sum of those rounded numbers will be different from the regular sum. There's little you can do to change that. If you insist, you'd have to:
calculate the rounded numbers
calculate the sum, and if not 100%,
loop through the rounded numbers and decide which one should get the missing percent.
But you're messing with the data. You may think you're cleaning it, but you're messing it up.
This way lead to ~100%, 'number_format' is nice thing
$a = 4;
$b = 2;
$c = 4;
$d = 1;
$e = 0;
$total = $a + $b + $c + $d + $e;
$arr = array(
'a' => number_format(($a / $total) * 100, 3),
'b' => number_format(($b / $total) * 100, 3),
'c' => number_format(($c / $total) * 100, 3),
'd' => number_format(($d / $total) * 100, 3),
'e' => number_format(($e / $total) * 100, 3)
);
foreach ($arr as $answer => $percentage) {
echo $answer .': '. $percentage . '<br />';
}
// this will be 100.001 so we format is
echo 'total: '. number_format(array_sum($arr), 2);
You can specify number of digits after decimal places in round.
ex:round(number,2);
There's nothing out-of-the-box you can do about it, if you floor() everything you'll miss one point, if you ceil() you'll gain one point.
You could floor() everything then if then calculate the array_sum(), if not 100 then find min() and ceil() it.

Weird calculation in PHP [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is JavaScript's Math broken?
Adding fractions number yields different result in PHP
$grand_total = (float)$subtotal_email + (float)$delivery_email + (float)$fuel_surcharge_email - (float)$discount_coupon_email + (float)$texas_tax_email - (float)$cancel_fee_email - (float)$refund_email - (float)$refund_tax_email - (float)$coupon_tmp;
echo (float)$subtotal_email." + ".(float)$delivery_email." + ".(float)$fuel_surcharge_email." - ".(float)$discount_coupon_email." + ".(float)$texas_tax_email." - ".(float)$cancel_fee_email." - ".(float)$refund_email." - ".(float)$refund_tax_email." - ".(float)$coupon_tmp." = ".(float)$grand_total;
When I run the above in php, I get the following output:
89.99 + 0 + 16.2 - 0 + 8.61 - 3 - 100 - 10 - 1.8 = -2.88657986403E-15
But if you look at LHS, it should be 0, and this happens with or without float....any idea why?
Floating point arithmetic is never that accurate. If you need to compare to zero, you need to take the different and compare it to some small number.
if (abs($result) < 0.00001)) {
// it's zero
} else {
}
Because float. Use ints and calculate the value with cents (* 100).

Categories