fn diapason(amount_bits: u32) -> [i128; 2] {
let x:i128 = 2;
[-x.pow(amount_bits - 1), x.pow(amount_bits - 1) - 1]
}
fn signed_and_unsigned_int() {
let set_bits:[u32; 5] = [8, 16, 32, 64, 128];
for i in set_bits {
println!("i{} can store [{}, {}]", i,
diapason(i)[0], diapason(i)[1])
}
}
fn main() {
signed_and_unsigned_int()
}
美好的一天,我开始学习 Rust 并遇到了一个错误(线程“main”因“试图乘以溢出”而恐慌)。我不明白为什么数字“2 的 128 次方”不适合 i128 类型?
C:/Users/HOME/.cargo/bin/cargo.exe run --color=always --package start_learning --bin start_learning
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `target\debug\start_learning.exe`
i8 can store [-128, 127]
i16 can store [-32768, 32767]
i32 can store [-2147483648, 2147483647]
i64 can store [-9223372036854775808, 9223372036854775807]
thread 'main' panicked at 'attempt to multiply with overflow', C:\Users\HOME\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\num\mod.rs:119:5
stack backtrace:
0: std::panicking::begin_panic_handler
at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b\/library\std\src\panicking.rs:493
1: core::panicking::panic_fmt
at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b\/library\core\src\panicking.rs:92
2: core::panicking::panic
at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b\/library\core\src\panicking.rs:50
3: core::num::{{impl}}::pow
at C:\Users\HOME\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\num\int_macros.rs:1586
4: start_learning::diapason
at .\src\main.rs:4
5: start_learning::signed_and_unsigned_int
at .\src\main.rs:12
6: start_learning::main
at .\src\main.rs:17
7: core::ops::function::FnOnce::call_once<fn(),tuple<>>
at C:\Users\HOME\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:227
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
error: process didn't exit successfully: `target\debug\start_learning.exe` (exit code: 101)
进程以退出代码 101 结束
的最大值i128
确实是2¹²⁷-1
,小于2¹²⁷
。所以“2 的 127 次方”不适合 i128 类型是正确的。
由于您要计算x.pow(amount_bits - 1) - 1
,因此您需要先计算x.pow(amount_bits - 1)
,然后再尝试计算2¹²⁷
。所有中间值也需要适合i128
,而不仅仅是最终结果。同样,您正在尝试计算-x.pow(amount_bits - 1)
,首先需要x.pow(amount_bits - 1)
再次计算哪个不适合 a i128
。
该公式amount_bits
最多适用于 64,因为您在 a 中计算结果i128
,这对于 来说足够大2⁶⁴
,但它在 128 处溢出。
通过一些简单的数学运算,您可以更改为:
fn diapason(amount_bits: u32) -> [i128; 2] {
let x:i128 = 2;
[-2*x.pow(amount_bits - 2), 2*(x.pow(amount_bits - 2) - 1) + 1]
}
这些使用以下一些简单的数学运算,其中间结果更小并且永远不会溢出 i128:
-2**n == -2*(2 ** (n-1))
2**n-1 == 2**n - 2 + 1 == 2*(2 ** (n-1) - 1) + 1
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句