Do I have to branch on the sign of the signed integer, like in the example below? (In the real program y
is calculated to change the index pointing into a 64K array, and wraparound is the desired behavior)
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
That means you can cast y as u16
it will turn into a twos complement value that a wrapping_add will rightfully handle if y
was negative.
In short: do as @Veedrac said.
fn main() {
let mut x: u16 = 100;
let y: i8 = -1;
x = x.wrapping_add(y as u16);
println!("{}", x);
}
If you're on nightly, we now have the unstable feature mixed_integer_ops.
With this you can do:
#[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);
}
There's wrapping_
, checked_
, saturating_
, and overflowing_
variants, depending on what behavior you want on overflow; and the methods are on both signed and unsigned integers, named _unsigned
and _signed
respectively (so the above could also be expressed as x = y.wrapping_add_unsigned(x);
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With