Will numeric comparison, between a BigInt and a Number, coerce one argument to BigInt, or coerce one argument to Number?
For example, in the following, is 3n coerced to 3, or is 1 coerced to 1n?
console.log(3n > 1) // true
Both operands appear to be converted to a "mathematical value" in 4.k of the IsLessThan abstract operation; a process that is designated ℝ in the specification.
I have no idea what this means, however.
I note that:
console.log(19_999_999_999_999_998 > 19_999_999_999_999_999n) // true
Perhaps the "mathematical value", ℝ, of 19,999,999,999,999,998, is the descriptor for the value 20,000,000,000,000,000, which is the closest possible IEEE754 representation?
I still don't understand if coercion can be said to occur, given that a Number can have a fractional component, and a BigInt cannot.
Will numeric comparison between a BigInt and a Number coerce one argument to BigInt, or coerce one argument to Number?
Neither. As you read in the spec, their mathematical values are compared.
Consider 2n < 2.4. If both were converted to BigInt, you'd either get an exception ("cannot convert non-integer to BigInt") or you'd get the result false because 2n is not smaller than 2n. But no, we get the result true because "ℝ(2n) < ℝ(2.4)" is "2 < 2.4" which is true.
Consider 9007199254740993n > 9007199254740992. If both were converted to Number values, you'd get the result false because 9007199254740993 is larger than the Number.MAX_SAFE_INTEGER and loses precision, becoming the number value 9007199254740992 which is not larger than 9007199254740992. But no, we get the result true because "ℝ(9007199254740993n) > ℝ(9007199254740992)" is "9007199254740993 > 9007199254740992" which is true.
Perhaps the "mathematical value", ℝ, is the closest possible IEEE754 representation?
No, that's the Number value for x, also denoted as 𝔽(x), which converts from a mathematical value (the real numbers) or extended mathematical value (the real numbers plus two infinities) to a concrete (IEEE 754 double-precision floating point) Number value. The mathematical values are abstract, and there are many real numbers that can neither be represented accurately as a BigInt or Number.
Because coercing between Number values and BigInt values can lead to loss of precision, the following are recommended:
Only use a BigInt value when values greater than 2^53 are reasonably expected. Don't coerce between BigInt values and Number values.
The BigInt is converted to a Number (which can lead to loss of precision).
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt
UPDATE:
For 3n > 1
Bytecode length: 11
Parameter count 6
Register count 2
Frame size 16
OSR nesting level: 0
Bytecode Age: 0
16 S> 0x28001122e @ 0 : 13 00 LdaConstant [0]
0x280011230 @ 2 : c2 Star1
0x280011231 @ 3 : 0d 01 LdaSmi [1]
20 E> 0x280011233 @ 5 : 6d f9 00 TestGreaterThan r1, [0]
0x280011236 @ 8 : c3 Star0
0x280011237 @ 9 : 0e LdaUndefined
24 S> 0x280011238 @ 10 : a8 Return
Constant pool (size = 1)
0x2800111c9: [FixedArray] in OldSpace
- map: 0x0a554d7412c1 <Map>
- length: 1
0: 0x0002800111e1 <BigInt 3>
Handler Table (size = 0)
Source Position Table (size = 8)
0x000280011241 <ByteArray[8]>
For TestGreaterThan, it looks like it compares two fixed arrays (BigInt & Int)