views:

1965

answers:

5

Is there a good javascript BigDecimal library out there?

I saw this one: http://www.navioo.com/javascript/BigDecimal_for_JavaScript_959.html# (also known as http://stz-ida.de/html/oss/js_bigdecimal.html.en)

But that looks like it was autogenerated from java to javascript. It's 180K and declares global variables all over the place.

I don't really need arbitrary precision here. 7 decimal places would be good, 10-15 would be great.

.1 + .2 in javascript is wrong in the 17th? decimal place. So if I just round all numbers to 10 decimals after each arithmetic operation, would that be enough?

A: 

Have you tried this one?

http://stz-ida.de/html/oss/js_bigdecimal.html.en

Seb
yes, that's where the "demo" link takes you from the site I mentioned
Mike Blandford
A: 

7 decimal places would be good, 10-15 would be great

JavaScript Number gives you 15 significant figures (52 bits of mantissa).

So if I just round all numbers to 10 decimals after each arithmetic operation, would that be enough?

You could do, although still you'd not be rounding exactly to that decimal of course.

For certainty and efficiency you should also consider fixed-point arithmetic.

It's 180K and declares global variables all over the place.

Yeah, I wrote my own limited implementation for what I needed (only does +-*/).

bobince
You wrote a javascript BigDecimal class? Any chance you could post that? :D
Mike Blandford
+2  A: 

.1 + .2 in javascript is wrong in the 17th? decimal place. So if I just round all numbers to 10 decimals after each arithmetic operation, would that be enough?

Instead of rounding:

  1. scale to whole numbers
  2. do math
  3. scale to decimal.

(0.1*10 + 0.2*10) / 10 = 0.3

http://yuiblog.com/blog/2009/03/10/when-you-cant-count-on-your-numbers/

Jason Harwig
+5  A: 

Scaling numbers is a "poor mans" BigDecimal. It will alleviate floating point issues but not fix them. Think of scaled math as a treatment, not a cure.

The BigDecimal library has proven to be the most useful to me. There is also "BigNumber", which you can find here: http://jsfromhell.com/classes/bignumber. Both have bugs, but those bugs can be fixed. I've outlined them below.

BigDecimal is a straight port from the Java library of the same name. Despite its scary appearance it is much faster than BigNumber in some operations.

Performance results from my own tests show that addition,subtraction,multiplication and division all average around .03 milliseconds for a single call. BigNumber operations average around .05. The real difference shows in more complex calculations. A standard compound interest calculation using BigDecimal averages .39 milliseconds while the same calculation with BigNumber took several milliseconds, I believe this is due in large part to a more efficient implementation of pow() by BigDecimal.

In choosing to use these, there are two issues to be aware of: BigNumber has a bug that prevents correct rounding.The name of the rounding constants used are incorrect in the round function, and the add function incorrectly returns a new object when in "rounding mode" (it should "add in place"). Both issues are easy to fix.

BigDecimal has a bug in the implementation of its pow() function. The author kindly provided a fix. As the Java version relied upon an integer overflow, you need to correct the following in BigDecimal.js:

2405   n=n+n; // shift left 1 bit
2406   if (n<0)

To

2405   n<<=1; // shift left 1 bit
2406   if (n<0)

In the end I chose BigDecimal and have been happy with the results, hopefully these two fixes will allow you to evaluate them for yourself!

Matt Baker
wow, BigNumber uses a "with" statement. First time I've seen that apart from reading about it in the "bad practice, never use" section of a js book. I like that that source is so small on BigNumber. If I decide to use BigDecimal I'd spend some time refactoring it. It looks like a lot of the 160k is comments anyway.
Mike Blandford
The YUI compressor would probably help you there: http://developer.yahoo.com/yui/compressor/But I understand to drive to refactor, my aesthetic sensibilities are causing similar feelings. Check out line 2405 in BigDecimal.js if you really want a headache.
Matt Baker
+1  A: 

I recently released BigDecimal for Javascript. It is the GWT Java BigDecimal and BigInteger classes compiled into standalone CommonJS modules. The GWT code itself comes from Apache Harmony.

Pros:

  • Complete, documented implementation interface
  • Stable, bug-free (as much as can be expected) implementation

Cons:

  • Javascript code is compiled from Java, not human-editable
  • 110 KB source file

I am using it successfully in my own CouchDB and NodeJS projects.

jhs