Rust 中的 128 位 (a * b) / c 具有幻象溢出保护

rea*_*dul 5 integer-overflow rust solidity

令a、b 和c 为128 位数字。a * b当中间值溢出 128 位时,就会发生幻像溢出。然而,除法后的最终结果numerator / c可以容纳 128 位。

对于 64 位及更小的数字,可以转换为 128 位或使用muldiv crate。对于 128 位数字执行此操作的最佳方法是什么?问题是:

  • Rust 没有大于 128 位的本机类型
  • muldiv crate 不支持 128 位

参考资料-Remco Bloemen 的 muldiv in Solidity

hkB*_*Bst 1

两个 128 位数字相乘会得到 256 位输出。可能有一条汇编指令可以让您获取这些位。

或者,您可以将每个 128 位整数分成上半部分 64 位和下半部分 64 位。将这些一半相乘会得到最多 128 位的输出,因此可以在 128 位整数中完成。

(a_up*2^64 + a_lo) * (b_up*2^64 + b_lo) = a_up*b_up*2^128 + a_up*b_lo*2^64 + a_lo*b_up*2^64 + a_lo*b_lo
Run Code Online (Sandbox Code Playgroud)

因此,高 128 位为a_up*b_up*2^128 + (a_up*b_lo*2^64 + a_lo*b_up*2^64)_up,低 128 位为(a_up*b_lo*2^64 + a_lo*b_up*2^64 + a_lo*b_lo)_lo

然后你只需要将这个 256 位结果除以 c...