最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

floating point precision - Can javascript be trusted when making calculations? - Stack Overflow

programmeradmin1浏览0评论

I am implementing an invoice system, where everything is dynamically added on the dom through javascript and I am making some calculations on the browser itself with javascript. for eg I am calculating each invoice line with quantity and price of unit and generating a total sum

price can be a floating point number

but I am not sure if this should be trusted or not, if someone has the same toughts about javascript please ment :)

I don't know but javascript doesn't seem to me to be trusted like other programming languages like PHP or so, this is my opinion, but if you can convince me please do

Thanks

I am implementing an invoice system, where everything is dynamically added on the dom through javascript and I am making some calculations on the browser itself with javascript. for eg I am calculating each invoice line with quantity and price of unit and generating a total sum

price can be a floating point number

but I am not sure if this should be trusted or not, if someone has the same toughts about javascript please ment :)

I don't know but javascript doesn't seem to me to be trusted like other programming languages like PHP or so, this is my opinion, but if you can convince me please do

Thanks

Share Improve this question edited Feb 19, 2015 at 11:58 webmaster asked Feb 1, 2015 at 15:50 webmasterwebmaster 2,03025 silver badges31 bronze badges 7
  • 5 You should not use floating point math for monetary calculations in any programming language. – Pointy Commented Feb 1, 2015 at 15:52
  • @Pointy You have a point, but in JavaScript we don't have types like decimal in C# to make monetary calculations. How we could achieve that you are talking about? Thank you very much in advance. – Christos Commented Feb 1, 2015 at 15:54
  • 1 @Christos Use ints and calculate in cents, then divide by 100. – MisterBla Commented Feb 1, 2015 at 15:55
  • 1 decimal.js, if one wants a prepared solution. – raina77ow Commented Feb 1, 2015 at 15:55
  • 1 @Bergi That's true. But it's still better than Floating Point numbers. – MisterBla Commented Feb 1, 2015 at 16:02
 |  Show 2 more ments

4 Answers 4

Reset to default 4

Javascript uses the same data type that almost all languages use for floating point calculations. The double precision floating point data type is very mon, because processors have built in support for it.

Floating point numbers have a limited precision, and most numbers with a fractional part can't be represented exactly. However, for what you are going to use it for, the precision is more than enough to show a correct result.

You should just be aware of the limited precision. When displaying the result, you should make sure that it's formatted (and rounded) to the precision that you want to show. Otherwise the limited precision might show up as for example a price of 14.9500000000000001 instead 14.95.

According to JavaScript's specifications, all numbers are 64bit precision (as in 64bit floating point precision).

From this post, you have 3 solutions:

  1. use some implementation of Decimal for JavaScript, as BigDecimal.js
  2. just choose a fixed number of digits to keep, like this (Math.floor(y/x) * x).toFixed(2)
  3. switch to pure integers, treating prices as number of cents. This could lead you to big changes across the whole project

Financial calculations usually require specific fixed rules about (for example) when and how to round (in which direction), etc.
That means you'll often maintain an internal sub-total precision until you move to a next section of your calculation (like adding the tax, as per rules set).

IEEE-754 Floating point (as used in javascript) will give you a maximum accuracy of 2^53 (if you think about it like an integer).
Now your 'job' is to pretend javascript doesn't support floating point and substitute it yourself using the simplest possible way: decrease your maximum integer range to obtain the required floating point precision and see if that resulting range is suitable to your needs. If not, then you might need an external high precision math library (although most basic operations are pretty easy to implement).

First determine your desired internal precision (incl overflow digit for your expected rounding behavior): for example 3 digits:
FLOOR((2^53)/(10^3))=FLOOR(9.007.199.254.740.992/1000)=9.007.199.254.740,000
If this range is sufficient, then you need no other library, just multiply your input 10^float_digits and maintain that internal precision per calculation-section, while rounding each step according to the rules required for your calculation (you'd still need to do that when using a high-precision external math library).

For (visual) output, again, apply proper rounding and just divide your remaining value by 10^(floatDigits-roundingDigit(s)) and pass it through Number.prototype.toFixed() (which then just pads zero's when required).



As to your other question regarding trustworthiness of javascript vs other programming languages: one can even boot/run and use LINUX on javascript inside the browser: http://bellard/jslinux/
Let that sink in for a moment...
Now what if I told you this even works in IE6... Pretty humbling. Even servers can run on javascript (node.js)..

Hope this helps (it didn't fit in a ment).

Other answers have addressed issues that JavaScript has with using floating point numbers to represent money.

There's a separate issue with using JavaScript for calculations involving financial transactions that es to mind. Because the code is executed in a browser on the client machine, You can only trust the result to the extent that you can trust the client.

Therefore you should really only rely on JavaScript to calculate something that you could take for granted if the client told you. For instance, if you were writing an e-merce site, you could trust code that told you what the client wanted to buy, and what the clients shipping address was, but you would need to calculate the price of the goods yourself to prevent the client from telling you a lower price.

It's entirely possible that the invoicing system you're working on will only be used internally to your organisation. If this is the case, you can disregard this entire answer. But, if your applications is going to be used by customers to access and manipulate their invoices and orders, then this is something you'd have to consider.

发布评论

评论列表(0)

  1. 暂无评论