Rust有128位整数,它们用数据类型i128表示(无符号整数用u128表示):

let a: i128 = 170141183460469231731687303715884105727;

Rust如何使这i128个值在64位系统上工作;e、 g.它是如何计算这些数据的?

因为,据我所知,该值不能放入x86-64 CPU的一个寄存器中,编译器是否会以某种方式使用两个寄存器来表示一个i128值?或者他们是在使用某种大整数 struct 来表示它们?

推荐答案

Rust的所有整数类型都编译为LLVM integers.LLVM抽象机允许1到2^23-1之间的任何位宽度的整数.*LLVM instructions通常处理任何大小的整数.

显然,没有太多8388607位的体系 struct ,所以当代码被编译成本机代码时,LLVM必须决定如何实现它.像add这样的抽象指令的语义是由LLVM本身定义的.通常,在本机代码中只有一条指令等效的抽象指令将被编译为该本机指令,而没有的抽象指令将被模拟,可能会有多条本机指令.mcarton's answer演示了LLVM如何编译本机指令和模拟指令.

(这不仅适用于大于本机所能支持的整数,也适用于较小的整数.例如,现代体系 struct 可能不支持本机8位算术,因此两个i8上的add指令可以用更宽的指令模拟,多余的位被丢弃.)

编译器是否会对一个i128值使用两个寄存器?或者他们使用某种大整数 struct 来表示他们?

在LLVM IR级别,答案是两者都不是:i128适合单个寄存器,就像其他single-valued type个寄存器一样.另一方面,一旦翻译成机器代码,两者之间就没有什么区别,因为 struct 可以像整数一样分解成寄存器.不过,在进行算术运算时,LLVM可以很安全地将整个内容加载到两个寄存器中.


*然而,并非所有LLVM后端都是平等创建的.这个答案与x86-64有关.我知道后端对大于128的大小和非二次幂的支持是不稳定的(这可能部分解释了为什么Rust只expose 8、16、32、64和128位整数).According to est31 on Reddit时,rustc在软件中实现128位整数,目标是本机不支持它们的后端.

Rust相关问答推荐

为什么复印是豆荚的一个重要特征?

什么是Rust惯用的方式来使特征向量具有单个向量项的别名?

Rust TcpStream不能在读取后写入,但可以在不读取的情况下写入.为什么?

使用模块中的所有模块,但不包括特定模块

如何go 除铁 rust 中路径组件的第一项和最后一项?

在IntoIter上调用.by_ref().Take().rev()时会发生什么情况

如何将映射反序列化为具有与键匹配的字段的定制 struct 的向量?

将serde_json读入`VEC<;T&>;`( rust 色)时出现问题

失真图像图形捕获Api

如何在Rust中缩短数组

我可以解构self 参数吗?

如何从 rust 中的同一父目录导入文件

有什么办法可以追踪泛型的单态化过程吗?

为什么不可变特征的实现可以是可变的?

为什么具有 Vec 变体的枚举没有内存开销?

用逗号分隔字符串,但在标记中使用逗号

Rust - 在线程之间不安全地共享没有互斥量的可变数据

火箭整流罩、tokio-scheduler 和 cron 的生命周期问题

为什么我可以在没有生命周期问题的情况下内联调用 iter 和 collect?

在 Rust 中组合特征的不同方法是否等效?