如何在 Rust 中将有符号整数与无符号整数相加?

Ale*_*xey 14 rust

我是否必须在有符号整数的符号上进行分支,如下例所示?(在真实的程序中y是计算改变索引指向为64K数组,而wraparound是期望的行为)

fn main() {
    let mut x: u16 = 100;
    let y: i8 = -1;
    //x += y;
    if y < 0 {
        x -= i8::abs(y) as u16;
    } else {
        x += i8::abs(y) as u16;
    }
    println!("{}", x);
}
Run Code Online (Sandbox Code Playgroud)

Zoe*_*wll 12

Rustc 1.66+ 支持一些混合整数运算。请注意,这之前在mix_integer_ops功能标志下不稳定。

有了这个你可以这样做:

fn main() {
    let mut x: u16 = 100;
    let y: i8 = -1;
    //x += y;
    x = x.wrapping_add_signed(y.into()); // wraps on overflow
    println!("{}", x);
}
Run Code Online (Sandbox Code Playgroud)

这些*_add_signed针对无符号整数的方法都接受有符号参数并返回无符号结果。有wrapping_checked_saturating_overflowing_变体,具体取决于您要如何具体处理溢出情况。

在有符号整数上也有类似的方法,用于加法或减法,它们接受无符号参数并返回有符号结果,名为*_add_unsigned*_sub_unsigned


kmk*_*lan 7

  • 有符号整数是二进制补码
  • 数字转换符号扩展了i8 as u16

这意味着您可以将其转换为二进制补码值,如果为负数,y as u16则wrapping_add将正确处理该值。y

简而言之:按照@Veedrac 所说的去做。

fn main() {
    let mut x: u16 = 100;
    let y: i8 = -1;
    x = x.wrapping_add(y as u16);
    println!("{}", x);
}
Run Code Online (Sandbox Code Playgroud)

  • @hello 介意详细说明吗?首先,这看起来更加复杂并且容易出错,其次在某些时候(`u128`)你就是不能。 (2认同)