如何让Rust处理128位以上数字?解决斐波那契数列溢出问题
突破i128生成斐波那契数列的溢出限制方案
我用Rust写了一段循环生成斐波那契数列的代码,分别尝试过32位、64位、128位有符号整数变量,但128位变量最多只能生成到第182代,超过这个次数就会触发main panicked at 'attempt to add with overflow'的溢出错误。当前代码如下:
fn main() { let mut in1: i128 = 1; let mut in2: i128 = 1; let mut op1: i128; for iterations in 0..183 { // add the given numbers op1 = in1 + in2; // print the result println!("{}: {}", iterations + 1, op1); // prepare the next iterations in1 = in2; in2 = op1; // repeat } }
解决方案
改用无符号128位整数(u128)
有符号整数i128的最大值是2^127 - 1,而无符号u128的最大值是2^128 - 1,能多支持一代斐波那契数(到第183代)。只需修改变量类型即可:fn main() { let mut in1: u128 = 1; let mut in2: u128 = 1; let mut op1: u128; for iterations in 0..184 { op1 = in1 + in2; println!("{}: {}", iterations + 1, op1); in1 = in2; in2 = op1; } }使用任意精度大整数
如果需要生成更多代的斐波那契数,必须摆脱固定位数整数的限制,使用支持任意精度的大整数库。Rust标准库没有原生大整数,但可以借助num_bigintcrate实现:首先在
Cargo.toml中添加依赖:[dependencies] num-bigint = "0.4" num-traits = "0.2"然后修改代码:
use num_bigint::BigInt; use num_traits::One; fn main() { let mut in1: BigInt = One::one(); let mut in2: BigInt = One::one(); let mut op1: BigInt; // 这里可以设置任意大的迭代次数,比如1000代 for iterations in 0..1000 { op1 = &in1 + &in2; println!("{}: {}", iterations + 1, op1); in1 = in2; in2 = op1; } }这种方式只要内存足够,就能生成几乎无限多代的斐波那契数。
手动处理溢出(仅适用于非精度要求场景)
如果你只是想避免程序panic,不需要正确的大数结果,可以使用Rust的溢出运算符wrapping_add,它会在溢出时循环回到类型的最小值,但生成的结果是错误的,仅适合特定场景:fn main() { let mut in1: i128 = 1; let mut in2: i128 = 1; let mut op1: i128; for iterations in 0..200 { op1 = in1.wrapping_add(in2); println!("{}: {}", iterations + 1, op1); in1 = in2; in2 = op1; } }
内容的提问来源于stack exchange,提问作者Curious Chimpanzee
相关产品推荐
相关产品推荐

