javascript - V8(或其他 JS 引擎)BigInt 实现 - 显示为十进制

标签 javascript v8 bigint spidermonkey

我想知道是否有人能够向我解释 JavaScript BigInt 实现的特定方面。

我理解的概述实现 - 不是在基数 10 中操作,而是构建一个表示数字的数组,该数组根据构建架构在基数 2^32/2^64 中有效操作。

我很好奇的是这种类型的 display/console.log 实现 - 对于大多数常见情况来说它的速度非常快,以至于如果您对实现一无所知你可能会认为它是原生的。但是,知道我对实现做了什么,它能够尽可能快地执行十进制转换/字符串连接数学,这对我来说是令人难以置信的,而且我很好奇它是如何工作的。

适度审视bigint.ccbigint.h Chromium 源代码中的内容只会让我更加困惑,因为有许多方法的签名已定义,但我似乎找不到其实现。

如果有人指出 Chromium 源代码中包含十进制转换实现的另一个位置,我会很感激。

最佳答案

(这里是 V8 开发人员。)

@Bergi 基本上已经提供了相关链接,所以总结一下:

将二进制数格式化为十进制字符串是一种“基本转换”,其基本构建 block 是:

while (number > 0) {
  next_char = "0123456789"[number % 10];
  number = number / 10;  // Truncating integer division.
}

(假设 next_char 也被写入某个字符串后备存储中;该字符串是从右侧构建的。)

针对 BigInt 一开始只有一个 64 位“数字”的常见情况的特殊情况,您可以在代码 here 中找到该算法。

更多数字和非十进制基数的泛化是 here ;这是相同的算法。

对于足够小的 BigInt,该算法运行得足够快;它的问题是它与 BigInt 的长度呈二次方缩放。因此,对于大型 BigInt(由于能够实现更好的扩展,一些初始开销很容易收回),我们有一个基于更好扩展的 divide-and-conquer implementationdivision 算法构建的 multiplication

当请求的基数是 2 的幂时,则不需要这样的重型机械,因为线性时间实现是 easy 。这就是为什么 some_bigint.toString(16) 总是比 some_bigint.toString() 快得多(至少对于大型 BigInt),因此当您需要反/序列化时十六进制字符串比人类可读性更适合性能。

if you didn't know anything about the implementation you'd probably assume it was native

这是什么意思?

关于javascript - V8(或其他 JS 引擎)BigInt 实现 - 显示为十进制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75272534/

相关文章:

c++ - 运算符==重载

java - Java 的 Long 可以保存 SQL BIGINT(20) 值吗?

javascript - 逐行淡入

javascript - 以编程方式访问函数位置

javascript - Javascript V8 中对象引用的大小

java - Google V8 的工作方式与 Java 虚拟机类似吗?

javascript - BigInt 模 float

javascript - Node.js 提供 HTML,但无法在提供的页面中加载脚本文件

javascript - 是否可以在Electron中禁用failIfMajorPerformanceCaveat安全措施?

javascript - 如何查找具有特定 data- 属性的所有标签?