Skip to content

Commit

Permalink
#148 Bugfix: primitive numbers passed to constructor internally in st…
Browse files Browse the repository at this point in the history
…rict mode
  • Loading branch information
MikeMcl committed Dec 2, 2020
1 parent 5810376 commit 2ea2e75
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 50 deletions.
71 changes: 46 additions & 25 deletions big.js
Expand Up @@ -353,7 +353,11 @@
}

// Dividend is 0? Return +-0.
if (!a[0]) return new Big(k * 0);
if (!a[0]) {
y.s = k;
y.c = [y.e = 0];
return y;
}

var bl, bt, n, cmp, ri,
bz = b.slice(),
Expand Down Expand Up @@ -504,9 +508,14 @@

// Either zero?
if (!xc[0] || !yc[0]) {

// y is non-zero? x is non-zero? Or both are zero.
return yc[0] ? (y.s = -b, y) : new Big(xc[0] ? x : 0);
if (yc[0]) {
y.s = -b;
} else if (xc[0]) {
y = new Big(x);
} else {
y.s = 1;
}
return y;
}

// Determine which is the bigger number. Prepend zeros to equalise exponents.
Expand Down Expand Up @@ -622,15 +631,15 @@
* Return a new Big whose value is the value of this Big plus the value of Big y.
*/
P.plus = P.add = function (y) {
var t,
var e, k, t,
x = this,
Big = x.constructor,
a = x.s,
b = (y = new Big(y)).s;
Big = x.constructor;

y = new Big(y);

// Signs differ?
if (a != b) {
y.s = -b;
if (x.s != y.s) {
y.s = -y.s;
return x.minus(y);
}

Expand All @@ -639,24 +648,33 @@
ye = y.e,
yc = y.c;

// Either zero? y is non-zero? x is non-zero? Or both are zero.
if (!xc[0] || !yc[0]) return yc[0] ? y : new Big(xc[0] ? x : a * 0);
// Either zero?
if (!xc[0] || !yc[0]) {
if (!yc[0]) {
if (xc[0]) {
y = new Big(x);
} else {
y.s = x.s;
}
}
return y;
}

xc = xc.slice();

// Prepend zeros to equalise exponents.
// Note: reverse faster than unshifts.
if (a = xe - ye) {
if (a > 0) {
if (e = xe - ye) {
if (e > 0) {
ye = xe;
t = yc;
} else {
a = -a;
e = -e;
t = xc;
}

t.reverse();
for (; a--;) t.push(0);
for (; e--;) t.push(0);
t.reverse();
}

Expand All @@ -667,20 +685,20 @@
xc = t;
}

a = yc.length;
e = yc.length;

// Only start adding at yc.length - 1 as the further digits of xc can be left as they are.
for (b = 0; a; xc[a] %= 10) b = (xc[--a] = xc[a] + yc[a] + b) / 10 | 0;
for (k = 0; e; xc[e] %= 10) k = (xc[--e] = xc[e] + yc[e] + k) / 10 | 0;

// No need to check for zero, as +x + +y != 0 && -x + -y != 0

if (b) {
xc.unshift(b);
if (k) {
xc.unshift(k);
++ye;
}

// Remove trailing zeros.
for (a = xc.length; xc[--a] === 0;) xc.pop();
for (e = xc.length; xc[--e] === 0;) xc.pop();

y.c = xc;
y.e = ye;
Expand All @@ -698,7 +716,7 @@
*/
P.pow = function (n) {
var x = this,
one = new x.constructor(1),
one = new x.constructor('1'),
y = one,
isneg = n < 0;

Expand Down Expand Up @@ -762,7 +780,7 @@
Big = x.constructor,
s = x.s,
e = x.e,
half = new Big(0.5);
half = new Big('0.5');

// Zero?
if (!x.c[0]) return new Big(x);
Expand All @@ -784,7 +802,7 @@
e = ((e + 1) / 2 | 0) - (e < 0 || e & 1);
r = new Big((s == 1 / 0 ? '5e' : (s = s.toExponential()).slice(0, s.indexOf('e') + 1)) + e);
} else {
r = new Big(s);
r = new Big(s + '');
}

e = r.e + (Big.DP += 4);
Expand Down Expand Up @@ -817,7 +835,10 @@
y.s = x.s == y.s ? 1 : -1;

// Return signed 0 if either 0.
if (!xc[0] || !yc[0]) return new Big(y.s * 0);
if (!xc[0] || !yc[0]) {
y.c = [y.e = 0];
return y;
}

// Initialise exponent of result as x.e + y.e.
y.e = i + j;
Expand Down
71 changes: 46 additions & 25 deletions big.mjs
Expand Up @@ -350,7 +350,11 @@ P.div = function (y) {
}

// Dividend is 0? Return +-0.
if (!a[0]) return new Big(k * 0);
if (!a[0]) {
y.s = k;
y.c = [y.e = 0];
return y;
}

var bl, bt, n, cmp, ri,
bz = b.slice(),
Expand Down Expand Up @@ -501,9 +505,14 @@ P.minus = P.sub = function (y) {

// Either zero?
if (!xc[0] || !yc[0]) {

// y is non-zero? x is non-zero? Or both are zero.
return yc[0] ? (y.s = -b, y) : new Big(xc[0] ? x : 0);
if (yc[0]) {
y.s = -b;
} else if (xc[0]) {
y = new Big(x);
} else {
y.s = 1;
}
return y;
}

// Determine which is the bigger number. Prepend zeros to equalise exponents.
Expand Down Expand Up @@ -619,15 +628,15 @@ P.mod = function (y) {
* Return a new Big whose value is the value of this Big plus the value of Big y.
*/
P.plus = P.add = function (y) {
var t,
var e, k, t,
x = this,
Big = x.constructor,
a = x.s,
b = (y = new Big(y)).s;
Big = x.constructor;

y = new Big(y);

// Signs differ?
if (a != b) {
y.s = -b;
if (x.s != y.s) {
y.s = -y.s;
return x.minus(y);
}

Expand All @@ -636,24 +645,33 @@ P.plus = P.add = function (y) {
ye = y.e,
yc = y.c;

// Either zero? y is non-zero? x is non-zero? Or both are zero.
if (!xc[0] || !yc[0]) return yc[0] ? y : new Big(xc[0] ? x : a * 0);
// Either zero?
if (!xc[0] || !yc[0]) {
if (!yc[0]) {
if (xc[0]) {
y = new Big(x);
} else {
y.s = x.s;
}
}
return y;
}

xc = xc.slice();

// Prepend zeros to equalise exponents.
// Note: reverse faster than unshifts.
if (a = xe - ye) {
if (a > 0) {
if (e = xe - ye) {
if (e > 0) {
ye = xe;
t = yc;
} else {
a = -a;
e = -e;
t = xc;
}

t.reverse();
for (; a--;) t.push(0);
for (; e--;) t.push(0);
t.reverse();
}

Expand All @@ -664,20 +682,20 @@ P.plus = P.add = function (y) {
xc = t;
}

a = yc.length;
e = yc.length;

// Only start adding at yc.length - 1 as the further digits of xc can be left as they are.
for (b = 0; a; xc[a] %= 10) b = (xc[--a] = xc[a] + yc[a] + b) / 10 | 0;
for (k = 0; e; xc[e] %= 10) k = (xc[--e] = xc[e] + yc[e] + k) / 10 | 0;

// No need to check for zero, as +x + +y != 0 && -x + -y != 0

if (b) {
xc.unshift(b);
if (k) {
xc.unshift(k);
++ye;
}

// Remove trailing zeros.
for (a = xc.length; xc[--a] === 0;) xc.pop();
for (e = xc.length; xc[--e] === 0;) xc.pop();

y.c = xc;
y.e = ye;
Expand All @@ -695,7 +713,7 @@ P.plus = P.add = function (y) {
*/
P.pow = function (n) {
var x = this,
one = new x.constructor(1),
one = new x.constructor('1'),
y = one,
isneg = n < 0;

Expand Down Expand Up @@ -759,7 +777,7 @@ P.sqrt = function () {
Big = x.constructor,
s = x.s,
e = x.e,
half = new Big(0.5);
half = new Big('0.5');

// Zero?
if (!x.c[0]) return new Big(x);
Expand All @@ -781,7 +799,7 @@ P.sqrt = function () {
e = ((e + 1) / 2 | 0) - (e < 0 || e & 1);
r = new Big((s == 1 / 0 ? '5e' : (s = s.toExponential()).slice(0, s.indexOf('e') + 1)) + e);
} else {
r = new Big(s);
r = new Big(s + '');
}

e = r.e + (Big.DP += 4);
Expand Down Expand Up @@ -814,7 +832,10 @@ P.times = P.mul = function (y) {
y.s = x.s == y.s ? 1 : -1;

// Return signed 0 if either 0.
if (!xc[0] || !yc[0]) return new Big(y.s * 0);
if (!xc[0] || !yc[0]) {
y.c = [y.e = 0];
return y;
}

// Initialise exponent of result as x.e + y.e.
y.e = i + j;
Expand Down

0 comments on commit 2ea2e75

Please sign in to comment.