Rust有128位整数,它们用数据类型i128
表示(无符号整数用u128
表示):
let a: i128 = 170141183460469231731687303715884105727;
Rust如何使这i128
个值在64位系统上工作;e、 g.它是如何计算这些数据的?
因为,据我所知,该值不能放入x86-64 CPU的一个寄存器中,编译器是否会以某种方式使用两个寄存器来表示一个i128
值?或者他们是在使用某种大整数 struct 来表示它们?
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位整数,目标是本机不支持它们的后端.