0

In JavaScript 0.1 + 0.2 = 0.30000000000000004 and Is floating point math broken? explains why because of IEEE 754 math. I am working with applications in the finance/accounting domain and want a way to make 0.1 + 0.2 = 0.3

Therefore, I am looking for a solution that can take code similar to the below example with type annotations for Decimal (using the TypeScript syntax).

var a:Decimal, b:Decimal, c:Decimal;

a = 0.1;
b = 0.2;

c = a + b;

The compile/macro expansion process could output this code which uses a JavaScript Decimal library (e.g. decimal.js), so c = 0.3 and not 0.30000000000000004

var a, b, c;

a = new Decimal(0.1);
b = new Decimal(0.2);

c = a.plus(b);

Mozilla sweet.js macros seems to support custom operators which "let you define your own operators or override the built-in operators."

Question: Is this behavior possible with sweet.js? Are there any similar examples?


TypeScript transpiles source code and this concept has been asked about before with TypeScript:

Question: Can the TypeScript compiler be extended to support this use case? Would this be appropriate for a feature request?


Additionally, a blog post in a series about cross-compiling ActionScript to JavaScript concluded they wanted "same wrong result in ActionScript and JavaScript" for consistency reasons, but that did not assume additional type annotations.

Question: Are there other strategies or compile-to-JavaScript options to achieve this goal?

Community
  • 1
  • 1
Kevin Hakanson
  • 41,386
  • 23
  • 126
  • 155

2 Answers2

1

Is there a compile-to-JavaScript solution that does this today

One worth mentioning that does support operator overriding and does have optional type annotations is google's Dart : https://www.dartlang.org/

Operator overriding : https://www.dartlang.org/articles/idiomatic-dart/#operators Optional Types : https://www.dartlang.org/articles/optional-types/

basarat
  • 261,912
  • 58
  • 460
  • 511
1

Alternatively, you could do all the maths using a separate math library. For example math.js comes with an expression parser and supports bignumbers (powered by decimal.js):

math.config({number: 'bignumber'});

// using a parser to manage variables for you in an internal scope:
var parser = math.parser();
parser.eval('a = 0.1');   // BigNumber, 0.1
parser.eval('b = 0.2');   // BigNumber, 0.2
parser.eval('c = a + b'); // BigNumber, 0.3

// or without a parser: 
var scope = {};
math.eval('a = 0.1', scope);   // BigNumber, 0.1
math.eval('b = 0.2', scope);   // BigNumber, 0.2
math.eval('c = a + b', scope); // BigNumber, 0.3
// scope now contains properties a, b, and c

I don't know if this would be feasible and handy for your application, but at least that would allow you to write your equations in "readable" expressions.

Jos de Jong
  • 6,602
  • 3
  • 38
  • 58