Rust 中的数据类型

两K之战
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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章