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();