Skip to content

Commit 2ea2e75

Browse files
committed
#148 Bugfix: primitive numbers passed to constructor internally in strict mode
1 parent 5810376 commit 2ea2e75

File tree

2 files changed

+92
-50
lines changed

2 files changed

+92
-50
lines changed

big.js

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,11 @@
353353
}
354354

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

358362
var bl, bt, n, cmp, ri,
359363
bz = b.slice(),
@@ -504,9 +508,14 @@
504508

505509
// Either zero?
506510
if (!xc[0] || !yc[0]) {
507-
508-
// y is non-zero? x is non-zero? Or both are zero.
509-
return yc[0] ? (y.s = -b, y) : new Big(xc[0] ? x : 0);
511+
if (yc[0]) {
512+
y.s = -b;
513+
} else if (xc[0]) {
514+
y = new Big(x);
515+
} else {
516+
y.s = 1;
517+
}
518+
return y;
510519
}
511520

512521
// Determine which is the bigger number. Prepend zeros to equalise exponents.
@@ -622,15 +631,15 @@
622631
* Return a new Big whose value is the value of this Big plus the value of Big y.
623632
*/
624633
P.plus = P.add = function (y) {
625-
var t,
634+
var e, k, t,
626635
x = this,
627-
Big = x.constructor,
628-
a = x.s,
629-
b = (y = new Big(y)).s;
636+
Big = x.constructor;
637+
638+
y = new Big(y);
630639

631640
// Signs differ?
632-
if (a != b) {
633-
y.s = -b;
641+
if (x.s != y.s) {
642+
y.s = -y.s;
634643
return x.minus(y);
635644
}
636645

@@ -639,24 +648,33 @@
639648
ye = y.e,
640649
yc = y.c;
641650

642-
// Either zero? y is non-zero? x is non-zero? Or both are zero.
643-
if (!xc[0] || !yc[0]) return yc[0] ? y : new Big(xc[0] ? x : a * 0);
651+
// Either zero?
652+
if (!xc[0] || !yc[0]) {
653+
if (!yc[0]) {
654+
if (xc[0]) {
655+
y = new Big(x);
656+
} else {
657+
y.s = x.s;
658+
}
659+
}
660+
return y;
661+
}
644662

645663
xc = xc.slice();
646664

647665
// Prepend zeros to equalise exponents.
648666
// Note: reverse faster than unshifts.
649-
if (a = xe - ye) {
650-
if (a > 0) {
667+
if (e = xe - ye) {
668+
if (e > 0) {
651669
ye = xe;
652670
t = yc;
653671
} else {
654-
a = -a;
672+
e = -e;
655673
t = xc;
656674
}
657675

658676
t.reverse();
659-
for (; a--;) t.push(0);
677+
for (; e--;) t.push(0);
660678
t.reverse();
661679
}
662680

@@ -667,20 +685,20 @@
667685
xc = t;
668686
}
669687

670-
a = yc.length;
688+
e = yc.length;
671689

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

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

677-
if (b) {
678-
xc.unshift(b);
695+
if (k) {
696+
xc.unshift(k);
679697
++ye;
680698
}
681699

682700
// Remove trailing zeros.
683-
for (a = xc.length; xc[--a] === 0;) xc.pop();
701+
for (e = xc.length; xc[--e] === 0;) xc.pop();
684702

685703
y.c = xc;
686704
y.e = ye;
@@ -698,7 +716,7 @@
698716
*/
699717
P.pow = function (n) {
700718
var x = this,
701-
one = new x.constructor(1),
719+
one = new x.constructor('1'),
702720
y = one,
703721
isneg = n < 0;
704722

@@ -762,7 +780,7 @@
762780
Big = x.constructor,
763781
s = x.s,
764782
e = x.e,
765-
half = new Big(0.5);
783+
half = new Big('0.5');
766784

767785
// Zero?
768786
if (!x.c[0]) return new Big(x);
@@ -784,7 +802,7 @@
784802
e = ((e + 1) / 2 | 0) - (e < 0 || e & 1);
785803
r = new Big((s == 1 / 0 ? '5e' : (s = s.toExponential()).slice(0, s.indexOf('e') + 1)) + e);
786804
} else {
787-
r = new Big(s);
805+
r = new Big(s + '');
788806
}
789807

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

819837
// Return signed 0 if either 0.
820-
if (!xc[0] || !yc[0]) return new Big(y.s * 0);
838+
if (!xc[0] || !yc[0]) {
839+
y.c = [y.e = 0];
840+
return y;
841+
}
821842

822843
// Initialise exponent of result as x.e + y.e.
823844
y.e = i + j;

big.mjs

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,11 @@ P.div = function (y) {
350350
}
351351

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

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

502506
// Either zero?
503507
if (!xc[0] || !yc[0]) {
504-
505-
// y is non-zero? x is non-zero? Or both are zero.
506-
return yc[0] ? (y.s = -b, y) : new Big(xc[0] ? x : 0);
508+
if (yc[0]) {
509+
y.s = -b;
510+
} else if (xc[0]) {
511+
y = new Big(x);
512+
} else {
513+
y.s = 1;
514+
}
515+
return y;
507516
}
508517

509518
// Determine which is the bigger number. Prepend zeros to equalise exponents.
@@ -619,15 +628,15 @@ P.mod = function (y) {
619628
* Return a new Big whose value is the value of this Big plus the value of Big y.
620629
*/
621630
P.plus = P.add = function (y) {
622-
var t,
631+
var e, k, t,
623632
x = this,
624-
Big = x.constructor,
625-
a = x.s,
626-
b = (y = new Big(y)).s;
633+
Big = x.constructor;
634+
635+
y = new Big(y);
627636

628637
// Signs differ?
629-
if (a != b) {
630-
y.s = -b;
638+
if (x.s != y.s) {
639+
y.s = -y.s;
631640
return x.minus(y);
632641
}
633642

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

639-
// Either zero? y is non-zero? x is non-zero? Or both are zero.
640-
if (!xc[0] || !yc[0]) return yc[0] ? y : new Big(xc[0] ? x : a * 0);
648+
// Either zero?
649+
if (!xc[0] || !yc[0]) {
650+
if (!yc[0]) {
651+
if (xc[0]) {
652+
y = new Big(x);
653+
} else {
654+
y.s = x.s;
655+
}
656+
}
657+
return y;
658+
}
641659

642660
xc = xc.slice();
643661

644662
// Prepend zeros to equalise exponents.
645663
// Note: reverse faster than unshifts.
646-
if (a = xe - ye) {
647-
if (a > 0) {
664+
if (e = xe - ye) {
665+
if (e > 0) {
648666
ye = xe;
649667
t = yc;
650668
} else {
651-
a = -a;
669+
e = -e;
652670
t = xc;
653671
}
654672

655673
t.reverse();
656-
for (; a--;) t.push(0);
674+
for (; e--;) t.push(0);
657675
t.reverse();
658676
}
659677

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

667-
a = yc.length;
685+
e = yc.length;
668686

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

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

674-
if (b) {
675-
xc.unshift(b);
692+
if (k) {
693+
xc.unshift(k);
676694
++ye;
677695
}
678696

679697
// Remove trailing zeros.
680-
for (a = xc.length; xc[--a] === 0;) xc.pop();
698+
for (e = xc.length; xc[--e] === 0;) xc.pop();
681699

682700
y.c = xc;
683701
y.e = ye;
@@ -695,7 +713,7 @@ P.plus = P.add = function (y) {
695713
*/
696714
P.pow = function (n) {
697715
var x = this,
698-
one = new x.constructor(1),
716+
one = new x.constructor('1'),
699717
y = one,
700718
isneg = n < 0;
701719

@@ -759,7 +777,7 @@ P.sqrt = function () {
759777
Big = x.constructor,
760778
s = x.s,
761779
e = x.e,
762-
half = new Big(0.5);
780+
half = new Big('0.5');
763781

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

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

816834
// Return signed 0 if either 0.
817-
if (!xc[0] || !yc[0]) return new Big(y.s * 0);
835+
if (!xc[0] || !yc[0]) {
836+
y.c = [y.e = 0];
837+
return y;
838+
}
818839

819840
// Initialise exponent of result as x.e + y.e.
820841
y.e = i + j;

0 commit comments

Comments
 (0)