gpt4 book ai didi

javascript - 为什么 Number ("x") == BigInt ("x") ... 只是有时?

转载 作者:行者123 更新时间:2023-12-04 11:04:35 31 4
gpt4 key购买 nike

我以为 JavaScript 的 loose equality运算符(operator)很好,让我将 Numbers 与 BigInts 进行比较:

42 == 42n  // true!
所以我尝试了一个大于 Number.MAX_SAFE_INTEGER 的数字.我认为由于数字会自动四舍五入,因此我可能还必须四舍五入 BigInt 才能使它们被视为相等:
9999999999999999 == 10000000000000000   // true - rounded to float64

9999999999999999 == 9999999999999999n // false - makes sense!
10000000000000000 == 9999999999999999n // false - makes sense!
9999999999999999 == 10000000000000000n // true - makes sense!
太好了,有道理——所以我尝试了另一个被四舍五入的大数字:
18446744073709551616 == 18446744073709552000   // true - rounded to float64

18446744073709551616 == 18446744073709551616n // true?!
18446744073709552000 == 18446744073709551616n // true?!
18446744073709551616 == 18446744073709552000n // false?!
我在 Chrome、Safari 和 Node.js 中观察到了相同的结果。
为什么这种行为不一致?是不是因为数字比较为 mathematical values ,这是什么意思?
bigint equality table

最佳答案

不一致是因为 Number::toString abstract operation未指定。
您的问题归结为 BigInt(String(x))BigInt(x) ,这可能被认为是整数 x 的等式但事实上并非如此。
在您的特定情况下,对于 x=18446744073709551616x=18446744073709552000 (或介于两者之间的任何东西,甚至有点左右),数字的字符串表示会产生 '18446744073709552000'而精确的数学值是 18446744073709551616。(我们知道这一点是因为 NumberToBigInt operation 是精确的 - 它为您提供数字的数学值,如果不是整数则为错误)。
我们还在 Number.prototype.toFixed 上找到以下注释:

The output of toFixed may be more precise than toString for some values because toString only prints enough significant digits to distinguish the number from adjacent Number values. For example,

(1000000000000000128).toString() returns "1000000000000000100", while
(1000000000000000128).toFixed(0) returns "1000000000000000128".



回答名义上的问题

Why does Number(“x”) == BigInt(“x”) … only sometimes?


这是因为浮点数值的精度有限。有多个数字文字被解析为完全相同的数字。与您的第一个示例类似,让我们使用 bigint 20000000000000000n .有一个具有相同数学值的浮点数,具体 +1 × 0b10001110000110111100100110111111000001 × 2 0b10001= 1 × 152587890625 × 217
= 20000000000000000
有多个整数字面值可以计算为这个 Number 值: 19999999999999998 , 19999999999999999 , 20000000000000000 , 20000000000000001 , 和 20000000000000002 . (注意它并不总是四舍五入)。当您将这些作为字符串并使用一元 + 时,也会发生这种情况。或 Number在他们。
但是,如果您使用具有相同文本表示的各个 bigint 文字,它们将评估为 5 个不同的 BigInt 值。 只有一个其中将 compare equal (with == ) to,即具有与 Number 值相同的数学值。
这是一致的:总是有一个,它可以精确地表示为一个浮点数。

Why isn't this behavior consistent?


您的困惑来自数字值 18446744073709551616 的字符串表示形式。打印数字文字时 18446744073709551616 , 或 +'18446744073709551616' , 你得到 18446744073709552000 (因为控制台在内部使用 String()/ .toString()),这使您假设 18446744073709552000 是它的数学值,而 18446744073709552000n应该比较等于它。但这不是:-/

console.log(18446744073709551616..toString());
console.log(18446744073709551616..toFixed());
console.log(18446744073709552000..toString());
console.log(18446744073709552000..toFixed());

相信哪个?

关于javascript - 为什么 Number ("x") == BigInt ("x") ... 只是有时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68108016/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com