I'm trying to calculate a tax or discount value using BCMATH in PHP. I need 2 DECIMAL PLACES. Here's how i'm doing it:
bcscale(2);
$price = '60.67';
$discount = bcmul(bcdiv($price, 100), '3.8'); // calculate 3.8 percent from 60.67
// result is: 2.28
// result should be: 2.31
I could simply increase the scale to 4 or something like that and that would now give me a correct result.
So the question is: how should i do this correctly? Should i set the scale to 4 and then sprintf('%0.2f', $discount) in the end? Or is there a better way of doing this?
Bypass bcmath?
$discount = round( ($price / 100) * 3.8, 2);
// 2.31
Related
I have a simple code in php and would like to add 3% on bitcoin value:
</PHP
$price = "0.00001000"
$price_format = str_replace(".", "", $price);
echo ($price_format + ($price_format / 100 * 3)); // 1030
?>
Return of my code:
1030
I need the return to be:
0.0001030
Does anyone know how I can perform this calculation by following the number of houses of the price?
You can use number_format when you multiply on the 3 percent to keep decimal places intact. Multiply price by 1.03 (3%) and specify 8 decimal places.
<?php
$price = 0.00001000;
$new_price = number_format($price * 1.03, 8);
echo $new_price;
Here's a link to number_format for more info:
https://www.php.net/manual/en/function.number-format.php
When I need to add a percentage to a price in order to increase it by a certain percentage I have this formula $price * (1 + $percent / 100) which is somewhat limiting.
For example if I wanted to increase the price by 200% or 300% I'd need to create a complex code to detect if its a 3 decimal number. And then extract the first number and replace the 1 like this (2 + $percent / 100).
Is there a more elegant way to increase a price by a certain percentage?
This is my way to do:
$price = $price + ($price * $percent / 100)
Works simple, calculate te percent of the price ($price * $percent / 100) and then sums that to the initial price.
This should work on every case
$price = $price + ($percentage / 100 ) * $price
But your formula is working with 200 or 300 without problem
I've got a significant problem in working out the percentage tax applied to a product, due to the rounding.
For example:
If you have a product which is £1.00 including 20% tax the break down would be:
0.83 ex tax
0.17 tax
1.00 total
However, if you work out the percentage increase:
round( (( ( 1 - 0.83 ) / 0.83 ) * 100), 2);
The answer is 20.48, because the actual price ex VAT is 0.8333333333
Therefore if you calculate:
round( (( ( 1 - 0.8333333333 ) /0.8333333333 ) * 100), 2);
You get the correct answer of 20.
In this case it would obviously work to round the 20.48 down to 20, but thats not a solution because some tax rates are to 2 decimal places so the assumption can't be made that you can just round the tax rate.
Am I missing something or is this impossible without knowing the original tax percentage?
0.17 is not 20% of 0.83, so your basic assumption is inaccurate( is rounded :P ).
Don't round money, calculate it without all that rounding and display rounded if need be. That avoids having to loose the precision in calculations.
A simple test will demonstrate
$price=0.8333333333;
$taxRate=21.25;
$tax=$price*$taxRate/100;
$total=$price+$tax;
$calculatedTaxRate=(($total-$price)/$price)*100; // 21.25
Since we didn't round anywhere, we can reverse engineer the tax rate always down to the dot.
Try with 20%
$price=0.8333333333;
$taxRate=20;
$tax=$price*$taxRate/100;
$total=$price+$tax;
$calculatedTaxRate=(($total-$price)/$price)*100; // 20
Wouldn't it something like:
17% VAT
85.47 taxless
85.47x0.17 = 14.53
Total: 100
So 100/1.17 = 85.47
My little-and-dirty version:
$taxrate=22; // 22%
$price=100;
$priceMinusTax=($price/(($taxrate/100)+1));
As long as you are dealing with low precision numbers, you will get a low precision answer. If you must show low precision numbers, you can round them when you show them to the user in the view, but save them as high precision numbers in the database.
Assuming your total price is £1 and tax rate is 20%:
$vatDecimal = (float) 1 + (20 / 100);
$priceExclVAT = round((1.00 / $vatDecimal), 2);
$priceDisplay = number_format($priceExclVAT, 2, ',', '.');
echo $priceDisplay;
The user enters the total amount and tax. Sometime its come form database, we can also use this code.
$actualPrice = "";
$total = 1000;//User Entry Total Amount
$gst = 18;//User Entry GST Tax %
$calculateTax = 100+$gst;
$calculateAmount = $total*100;
$actualPrice = $calculateAmount/$calculateTax;
echo $actualPrice = round($actualPrice,2);
echo $gstAmount = round($total-$actualPrice,2);
Im trying to make a calculation with the following values:
Product cost (without VAT) = 12,40 ($product)
The VAT percentage = 21%, what I will store in the database as 0,21 ($vat_perc)
The VAT is 2,604 ($vat)
edit: The VAT is per product
When I try to get the total then I get 15,00 ($total)
What I did is the following:
$total = $product + $vat
This will echo 15.004
Then I use the number_format:
echo(number_format($total,2,',','.'));
This will print 15.00
But then I want to multiply the product with 2
So that will give the following calculation:
$total = $product * 2 + $vat
Then again I use the format:
echo(number_format($total,2,',','.'));
Then the total = 30,01
I tried serveral things like ROUND en INT, but with no succes.
What am I doing wrong in this? In know that the VAT is the evil one here but I have no idea how to fix this.
$tax = round( ($price / 100) * 3.8, 2);
tax is rounded price divided by the 100 to make a clear percentage. Multiplied by the wanted stack
then you do the addition to or from your price table.
Well good to have you on the phone - maybe we can solve this faster by phone. Thank god for phones!
Cheers mate!
Here are some examples of how the numbers are rounded with PHP functions.
$product = 12.40;
$vat = 2.644;
$total = ( $product + $vat ) * 2;
var_dump( $total ); // float(30.088)
var_dump( number_format($total,2,',','.') ); // string(5) "30,09", rounded
var_dump( round( $total, 2 ) ); // float(30.09), rounded
var_dump( sprintf('%0.2f', $total ) ); // string(5) "30.09", rounded
var_dump( floor( $total * 100 ) / 100 ); // float(30.08), not rounded
All three founctions ( number_format, round, sprintf ) will round the result, to avoid the rounding and discard the decimal part after two decimal points you can use the last example.
Your initial total is 15.004 so when you call number_format that gets rounded down to 15.00. Now when you multiply by 2 your total is 15.008 which number_format will round up to 15.01. The issue isn't with the addition it is with the multiplication by 2. number_format rounds to the nearest place which for your case would be 30.01.
If you want the number to be rounded down all the time use floor, like so:
$total = floor(($product * 200)) / 100 + $vat;
echo(number_format($total,2,',','.'));
I have a project that stores money as bigint column in a database (storing in cents). I'm planning to rewrite this thing to use BCMATH instead. I don't mind integers, but they give me some terrible rounding errors event stored in cents and I suspect I might have the same rounding errors in BCMATH. The problem arises in situations, like in this pseudocode:
$price = $some_price_in_cents * $store_price_increase; // second value is a float for final price calculation, so the result might have fractions of a cent
$price_total = $price * $qty;
$discount = // some discount in cents (might have fractions of a cent)
$discount *= $qty;
$discounted_price = $price_total - $discount;
When inserting into a database, I do round() on all values in cents. And now I have a record which says:
total price = 12134
discount = 460
discounted price = 11675
Now if I do 12134 - 460 ... I obviously get 11674 and not 11675.
I also suspect that if I changed the way things are calculated (eg. multiply everything by the QTY at the end), I'd get even different results.
Would I get this kind of behaviour using BCMATH? Would the result depend on the order of math operations? How would I properly calculate the above using BCMATH and store it in DB (assuming 2 decimal places are required)?
I believe this is what you need. Note that bcmath requires strings. The number 2 is to specify how many decimals you need.
$price = bcmul($some_price_in_cents, $store_price_increase, 2);
$price_total = bcmul($price, $qty, 2);
$discount = bcmul($qty, "discount amount", 2);
$discounted_price = bcsub($price_total, $discount, 2);