jsbn-based arbitrary precision operations on currency amounts "XXX.YY"; because floats are BAD for representing money
npm install money-mathAdds, multiplies the currency _amounts,_ and calculates percentages of _amounts._ The result of
each of those operations is also an _amount:_ a string, strictly matching the /^\-?\d+\.\d\d$/
pattern, like "0.25", "1000.00", or "-42.10".
_Amounts_ on input and output are arbitrary large and precise:
99999999999999999999999999999999999999999999999999999999999999999999999999999999.99
+
0.01
=
100000000000000000000000000000000000000000000000000000000000000000000000000000000.00
However, in cases when the division is involved — like for percentage calculation — the result is
rounded to the whole cent.
``javascript`
money.percent("0.50", "33.00") // is "0.17" instead of "0.165"
As a bonus feature, there's a simple formatting function for _amounts_ in the following currencies:
* CHF
* EUR
* GBP
* JPY
* LTL
* PLN
* SEK
* SKK
* UAH
* USD
`javascript`
money.format("EUR", "-1560.00") // "-1.560,00"
Because storing currency amounts in floats is a really bad idea
Works both on Node and in the browser.
`javascript`
var money = require("money-math");
Download jsbn/index.js
Download money.js
`javascript`
window.Money
`javascript
money.add("16.11", "17.07"); // "33.18"
money.subtract("16.00", "7.00"); // "9.00"
money.mul("24.00", "0.25"); // "6.00"
money.div("64.00", "2.00"); // "32.00"
money.percent("200.00", "3.25"); // "6.50"
money.cmp("100.00", "200.00"); // -1
money.isEqual("100.00", "100.00"); // true
money.isZero("0.00"); // true
money.isNegative("-1.00"); // true
money.isPositive("-1.00"); // false
money.isGreaterThan("2.00", "1.00"); // true
money.isGreaterOrEqualTo("2.00", "2.00"); // true
money.isLessThan("2.00", "1.00"); // false
money.isLessrOrEqualTo("2.00", "2.00"); // true
money.format("JPY", "236800.00"); // "236,800"
money.floatToAmount(56.345); // "56.35"
`
And last, but not least :)
`javascript`
money.roundUpTo5Cents("42.02"); // "42.05"
money.roundTo5Cents("442.26"); // "442.25"
Which we use for bills in CHF that are required by law to be 0 (mod 5).
The _amount_ strings are expected to strictly adhere to the format described by the regular
expression noted above. Thus, for example, it must be:
* "10.10", not "10.1", not "10.100";"10.00"
* , not 10, not "10", not "10.0".
That's a precondition for any of the API functions accepting _amount_ arguments to work correctly. I
understand that it may be confusing to some of new users; but I believe that's an optimally
pragmatic way to mimic, by convention, an algebraic data type in idiomatic JavaScript -- a (very)
dynamically typed language.
Just for the sake of convenience, we provide a way to approximate an imprecise float value in
the _amounts field_ with money.floatToAmount(…) (half up rounding applied). Once all the values
are _amounts,_ money-math guarantees that all the _field_ operations keep the results withing the
_field._ Classic algebra.
A thoughtful reader might ask, why have money.floatToAmount(), when there's theNumber.prototype.toFixed(2)? Well, because:
`javascript``
> 56.155.toFixed(2);
'56.16'
> 56.345.toFixed(2);
'56.34'
Floats are such floats...