tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

bigint-compare-int32.js (6232B)


      1 // Extensive test for (BigInt R Int32) comparison operations, testing the output
      2 // is correct and consistent with (Int32 R⁻¹ BigInt).
      3 
      4 function gcd(a, b) {
      5  a |= 0;
      6  b |= 0;
      7  while (b !== 0) {
      8    [a, b] = [b, a % b];
      9  }
     10  return Math.abs(a);
     11 }
     12 
     13 const ITERATIONS = 150;
     14 
     15 function assertAllCombinationsTested(xs, ys, n) {
     16  // If the array lengths are relatively prime and their product is at least
     17  // |n| long, all possible combinations are tested at least once. Make sure
     18  // we test each combination at least three times.
     19  var m = 3;
     20 
     21  assertEq(gcd(xs.length, ys.length), 1);
     22  assertEq(m * xs.length * ys.length <= n, true);
     23 }
     24 
     25 function LessThan(xs, ys, n = ITERATIONS) {
     26  assertAllCombinationsTested(xs, ys, n);
     27  for (var i = 0; i < n; ++i) {
     28    var x = xs[i % xs.length];
     29    var y = ys[i % ys.length]|0; // Ensure int32 typed
     30 
     31    assertEq(x == y, false);
     32    assertEq(y == x, false);
     33 
     34    assertEq(x != y, true);
     35    assertEq(y != x, true);
     36 
     37    assertEq(x < y, true);
     38    assertEq(y < x, false);
     39 
     40    assertEq(x <= y, true);
     41    assertEq(y <= x, false);
     42 
     43    assertEq(x > y, false);
     44    assertEq(y > x, true);
     45 
     46    assertEq(x >= y, false);
     47    assertEq(y >= x, true);
     48  }
     49 }
     50 
     51 function GreaterThan(xs, ys, n = ITERATIONS) {
     52  assertAllCombinationsTested(xs, ys, n);
     53  for (var i = 0; i < n; ++i) {
     54    var x = xs[i % xs.length];
     55    var y = ys[i % ys.length]|0; // Ensure int32 typed
     56 
     57    assertEq(x == y, false);
     58    assertEq(y == x, false);
     59 
     60    assertEq(x != y, true);
     61    assertEq(y != x, true);
     62 
     63    assertEq(x < y, false);
     64    assertEq(y < x, true);
     65 
     66    assertEq(x <= y, false);
     67    assertEq(y <= x, true);
     68 
     69    assertEq(x > y, true);
     70    assertEq(y > x, false);
     71 
     72    assertEq(x >= y, true);
     73    assertEq(y >= x, false);
     74  }
     75 }
     76 
     77 function Equal(xs, ys, n = ITERATIONS) {
     78  assertAllCombinationsTested(xs, ys, n);
     79  for (var i = 0; i < n; ++i) {
     80    var x = xs[i % xs.length];
     81    var y = ys[i % ys.length]|0; // Ensure int32 typed
     82 
     83    assertEq(x == y, true);
     84    assertEq(y == x, true);
     85 
     86    assertEq(x != y, false);
     87    assertEq(y != x, false);
     88 
     89    assertEq(x < y, false);
     90    assertEq(y < x, false);
     91 
     92    assertEq(x <= y, true);
     93    assertEq(y <= x, true);
     94 
     95    assertEq(x > y, false);
     96    assertEq(y > x, false);
     97 
     98    assertEq(x >= y, true);
     99    assertEq(y >= x, true);
    100  }
    101 }
    102 
    103 function test(fn) {
    104  // Clone the test function to ensure a new function is compiled each time.
    105  return Function(`return ${fn}`)();
    106 }
    107 
    108 const negativeInt32 = [-2147483648, -2147483647, -1];
    109 const zeroInt32 = [0];
    110 const positiveInt32 = [1, 2147483646, 2147483647];
    111 const zeroOrPositiveInt32 = [...zeroInt32, ...positiveInt32];
    112 const anyInt32 = [...negativeInt32, ...zeroInt32, ...positiveInt32];
    113 
    114 // Test when the BigInt is too large to be representable as a single BigInt digit.
    115 function testLarge() {
    116  var xs = [
    117    2n ** 32n, // exceeds single digit limit on 32-bit
    118    2n ** 64n, // exceeds single digit limit on 64-bit
    119    2n ** 96n, // not a single digit on either platform
    120  ];
    121  test(GreaterThan)(xs, anyInt32);
    122 
    123  var xs = [
    124    -(2n ** 32n), // exceeds single digit limit on 32-bit
    125    -(2n ** 64n), // exceeds single digit limit on 64-bit
    126    -(2n ** 96n), // not a single digit on either platform
    127  ];
    128  test(LessThan)(xs, anyInt32);
    129 }
    130 testLarge();
    131 
    132 // Test when the BigInt is 0n.
    133 function testZero() {
    134  var xs = [
    135    0n
    136  ];
    137 
    138  test(GreaterThan)(xs, negativeInt32);
    139  test(Equal)(xs, zeroInt32);
    140  test(LessThan)(xs, positiveInt32);
    141 }
    142 testZero();
    143 
    144 // Test when both numbers are negative.
    145 function testNegative() {
    146  var xs = [
    147    -(2n ** 64n) - 2n,
    148    -(2n ** 64n) - 1n, // Max negative using a single BigInt digit on 64-bit.
    149    -(2n ** 64n),
    150 
    151    -(2n ** 32n) - 2n,
    152    -(2n ** 32n) - 1n, // Max negative using a single BigInt digit on 32-bit.
    153    -(2n ** 32n),
    154 
    155    -(2n ** 31n) - 1n, // One past max negative for Int32.
    156  ];
    157  test(LessThan)(xs, negativeInt32);
    158 
    159  var xs = [
    160    -(2n ** 31n), // Max negative for Int32.
    161  ];
    162  test(Equal)(xs, [-2147483648]);
    163  test(LessThan)(xs, [-2147483647, -1]);
    164 
    165  var xs = [
    166    -(2n ** 31n) + 1n,
    167  ];
    168  test(GreaterThan)(xs, [-2147483648]);
    169  test(Equal)(xs, [-2147483647]);
    170  test(LessThan)(xs, [-1]);
    171 
    172  var xs = [
    173    -1n,
    174  ];
    175  test(GreaterThan)(xs, [-2147483648, -2147483647]);
    176  test(Equal)(xs, [-1]);
    177 }
    178 testNegative();
    179 
    180 // Test when both numbers are positive (and BigInt strictly positive).
    181 function testPositive() {
    182  var xs = [
    183    1n,
    184  ];
    185  test(GreaterThan)(xs, [0]);
    186  test(Equal)(xs, [1]);
    187  test(LessThan)(xs, [2147483646, 2147483647]);
    188 
    189  var xs = [
    190    2n ** 31n - 2n,
    191  ];
    192  test(GreaterThan)(xs, [0, 1]);
    193  test(Equal)(xs, [2147483646]);
    194  test(LessThan)(xs, [2147483647]);
    195 
    196  var xs = [
    197    2n ** 31n - 1n, // Max positive for Int32.
    198  ];
    199  test(GreaterThan)(xs, [0, 1, 2147483646]);
    200  test(Equal)(xs, [2147483647]);
    201 
    202  var xs = [
    203    2n ** 31n, // One past max positive for Int32.
    204 
    205    2n ** 32n - 2n,
    206    2n ** 32n - 1n, // Max positive using a single BigInt digit on 32-bit.
    207    2n ** 32n,
    208 
    209    2n ** 64n - 2n,
    210    2n ** 64n - 1n, // Max positive using a single BigInt digit on 64-bit.
    211    2n ** 64n,
    212  ];
    213  test(GreaterThan)(xs, zeroOrPositiveInt32);
    214 }
    215 testPositive();
    216 
    217 // Test negative BigInt and positive Int32.
    218 function testNegativePositive() {
    219  var xs = [
    220    -(2n ** 64n) - 2n,
    221    -(2n ** 64n) - 1n, // Max negative using a single BigInt digit on 64-bit.
    222    -(2n ** 64n),
    223 
    224    -(2n ** 32n) - 2n,
    225    -(2n ** 32n) - 1n, // Max negative using a single BigInt digit on 32-bit.
    226    -(2n ** 32n),
    227 
    228    -(2n ** 31n) - 1n,
    229    -(2n ** 31n), // Max negative for Int32.
    230    -(2n ** 31n) + 1n,
    231 
    232    -2n, // Extra entry to ensure assertAllCombinationsTested passes.
    233    -1n,
    234  ];
    235  test(LessThan)(xs, zeroOrPositiveInt32);
    236 }
    237 testNegativePositive();
    238 
    239 // Test (strictly) positive BigInt and negative Int32.
    240 function testPositiveNegative() {
    241  var xs = [
    242    1n,
    243 
    244    2n ** 31n - 2n,
    245    2n ** 31n - 1n, // Max positive for Int32.
    246    2n ** 31n,
    247 
    248    2n ** 32n - 2n,
    249    2n ** 32n - 1n, // Max positive using a single BigInt digit on 32-bit.
    250    2n ** 32n,
    251 
    252    2n ** 64n - 2n,
    253    2n ** 64n - 1n, // Max positive using a single BigInt digit on 64-bit.
    254    2n ** 64n,
    255  ];
    256  test(GreaterThan)(xs, negativeInt32);
    257 }
    258 testPositiveNegative();