簡體   English   中英

如何在 Rust 中將已簽名的 integer 添加到未簽名的 integer 中?

[英]How do I add a signed integer to an unsigned integer in Rust?

我是否必須在已簽名的 integer 的符號上分支,如下例所示? (在實際程序中,計算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);
}
  • 有符號整數是二進制補碼
  • 數字強制轉換符號將i8 as u16擴展i8 as u16

這意味着您可以將y as u16轉換y as u16 ,它將轉換為二進制補碼值,如果y為負數,則wrapping_add將正確處理。

簡而言之:按照@Veedrac所說的做。

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

在實際程序中,計算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);
}

如果您每晚使用,我們現在有不穩定的功能mixed_integer_ops

有了這個,你可以這樣做:

#[feature(mixed_integer_ops)]
fn main() {
    let mut x: u16 = 100;
    let y: i8 = -1;
    //x += y;
    x = x.wrapping_add_signed(y); // wraps on overflow
    println!("{}", x);
}

wrapping_checked_saturating_overflowing_變體,具體取決於您希望溢出時的行為; 並且這些方法都在有符號和無符號整數上,分別命名為_unsigned_signed (所以上面也可以表示為x = y.wrapping_add_unsigned(x);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM