Petitioning for Javascript BC Math

About a month ago Microsoft published this up on the IEBlog

http://blogs.msdn.com/b/ie/archive/2011/11/22/evolving-ecmascript.aspx

I sent them an email back stating that one thing a lot more people need in Javascript than some trig functions is a reliable binary calculator. The response I got was a little encouraging, “We’ll look into it” from someone who’s sig said they where in charge of the MS javascript engine, so I dunno - here’s hoping. If IE 10 did have a binary calculator and the other browsers didn’t I’d push for my clients to use IE with the site more. More importantly, the other browser manufacturers would probably follow suit.

For those wondering about the significance of all this: The problems of floating point math are as esoteric as they are frustrating. Further, I know a lot more of us are dealing with money in accounting and ecommerce packages than there are graphing calculations. Not to downplay what Microsoft is proposing to add to the IE js parser, but I think it’s high time javascript picked up this ability as a js core ability. The API need not be complicated and can be extended off the existing Math object as a bc sub-object.

alert( Math.bc.div( 1, 3, 2) ); would return “.33”, not “.3333333333333333333” or the like. BC Math is a library within Linux and PHP has a direct mapping inbuilt. It should be trivial for Firefox to build it in. My suggested API is as follows, and mimics the existing API seen in PHP, but isn’t the exactly the same.


Math.bc = {
  /*
   * Unless otherwise noted, l is 'left operand', 'r' is right operand, 
   * 's' is scale, which is the number of digits to the right of the
   * decimal to consider in the operation.
   *
   * Javascript is a loosely typed language, but be aware bc functions
   * expect string arguments and return strings, the will accept
   * numbers but will silently convert them to strings.
   */
  add: function ( l, r, s ) {},
  comp: function (l, r, s) {},
  div: function (l, r, s) {},
  mod: function (l, r) {}, // (modulus, % )
  mul: function (l, r, s) {},
  pow: function (l, r, s) {},
  powmod: function( l, r, m, s) {}, // m is modulus
  getScale: function() {}, // return the default scale.
  setScale: function( s ) {}, // set the default scale.
  sqrt: function( o, s ) {}, // o is operand.  This returns the square root.
  sub: function( l, r, s) {}

So far this object works like PHP library. That will be useful, but we can do better in js. All these functions can be called statically. However, I suggest allow bc object to be created with the new operator, taking one argument to be the starting value of the object (if no argument is supplied, it starts at 0 ). Such an object can then be chained, always passing itself as the starting value and returning itself for chaining. However, it would have a toString method to give it’s current value, and a set() function would be added to set a new value for the object. The scale of an active object would be independent of the default scaling. This would allow the following.



var myMoney = new Math.bc().setScale(2);
myMoney.add('2.33').add(1.15).sub(3).mul(2.5);


Thoughts?