[英]How do I add a signed integer to an unsigned integer in Rust, checking for unsigned overflow?
[英]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.