How should a BigDecimal be implemented?

858 views
Skip to first unread message

Justin Fagnani

unread,
Aug 22, 2012, 12:07:09 PM8/22/12
to General Dart Discussion
I used to make a lot of use of Java's BigDecimal for financial apps and was thinking of how useful it'd be, and how much nicer it'd be to use, in Dart, but the implementation brings up some interesting questions for the language regarding both ints and environment-specific code.

BigDecimals are usually implemented with a BigInteger value and an int scale. Dart's arbitrary-sized int would seem to make the BigInteger unnecessary so that you could define BigDecimal like:

class BigDecimal {
  final int unscaledValue;
  final int scale;

  double get doubleValue() => unscaledValue / pow(scale, 10);
}

But we know this won't work in dart2js, which leaves a few options with no clear winner to me:

1) Leave the implementation as-is and let it fail in dart2js. This is clearly wrong to me, but not actually that much worse than the current int behavior.

2) Implement a BigInteger in Dart and use that. The problems are a) if we need a BigInteger why have an arbitrary sized int? Maybe int should just have undefined overflow after 32 bits to deal with JS. b) we now perform BigInteger operations in Dart rather than in the VM with a possible performance hit.

3) Implement a BigInteger, but only use it in dart2js, otherwise use int in the VM. Dart has no facility to do this for user-written code, so it'd have to be added. It might be quite useful for other purposes too.

4) Include BigDecimal in Dart, so that it can have environment-specific implementations with no change to the language.


This basically distills down to two questions: should int be arbitrarily sized, and should it be consistent across JS and VM?

Should there be some allowance for user-written environment-specific code?

I'd love to hear some thoughts on this.

Cheers,
  Justin

Seth Ladd

unread,
Aug 22, 2012, 12:15:03 PM8/22/12
to mi...@dartlang.org
Related, I spotted https://github.com/Solvr/dart-bignum the other day. Also, it was suggested to take a look at BigInteger from http://code.google.com/p/v8/source/browse/branches/bleeding_edge/benchmarks/crypto.js

Meanwhile, I'd love to see conditional loading of library implementations, depending on the runtime environment (vm, dart2js). Another use case is building a common HTTP client.

Here's the main bug on the int size topic, if you want to star it: http://code.google.com/p/dart/issues/detail?id=1533



--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
 
 

Ben Laurie

unread,
Aug 22, 2012, 12:17:45 PM8/22/12
to mi...@dartlang.org
Everything should be consistent across JS and VM!

>
> Should there be some allowance for user-written environment-specific code?
>
> I'd love to hear some thoughts on this.
>
> Cheers,
> Justin
>

Justin Fagnani

unread,
Aug 22, 2012, 12:37:11 PM8/22/12
to mi...@dartlang.org
Ideally, but something probably has to give, probably either performance or our usual expectations of int behavior, due to JS's lack of an int type. Personally I think having double, int and bigint, where int has undefined behavior after 32bits is an interesting option. But maybe the dart2js team can make int work and perform well. That would be incredible.

Lars Tackmann

unread,
Aug 25, 2012, 10:39:39 AM8/25/12
to mi...@dartlang.org
We need arbitrary integer precision for www.solvr.io - We also need real numbers that behave correctly when decimal arithmetic is performed on them (i.e. sane results when stuff like 2.0 - 1.1 is calculated).

I would personally love that programming languages would start getting out of the old machine limitations and consider implementing mathematically correct integers and reals, but honestly for most people its not really needed (even allot of critical financial applications makes due with iee754 floats).

I wonder if this could be a flag for the dart2js compiler ?, so that the few of us who actually need this can get what we want. Until then, the work continues on https://github.com/Solvr/dart-bignum 

Regards,
  Lars

Justin Fagnani

unread,
Aug 25, 2012, 1:28:19 PM8/25/12
to mi...@dartlang.org
On Sat, Aug 25, 2012 at 7:39 AM, Lars Tackmann <la...@randompage.org> wrote:
We need arbitrary integer precision for www.solvr.io - We also need real numbers that behave correctly when decimal arithmetic is performed on them (i.e. sane results when stuff like 2.0 - 1.1 is calculated).

I would personally love that programming languages would start getting out of the old machine limitations and consider implementing mathematically correct integers and reals, but honestly for most people its not really needed (even allot of critical financial applications makes due with iee754 floats).

That's scary. I've worked on a few financial apps, and while I've never seen float or double inprecision lead to Superman II or Office Space like shenanigans, I have seen bugs persist because the tests were broken in their attempt to deal with slightly imprecise comparisons. It would be nice to have comparison methods on double that took an epsilon.
 

I wonder if this could be a flag for the dart2js compiler ?, so that the few of us who actually need this can get what we want. Until then, the work continues on https://github.com/Solvr/dart-bignum 

I think it's better as a separate type so that any cost is borne where it's needed rather than across the whole program. I have no idea whether it's feasible to implement the VMs int behavior in dart2js, but if it isn't I think it'd be fine to have double, int, BigDecimal and BigInt types. (although given that there's no float/single, I question the name "double", maybe it should be decimal).

 
Regards,
  Lars

Lars Tackmann

unread,
Aug 25, 2012, 2:23:20 PM8/25/12
to mi...@dartlang.org
On Sat, Aug 25, 2012 at 7:28 PM, Justin Fagnani
<justin...@google.com> wrote:
>
> That's scary. I've worked on a few financial apps, and while I've never seen
> float or double inprecision lead to Superman II or Office Space like
> shenanigans, I have seen bugs persist because the tests were broken in their
> attempt to deal with slightly imprecise comparisons. It would be nice to
> have comparison methods on double that took an epsilon.
>

Its definitely not a good choice for financial apps but I guess that
some of it was born out of the horrors of dealing with BigDecimal on
Java (i.e. due to Java's lack of operator overloading). Some of it no
doubt is due to SOAP/Schema's lack of good handling for big-decimals.

>
> I think it's better as a separate type so that any cost is borne where it's
> needed rather than across the whole program. I have no idea whether it's
> feasible to implement the VMs int behavior in dart2js, but if it isn't I
> think it'd be fine to have double, int, BigDecimal and BigInt types.
> (although given that there's no float/single, I question the name "double",
> maybe it should be decimal).
>

+1 for the decimal suggestion although I always liked SML's use of int
and real types because it resonates more with the actual mathematical
meaning of the numbers in an arbitrary precision system. Perhaps just
Integer and Real as type names with some ability to use implicit
conversion to convert literals to BigNum like "Real j = 3.14".



--
Yours sincerely

Lars Tackmann
Reply all
Reply to author
Forward
0 new messages