26

What can I use as a decimal type in JavaScript? It's not supported (0.1 + 0.2 !== 0.3), and I need it for representing exact values in a banking/financial application. See The State and Future of JavaScript for a good read and the dirty details behind JavaScript and it's (lack of) support for decimal arithmetic.

By "decimal", I mean either:

  1. infinite-range and arbitrary-precision (like BigDecimal in Java), or
  2. limited range and precision, but suitable for financial calculations (like decimal in C#).

So, what library or solution exists for working with decimal values? Thanks!

s.m.
  • 7,895
  • 2
  • 38
  • 46
Mr. X
  • 261
  • 1
  • 3
  • 3

5 Answers5

15

It is often recommended1 to handle money as an integer representing the number of cents: 2572 cents instead of 25.72 dollars. This is to avoid the problems with floating-point arithmetic that you mention. Fortunately integer arithmetic in floating point is exact, so decimal representation errors can be avoided by scaling.


1Douglas Crockford: JavaScript: The Good Parts: Appendix A - Awful Parts (page 105).

Daniel Vassallo
  • 337,827
  • 72
  • 505
  • 443
  • How many bits are available in the integer part of JavaScript floating point? I might be able to squeeze it all in. – Mr. X Aug 11 '10 at 03:05
  • @Mr. X: almost certainly 53 or more. – ysth Aug 11 '10 at 03:06
  • @Mr. X: check out http://stackoverflow.com/questions/307179/what-is-javascripts-max-int-whats-the-highest-integer-value-a-number-can-go-to, and this: http://stackoverflow.com/questions/3428136/javascript-integer-math-incorrect-results – Daniel Vassallo Aug 11 '10 at 03:11
  • This is really good advice regardless of the programming language. – Kelly Elton May 04 '18 at 16:23
  • Some software has to handle currencies that use 8 or even 18 decimals precision (crypto). Using integers works only with limits here and it's cumbersome and error-prone to "manually" keep track of how many decimals each currency uses (needed for correct output formatting). Using BigNumber (as another answer by Daniel O' Hara suggested) doesn't have either of those problems. – molecular Mar 08 '23 at 07:56
5

Javascript does have floating point support. But anyway, for financial records, the simplest implementation would simply be storing your values in standard integers. You may either declare an integer to represent the amount in cents, or two integers one for dollars and one for cents.

So $18.57 would become 1857cents in the first technique or 18 dollars and 57 cents in the second.

This has the added advantage of being completely accurate, as integers are stored purely as unique binary representation, there would be no such thing as rounding errors.

Razor Storm
  • 12,167
  • 20
  • 88
  • 148
  • 1
    Yeah, JavaScript has binary floating point, which is a bad choice for 99% of the applications that use JavaScript. Do any JavaScript libraries exist that abstract the concept of decimal for me? – Mr. X Aug 11 '10 at 03:03
  • 2
    Wouldn't it be simpler to just store it as integer like my example? All decimal implementations would have inherent inaccuracies due to how the architecture represents floating points. Don't worry about overflow, even the US national debt would fit neatly in a long type 64bit int. – Razor Storm Aug 11 '10 at 03:05
  • 2
    The integer part of JavaScript's floating point is less than 64 bits. – Mr. X Aug 11 '10 at 03:07
  • 1
    @Razor: *"All decimal implementations would have inherent inaccuracies due to how the architecture represents floating points."* Not **all**. A true "decimal" implementation could (and would probably have to) do what Java's `BigDecimal` class does: Actually store the data as a string of digits, the way we write and think about it, plus a scale indicator so it knows where the decimal point is. For money stuff in the realm of figures most people are likely to deal with, storing numbers of cents is fine; but for a general-purpose "decimal" type, that's the kind of thing that would be required... – T.J. Crowder Jul 04 '11 at 06:22
  • @Crowder x86 architecture can work with floating-point decimals (one nibble per decimal-digit) for ages. – John Nov 23 '13 at 14:56
3

Take a look at BigNumber and that post too.

Community
  • 1
  • 1
Daniel O'Hara
  • 13,307
  • 3
  • 46
  • 68
  • 1
    Just looking at that code makes me wanna cry. Interesting idea though, but it sucks to not be able to use regular operators `+ - / *` etc – adamJLev Aug 11 '10 at 03:05
2

It seems the following library implements decimal in js (node and browser): https://npmjs.org/package/jsdecimal

pedroteixeira
  • 806
  • 7
  • 7
0

I think using integers is great till you have to do some calculations with them that require percentages etc, then you're back to floats. I'd personally just use Decimals and use a library specifically designed to handle Decimals like

https://github.com/MikeMcl/decimal.js

And then you can represent your data and operate on it in a clear way, with your expectations met as to how it's represented, not messing with converting integers back to decimals for display purposes etc.

Artisan
  • 1,974
  • 1
  • 18
  • 23