I’m building a small JavaScript calculator where the user enters a tax-inclusive price and a tax rate, and the script needs to calculate the original price before tax.
For example:
Total: $214.00 Tax rate: 7%
The expected result is:
Original price: $200.00 Tax: $14.00
I’m using:
const originalPrice = total / (1 + taxRate / 100);
const taxAmount = total - originalPrice;
The calculation itself seems straightforward, but I’m running into questions about floating-point precision and rounding. I want the displayed values to always be accurate to two decimal places without introducing small differences in the tax amount.
Would you recommend rounding the original price first and then calculating the tax, or keeping full precision until the final output? Also, is there a better JavaScript approach for handling currency calculations?
I use something like this for my currency display.
let amountInINR = (amount) =>
{
return new Intl.NumberFormat("en-IN", {
style: "currency",
currency: "INR",
notation: "compact",
compactDisplay: "long"
}).format(amount);
}
Calculations are done before display though.
const formatter = new Intl.NumberFormat('en', { minimumFractionDigits: 0, maximumFractionDigits: 2 });
INR = formatter.format(amount / INR_THOUSAND, 2) + ' ' + ext;
4 yrs ago : https://alpinejs.in/show-amount-of-money-in-indian-rupees-as-k-lakhs-crores
It’s not my area of expertise, but the issue the OP is talking about I think relates to floating point issues e.g. .1 + .2 === .300000004 (something not limited to JS, but more to do with binary code AFAIK)
The one solution that is generally banded about is to multiply out the decimal places by a number and then divide by that number
e.g. (.1 * 100 + .2 * 100) / 100 = .3
I seem to remember Douglas Crockford goes into great detail about this in his ‘How Javascript Works’ book.
My understanding is that in the UK, value added tax (VAT) when added to a price exclusive of VAT should by law be rounded down to the nearest £0.01. So for example £12.10 inclusive of VAT at 20% would mean a VAT-exclusive price of £10.09 and £2.01 VAT (assuming the VAT-exclusive price does not include more than 2 decimal places). So you would need a calculation that rounds the VAT down to nearest £0.01 before working out the original price.
This, for the record, introduces values for which the original value cannot be determined. Your example was of 12.10 inclusive of price, resulting in a 10.09 pre-VAT price. However, it’s mathematically impossible to start with 12.11 and get to an original price, because 10.10 pre-VAT would result in 12.12 being the final price, and 10.09 results in 12.10. The flooring ‘skips’ certain values.
1 Like
The formula you’re using is the right approach for reversing an inclusive tax:
originalPrice = total / (1 + taxRate / 100)
I’d keep the full precision during the calculation and round only when displaying the final currency values. Rounding originalPrice first can sometimes create a one-cent mismatch between the displayed subtotal and tax.
For example, with $214 at 7%, the unrounded calculation gives $200, and the tax is $14.
For a small calculator, storing amounts as integer cents can also help avoid JavaScript floating-point surprises. For more complex financial calculations, a decimal/currency library is worth considering.
But is it?
I’m going to take you at your precise words, and that you’re ROUNDing, not FLOORing. (Note that this doesnt eliminate the problem i’m about to illustrate, it simply changes the point at which it occurs in the numbers)
What if i told you my end price was $214.23 at 7%?
The formula says my original price is $200.21.
If I take $200.21, reverse the formula and add 7% tax onto it, I get… $214.22.
That’s not the value I gave you.
This is where rounding errors come in.
1 Like