Bug 1558538 - Add tests of converting BigInt around and exceeding Number.MAX_VALUE to Number. r=wingo
authorJeff Walden <jwalden@mit.edu>
Thu, 20 Jun 2019 15:57:09 +0000
changeset 479313 30bd16cacdb636ee82c499c3acb99e7a2702fe7e
parent 479312 74e7a89b8d26daebae7c0a622cce47747e2c81b7
child 479314 3224107774b1fa55a9a0f70ebf656dca2838b840
push id36178
push useraiakab@mozilla.com
push dateThu, 20 Jun 2019 21:50:59 +0000
treeherdermozilla-central@74b3b3d1544c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswingo
bugs1558538
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1558538 - Add tests of converting BigInt around and exceeding Number.MAX_VALUE to Number. r=wingo Differential Revision: https://phabricator.services.mozilla.com/D35369
js/src/tests/non262/BigInt/Number-conversion-rounding.js
--- a/js/src/tests/non262/BigInt/Number-conversion-rounding.js
+++ b/js/src/tests/non262/BigInt/Number-conversion-rounding.js
@@ -1,13 +1,71 @@
 // |reftest| skip-if(!this.hasOwnProperty("BigInt"))
 // Any copyright is dedicated to the Public Domain.
 // https://creativecommons.org/licenses/publicdomain/
 
 /**
+ * Edge-case behavior at Number.MAX_VALUE and beyond til overflow to Infinity.
+ */
+function maxMagnitudeTests(isNegative)
+{
+  var sign = isNegative ? -1 : +1;
+  var signBigInt = isNegative ? -1n : 1n;
+
+  const MAX_VALUE = isNegative ? -Number.MAX_VALUE : +Number.MAX_VALUE;
+
+  // 2**971+2**972+...+2**1022+2**1023
+  var maxMagnitudeNumber = 0;
+  for (let i = 971; i < 1024; i++)
+    maxMagnitudeNumber += 2**i;
+  maxMagnitudeNumber *= sign;
+  assertEq(maxMagnitudeNumber, MAX_VALUE);
+
+  // 2**971+2**972+...+2**1022+2**1023
+  var maxMagnitudeNumberAsBigInt = 0n;
+  for (let i = 971n; i < 1024n; i++)
+    maxMagnitudeNumberAsBigInt += 2n**i;
+  maxMagnitudeNumberAsBigInt *= signBigInt;
+  var expectedMaxMagnitude = isNegative
+                           ? -(2n**1024n) + 2n**971n
+                           : 2n**1024n - 2n**971n;
+  assertEq(maxMagnitudeNumberAsBigInt, expectedMaxMagnitude);
+
+  // Initial sanity tests.
+  assertEq(BigInt(maxMagnitudeNumber), maxMagnitudeNumberAsBigInt);
+  assertEq(maxMagnitudeNumber, Number(maxMagnitudeNumberAsBigInt));
+
+  // Test conversion of BigInt values above Number.MAX_VALUE.
+  assertEq(Number(maxMagnitudeNumberAsBigInt + signBigInt * 1n), MAX_VALUE);
+  assertEq(Number(maxMagnitudeNumberAsBigInt + signBigInt * 2n), MAX_VALUE);
+  assertEq(Number(maxMagnitudeNumberAsBigInt + signBigInt * 3n), MAX_VALUE);
+  assertEq(Number(maxMagnitudeNumberAsBigInt + signBigInt * 4n), MAX_VALUE);
+  assertEq(Number(maxMagnitudeNumberAsBigInt + signBigInt * 5n), MAX_VALUE);
+  assertEq(Number(maxMagnitudeNumberAsBigInt + signBigInt * 6n), MAX_VALUE);
+  assertEq(Number(maxMagnitudeNumberAsBigInt + signBigInt * 7n), MAX_VALUE);
+  assertEq(Number(maxMagnitudeNumberAsBigInt + signBigInt * 8n), MAX_VALUE);
+  assertEq(Number(maxMagnitudeNumberAsBigInt + signBigInt * 9n), MAX_VALUE);
+  assertEq(Number(maxMagnitudeNumberAsBigInt + signBigInt * 2n**20n), MAX_VALUE);
+  assertEq(Number(maxMagnitudeNumberAsBigInt + signBigInt * 2n**400n), MAX_VALUE);
+  assertEq(Number(maxMagnitudeNumberAsBigInt + signBigInt * 2n**800n), MAX_VALUE);
+  assertEq(Number(maxMagnitudeNumberAsBigInt + signBigInt * 2n**900n), MAX_VALUE);
+  assertEq(Number(maxMagnitudeNumberAsBigInt + signBigInt * 2n**969n), MAX_VALUE);
+
+  // For conversion purposes, rounding for values above Number.MAX_VALUE do
+  // rounding with respect to Number.MAX_VALUE and 2**1024 (which is treated as
+  // the "even" value -- so if the value to convert lies halfway between those two
+  // values, 2**1024 is selected).  But if 2**1024 is the value that *would* have
+  // been chosen by this process, Infinity is substituted.
+  assertEq(Number(maxMagnitudeNumberAsBigInt + signBigInt * (2n**970n - 1n)), MAX_VALUE);
+  assertEq(Number(maxMagnitudeNumberAsBigInt + signBigInt * 2n**970n), sign * Infinity);
+}
+maxMagnitudeTests(false);
+maxMagnitudeTests(true);
+
+/**
  * Simple single-Digit on x64, double-Digit on x86 tests.
  */
 
 assertEq(BigInt(Number(2n**53n - 2n)), 2n**53n - 2n);
 assertEq(BigInt(Number(2n**53n - 1n)), 2n**53n - 1n);
 assertEq(BigInt(Number(2n**53n)), 2n**53n);
 assertEq(BigInt(Number(2n**53n + 1n)), 2n**53n);
 assertEq(BigInt(Number(2n**53n + 2n)), 2n**53n + 2n);