Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
Yaffle committed Dec 13, 2020
1 parent e6d68b5 commit 4b80707
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 18 deletions.
26 changes: 14 additions & 12 deletions BigDecimal.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
// BigDecimal.sin(a, rounding)
// BigDecimal.cos(a, rounding)
// BigDecimal.atan(a, rounding)
// (!) Note: consider using only 'half-even' rounding mode and rounding to a maximum number of significant digits,
// use to round to an integer use `BigDecimal.round(a, {maximumFractionDigits: 0, roundingMode: 'half-even'})`.
// (!) Note: consider to use only "half-even" rounding mode and rounding to a maximum number of significant digits for floating-point arithmetic,
// or only "floor" rounding to a maximum number of fraction digits for fixed-point arithmetic.
// BigFloat may have better performance.
// Use to round to an integer `BigDecimal.round(a, {maximumFractionDigits: 0, roundingMode: "half-even"})`.


var factory = function (BASE) {
Expand Down Expand Up @@ -379,12 +381,12 @@ BigDecimal.prototype.toString = function () {
};

var roundToInteger = function (a) {
var rint = BigDecimal.round(a, {maximumFractionDigits: 0, roundingMode: 'half-even'});
var rint = BigDecimal.round(a, {maximumFractionDigits: 0, roundingMode: "half-even"});
return !BigDecimal.lessThan(BigDecimal.multiply(BigDecimal.subtract(a, rint), BigDecimal.BigDecimal(2)), BigDecimal.BigDecimal(1)) ? BigDecimal.add(rint, BigDecimal.BigDecimal(1)) : rint;
};
var bigDecimalToPlainString = function (significand, exponent, minFraction, minSignificant) {
let e = exponent + significand.length - 1;
significand = significand.replace(/0+$/g, '');
significand = significand.replace(/0+$/g, "");
var zeros = Math.max(0, Math.max(e + 1, minSignificant) - significand.length);
if (e <= -1) {
significand = "0".repeat(0 - e) + significand;
Expand All @@ -398,7 +400,7 @@ var bigDecimalToPlainString = function (significand, exponent, minFraction, minS
var toPrecision = function (significand, exponent, minSignificant) {
const e = exponent + BigInt(significand.length - 1);
if (e < -6 || e >= minSignificant) {
return bigDecimalToPlainString(significand, -(significand.length - 1), 0, minSignificant) + 'e' + (e < 0 ? '-' : '+') + bigIntAbs(e).toString();
return bigDecimalToPlainString(significand, -(significand.length - 1), 0, minSignificant) + "e" + (e < 0 ? "-" : "+") + bigIntAbs(e).toString();
}
return bigDecimalToPlainString(significand, Number(exponent), 0, minSignificant);
};
Expand All @@ -407,12 +409,12 @@ var toFixed = function (significand, exponent, minFraction) {
};
var toExponential = function (significand, exponent, minFraction) {
const e = exponent + BigInt(significand.length - 1);
return bigDecimalToPlainString(significand, -(significand.length - 1), 0, minFraction + 1) + 'e' + (e < 0 ? '-' : '+') + bigIntAbs(e).toString();
return bigDecimalToPlainString(significand, -(significand.length - 1), 0, minFraction + 1) + "e" + (e < 0 ? "-" : "+") + bigIntAbs(e).toString();
};

BigDecimal.prototype.toFixed = function (fractionDigits) {
var value = BigDecimal.multiply(this, BigDecimal.BigDecimal(10n**BigInt(fractionDigits)));
var sign = BigDecimal.lessThan(value, BigDecimal.BigDecimal(0)) ? '-' : '';
var sign = BigDecimal.lessThan(value, BigDecimal.BigDecimal(0)) ? "-" : "";
value = roundToInteger(abs(value));
return sign + toFixed(BigDecimal.toBigInt(value).toString(), -fractionDigits, fractionDigits);
};
Expand Down Expand Up @@ -463,9 +465,9 @@ var getDecimalSignificantAndExponent = function (value, precision) {
return lg + log10Approximate(BigDecimal.divide(x, exponentiate(ten, lg), rounding));
};
if (BigDecimal.equal(value, BigDecimal.BigDecimal(0))) {
return {significand: '0', exponent: 0n};
return {significand: "0", exponent: 0n};
}
var rounding = {maximumSignificantDigits: 8, roundingMode: 'half-even'};
var rounding = {maximumSignificantDigits: 8, roundingMode: "half-even"};
var result = undefined;
var fd = 0;
do {
Expand Down Expand Up @@ -501,19 +503,19 @@ var getDecimalSignificantAndExponent = function (value, precision) {
result = BigDecimal.toBigInt(roundToInteger(x)).toString();
}
}
rounding = {maximumSignificantDigits: rounding.maximumSignificantDigits * 2, roundingMode: 'half-even'};
rounding = {maximumSignificantDigits: rounding.maximumSignificantDigits * 2, roundingMode: "half-even"};
} while (result == undefined);
return {significand: result, exponent: -fd};
};

BigDecimal.prototype.toPrecision = function (precision) {
var tmp = getDecimalSignificantAndExponent(abs(this), precision);
return (BigDecimal.lessThan(this, BigDecimal.BigDecimal(0)) ? '-' : '') + toPrecision(tmp.significand, tmp.exponent, precision);
return (BigDecimal.lessThan(this, BigDecimal.BigDecimal(0)) ? "-" : "") + toPrecision(tmp.significand, tmp.exponent, precision);
};

BigDecimal.prototype.toExponential = function (fractionDigits) {
var tmp = getDecimalSignificantAndExponent(abs(this), fractionDigits + 1);
return (BigDecimal.lessThan(this, BigDecimal.BigDecimal(0)) ? '-' : '') + toExponential(tmp.significand, tmp.exponent, fractionDigits);
return (BigDecimal.lessThan(this, BigDecimal.BigDecimal(0)) ? "-" : "") + toExponential(tmp.significand, tmp.exponent, fractionDigits);
};

function exponentiate(a, n) {
Expand Down
2 changes: 1 addition & 1 deletion BigDecimalByDecimal.js.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function rm(roundingMode) {
function setRounding(rounding) {
if (rounding != null) {
if (rounding.maximumFractionDigits != undefined) {
throw new RangeError("rounding to maximumFractionDigits is not supported");
throw new RangeError('rounding to maximumFractionDigits is not supported');
}
Decimal.precision = rounding.maximumSignificantDigits;
Decimal.rounding = rm(rounding.roundingMode);
Expand Down
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,21 @@ Similar to BigDecimal, but uses base 2.
## Example:
```javascript

import {BigDecimal} from './node_modules/@yaffle/bigdecimal/BigDecimal.js';
import {BigDecimal} from "./node_modules/@yaffle/bigdecimal/BigDecimal.js";

var pi = BigDecimal.multiply(BigDecimal.BigDecimal(4), BigDecimal.atan(BigDecimal.BigDecimal(1), {maximumSignificantDigits: 1000, roundingMode: 'half-even'}));
var pi = BigDecimal.multiply(BigDecimal.BigDecimal(4), BigDecimal.atan(BigDecimal.BigDecimal(1), {maximumSignificantDigits: 1000, roundingMode: "half-even"}));

console.log(pi.toString());

```

# Note:
Consider to use only "half-even" rounding mode and rounding to a maximum number of significant digits for floating-point arithmetic,
or only "floor" rounding to a maximum number of fraction digits for fixed-point arithmetic.
BigFloat may have better performance.
Use to round to an integer `BigDecimal.round(a, {maximumFractionDigits: 0, roundingMode: "half-even"})`.


# Similar projects:
1. https://github.com/MikeMcl/decimal.js/
2. https://github.com/uzyn/bigdenary
Expand Down
6 changes: 3 additions & 3 deletions tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -365,11 +365,11 @@ for (var c = 0; c < 1000; c += 1) {
//debugger;
if (number !== 0 && !Number.isNaN(number)) {
var bigfloat = bigfloatFromNumber(number);
var f = "sin cos atan exp log".split(" ")[Math.floor(Math.random() * 5)];
//f = "cos";
var f = 'sin cos atan exp log'.split(' ')[Math.floor(Math.random() * 5)];
//f = 'cos';
var value = Math[f](number);
if (Math.abs(value) > 0 && Math.abs(value) < 1/0) {
if (f !== "log" || number > 0) {
if (f !== 'log' || number > 0) {
var n = 20;
var a = BigFloat[f](bigfloat, {maximumSignificantDigits: 18, roundingMode: 'half-even'}).toPrecision(n);
var b = roundNumber(value, 18).toPrecision(n);
Expand Down

0 comments on commit 4b80707

Please sign in to comment.