views:

301

answers:

6

Hi,

I'm building a webapp using JQuery, Stripes, Spring and JPA (Hibernate).

I have a page that allows users to enter a number of order line items and each time onblur occurs in the price field, I have a JQuery event bound to the field which sums all the price fields (this is a subtotal), calculates 10% tax and adds the tax to the subtotal. I update the page to display the subtotal, tax and grand total.

My question is, should I be doing this calculation in Javascript? If so, how can I be sure the rounding etc is working correctly? I'm a bit worried about problems with precision.

Would it be better for me to make an Ajax call to do the calculation in Java?

Any advice would be great!

A: 

Javascript isn't the best language to do math with. You'll find some math expressions that are true but return false in Javascript. Can't remember them exactly but I found out when I did a calculator once.

You can find out about the good and bad parts of Javascript here: http://www.crockford.com/

Rimian
It's not really anything special about JavaScript. Any language that uses IEEE 754 floating point numbers (just about everything) has the same issues.
Matthew Crumley
+1  A: 

you should do it on the client side (I assume you have your client side validators in place) so that the user can see the total (I would hate if we make round trip calls to server to just see the total) and also do it on the server side .Reading off of the values from POST would not be a very good idea as someone with a HTTPProxy could change these values if you are picking it up from your HTTP POST.

TamperIE a tool to tamper with HTTP GET and POST and a sandbox where you can play around with

Edit: Yes, you can do the calculation in the server by making an AJAX call, but you would need to validate the total anyways (against the number of products + tax) when the user submits the order

ram
+7  A: 

As a rule of thumb, you need to measure what's important for your application. If it's absolute precision then do it as an AJAX call because there may be rounding differences between browsers, computers and OS.

When I was developing a site for a company I was working for I had the same problem, however we manage to use the javascript part by using a clever twist by using only integer arithmetics.

Because we were dealing with currency with two digits, we multiplied everything by 10,000 and did the calculations. Rounding up to the integer and divided by 10,000 truncating the result to two decimal places.

That make the round-trips nicely and consistently between the browser and the server side.

Paulo Santos
+ 1 from me Paulo. I did not know that JS had precision issues with arithmetic calculations
ram
Ram, ECMAScript uses fast, but imprecise, float calculations. So for instance, `.1 + .2 = 0.30000000000000004`. Even ECMAScript 5 will have these problems, because the proposed precision system was deemed too problematic (very slow and might break existing applications) for the standard. It'll be another couple years before a precise system is even standardized, let alone available.
eyelidlessness
Just about to give the same advice!
James Anderson
I remember an article called "Why computers suck at Math?" ( http://tinyurl.com/yhnl6xw )
Paulo Santos
+1  A: 

If you're accepting orders, I would recommend that you always do the calculations on the server side before confirming the order to avoid someone maliciously tampering with data being sent from the client. That said, you could do the dynamic updating using JavaScript with some suitably worded disclaimer around the accuracy and then present the user with your server-side calculation before they confirm the order.

mopoke
+4  A: 

Per the comp.lang.javascript FAQ, Javascript uses IEEE-754 and so it has a precision of 15-16 digits when doing floating point math. This should be enough for monetary operations, provided that you use the same rounding in Javascript that you do on the server side.

But if you need to be absolutely sure that it's correct on any and all browsers, an Ajax call would be the safest course of action.

Kaleb Brasee
A: 

You should be using the back-end, in your case being Java, to do your strict calculations for there is no guarantee that the data won't be tampered by the end-user to their benefit. And once you have sent them a confirmation of the tampered price, you are in essence bound by the terms of your purchase contract, even if you know they've tampered with the total price. There's no easy way you can prove they've tampered with your code or calculations, and in-turn will be at a loss. Use the back-end, you've got full control of that environment, any bugs or miscalculations from that angle can be blamed squarely on you.

Michael Mad