如何在Rust中将有符号整数添加到无符号整数?

时间:2018-11-23 22:46:35

标签: rust

我是否必须像下面的示例中那样对有符号整数的符号进行分支? (在实际程序中,y的计算是将指向64K数组的索引更改为索引,而环绕操作是所需的行为)

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);
}

2 个答案:

答案 0 :(得分:1)

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

这意味着您可以强制转换y as u16,如果y为负,则将变成一个二进制补码值,wraping_add将正确处理该值。

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

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

答案 1 :(得分:0)

  

在真实程序中,y的计算是将指向64K数组的索引更改为索引,而回绕是所需的行为)

目前尚无共识,但我的建议是:向用户提供两个功能:

fn add(&mut self, index: u16) -> u16 { // return previous index why not
    // ..
}

fn sub(&mut self, index: u16) -> u16 {
    // ..
}

您还可以添加一个不应轻易使用的辅助功能:

fn offset(&mut self, offset: i16) -> u16 {
    // ..
}

目的是,用户应该知道每当使用sub或add时,用户应该只管理未签名的类型。这个问题是基于观点的,所以我理解人们是否同意。

完整示例:

use std::mem;

#[derive(Debug, PartialEq, PartialOrd)]
struct MyIndex {
    index: u16,
}

impl MyIndex {
    fn new(index: u16) -> Self {
        Self { index }
    }

    fn add(&mut self, index: u16) -> u16 {
        let index = self.index.wrapping_add(index);
        self.replace(index)
    }

    fn sub(&mut self, index: u16) -> u16 {
        let index = self.index.wrapping_sub(index);
        self.replace(index)
    }

    fn offset(&mut self, offset: i16) -> u16 {
        if offset > 0 {
            self.add(offset as u16)
        } else {
            self.sub(offset as u16)
        }
    }

    fn replace(&mut self, index: u16) -> u16 {
        mem::replace(&mut self.index, index)
    }
}

fn main() {
    let mut index = MyIndex::new(42);

    let mut other_index = MyIndex::new(84);

    let (x, first) = if index > other_index {
        (index.index - other_index.index, true)
    }
    else {
        (other_index.index - index.index, false)
    };

    // ...

    if first {
        index.sub(x);
    }
    else {
        other_index.sub(x);
    }
    println!("{:?} {:?}", index, other_index);

    index.sub(21);
    println!("{:?}", index);

    index.offset(-1);
    println!("{:?}", index);
}