diff --git a/big.js b/big.js index 7743ddd..a9731a5 100644 --- a/big.js +++ b/big.js @@ -338,15 +338,17 @@ /* * Return a new Big whose value is the value of this Big divided by the value of Big y, rounded, - * if necessary, to a maximum of Big.DP decimal places using rounding mode Big.RM. + * if necessary, to a maximum of params?.dp, or Big.DP (if params?.dp is not specified) decimal + * places using rounding mode params?.rm, or Big.RM (if params?.rm is not specified) */ - P.div = function (y) { + P.div = function (y, params) { var x = this, Big = x.constructor, a = x.c, // dividend b = (y = new Big(y)).c, // divisor k = x.s == y.s ? 1 : -1, - dp = Big.DP; + dp = params?.dp ?? Big.DP, + rm = params?.rm ?? Big.RM; if (dp !== ~~dp || dp < 0 || dp > MAX_DP) { throw Error(INVALID_DP); @@ -441,7 +443,7 @@ } // Round? - if (qi > p) round(q, p, Big.RM, r[0] !== UNDEFINED); + if (qi > p) round(q, p, rm, r[0] !== UNDEFINED); return q; }; @@ -621,12 +623,7 @@ if (ygtx) return new Big(x); - a = Big.DP; - b = Big.RM; - Big.DP = Big.RM = 0; - x = x.div(y); - Big.DP = a; - Big.RM = b; + x = x.div(y, { dp: 0, rm: 0 }); return this.minus(x.times(y)); }; @@ -724,12 +721,12 @@ /* * Return a Big whose value is the value of this Big raised to the power n. - * If n is negative, round to a maximum of Big.DP decimal places using rounding - * mode Big.RM. + * If n is negative, round to a maximum of params?.dp, or Big.DP (if params?.dp is not specified) + * decimal places using rounding mode params?.rm, or Big.RM (if params?.rm is not specified). * * n {number} Integer, -MAX_POWER to MAX_POWER inclusive. */ - P.pow = function (n) { + P.pow = function (n, params) { var x = this, one = new x.constructor('1'), y = one, @@ -748,7 +745,7 @@ x = x.times(x); } - return isneg ? one.div(y) : y; + return isneg ? one.div(y, params) : params?.dp !== UNDEFINED || params?.rm !== UNDEFINED ? y.round(params?.dp, params?.rm) : y; }; @@ -787,15 +784,18 @@ /* * Return a new Big whose value is the square root of the value of this Big, rounded, if - * necessary, to a maximum of Big.DP decimal places using rounding mode Big.RM. + * necessary, to a maximum of params?.dp, or Big.DP (if params?.dp is not specified) + * decimal places using rounding mode params?.rm, or Big.RM (if params?.rm is not specified). */ - P.sqrt = function () { + P.sqrt = function (params) { var r, c, t, x = this, Big = x.constructor, s = x.s, e = x.e, - half = new Big('0.5'); + half = new Big('0.5'), + dp = params?.dp ?? Big.DP, + rm = params?.rm ?? Big.RM; // Zero? if (!x.c[0]) return new Big(x); @@ -820,15 +820,15 @@ r = new Big(s + ''); } - e = r.e + (Big.DP += 4); + e = r.e + (dp += 4); // Newton-Raphson iteration. do { t = r; - r = half.times(t.plus(x.div(t))); + r = half.times(t.plus(x.div(t, { dp, rm }))); } while (t.c.slice(0, e).join('') !== r.c.slice(0, e).join('')); - return round(r, (Big.DP -= 4) + r.e + 1, Big.RM); + return round(r, (dp -= 4) + r.e + 1, rm); }; diff --git a/test/methods/div.js b/test/methods/div.js index e81e23d..b3e79ff 100644 --- a/test/methods/div.js +++ b/test/methods/div.js @@ -2,8 +2,8 @@ if (typeof test === 'undefined') require('../test'); test('div', function () { - function t(dividend, divisor, expected) { - test.areEqual(String(expected), String(new Big(dividend).div(divisor))); + function t(dividend, divisor, expected, params) { + test.areEqual(String(expected), String(new Big(dividend).div(divisor, params))); } Big.DP = 40; @@ -9922,4 +9922,20 @@ test('div', function () { Big.DP = 2; t( 1, 4, '0.25'); t( 0.25, 1, '0.25'); + + // Using params. + t(0.034, 365, '0.0000931506', { dp: 10, rm: 0 }); + t(0.034, 365, '0.0000931507', { dp: 10, rm: 1 }); + t(0.034, 365, '0.0000931507', { dp: 10, rm: 2 }); + t(0.034, 365, '0.0000931507', { dp: 10, rm: 3 }); + + t(0.034, 365, '0.00009315068493150684', { dp: 20, rm: 0 }); + t(0.034, 365, '0.00009315068493150685', { dp: 20, rm: 1 }); + t(0.034, 365, '0.00009315068493150685', { dp: 20, rm: 2 }); + t(0.034, 365, '0.00009315068493150685', { dp: 20, rm: 3 }); + + t(0.034, 365, '0.000093150684931506849315068493', { dp: 30, rm: 0 }); + t(0.034, 365, '0.000093150684931506849315068493', { dp: 30, rm: 1 }); + t(0.034, 365, '0.000093150684931506849315068493', { dp: 30, rm: 2 }); + t(0.034, 365, '0.000093150684931506849315068494', { dp: 30, rm: 3 }); }); diff --git a/test/methods/pow.js b/test/methods/pow.js index cf82acb..731e3d6 100644 --- a/test/methods/pow.js +++ b/test/methods/pow.js @@ -3,8 +3,8 @@ if (typeof test === 'undefined') require('../test'); test('pow', function () { var MAX_POWER = 1e6; - function t(expected, n, exp) { - test.areEqual(String(expected), String(new Big(n).pow(exp))) + function t(expected, n, exp, params) { + test.areEqual(String(expected), String(new Big(n).pow(exp, params))) } Big.DP = 20; @@ -1129,6 +1129,28 @@ test('pow', function () { t('-1e-99', '-62548432.8', -25); t('1.22088300717794393478122381886210353872220530435821687360137756351400919646900089304893824e-10', '-90503', -2); + // Using params. + t('0.00000256', 0.2, 8, { dp: 8, rm: 0 }); + + t('0', 0.2, 8, { rm: 0 }); + t('0.0000026', 0.2, 8, { dp: 7 }); + t('0.00000256', 0.2, 8, {}); + + t('0.0000025', 0.2, 8, { dp: 7, rm: 0 }); + t('0.0000026', 0.2, 8, { dp: 7, rm: 1 }); + t('0.0000026', 0.2, 8, { dp: 7, rm: 2 }); + t('0.0000026', 0.2, 8, { dp: 7, rm: 3 }); + + t('0.000002', 0.2, 8, { dp: 6, rm: 0 }); + t('0.000003', 0.2, 8, { dp: 6, rm: 1 }); + t('0.000003', 0.2, 8, { dp: 6, rm: 2 }); + t('0.000003', 0.2, 8, { dp: 6, rm: 3 }); + + t('0.0069', 12, -2, { dp: 4, rm: 0 }); + t('0.0069', 12, -2, { dp: 4, rm: 1 }); + t('0.0069', 12, -2, { dp: 4, rm: 2 }); + t('0.007', 12, -2, { dp: 4, rm: 3 }); + /* * Notes: * diff --git a/test/methods/sqrt.js b/test/methods/sqrt.js index f2433af..03896c4 100644 --- a/test/methods/sqrt.js +++ b/test/methods/sqrt.js @@ -2,8 +2,8 @@ if (typeof test === 'undefined') require('../test'); test('sqrt', function () { - function t(root, value) { - test.areEqual(root, new Big(value).sqrt().toString()) + function t(root, value, params) { + test.areEqual(root, new Big(value).sqrt(params).toString()) } Big.DP = 20; @@ -737,4 +737,20 @@ test('sqrt', function () { Big.RM = 0; t('9.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999e+179', new Big('1e360').minus(1)); //t('9.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999e+499', new Big('1e1000').minus(1)); + + // Using params. + t('3.4813790371', 12.12, { dp: 10, rm: 0 }); + t('3.4813790371', 12.12, { dp: 10, rm: 1 }); + t('3.4813790371', 12.12, { dp: 10, rm: 2 }); + t('3.4813790372', 12.12, { dp: 10, rm: 3 }); + + t('3.48137903710584205614', 12.12, { dp: 20, rm: 0 }); + t('3.48137903710584205614', 12.12, { dp: 20, rm: 1 }); + t('3.48137903710584205614', 12.12, { dp: 20, rm: 2 }); + t('3.48137903710584205615', 12.12, { dp: 20, rm: 3 }); + + t('3.481379037105842056144488334142', 12.12, { dp: 30, rm: 0 }); + t('3.481379037105842056144488334143', 12.12, { dp: 30, rm: 1 }); + t('3.481379037105842056144488334143', 12.12, { dp: 30, rm: 2 }); + t('3.481379037105842056144488334143', 12.12, { dp: 30, rm: 3 }); });