简体   繁体   English

如何在 Rust 中返回 integer 溢出标志?

[英]How do I return a flag on integer overflow in Rust?

Swift has integer overflow arithmetic functions which return a flag whether the number has overflowed or not. Swift 有 integer 个溢出算术函数,返回一个标志是否溢出。 Do we have same thing in Rust?我们在 Rust 有同样的东西吗?

Since Rust 1.7.0, there's overflowing_<operation>(rhs) defined on integer types.从 Rust 1.7.0 开始,在整数类型上定义了overflowing_<operation>(rhs)

Example for overflowing_add : overflowing_add的示例:

Calculates self + rhs计算self + rhs

Returns a tuple of the addition along with a boolean indicating whether an arithmetic overflow would occur.返回一个加法元组以及一个指示是否会发生算术溢出的布尔值。 If an overflow would have occurred then the wrapped value is returned.如果发生溢出,则返回包装的值。

Example:例子:

use std::i64;

assert_eq!(5i64.overflowing_add(2), (7, false));
assert_eq!(i64::MAX.overflowing_add(1), (i64::MIN, true));

( playground ) 操场

As you note, there are intrinsics for this but these are unsafe and somewhat annoying to use.正如您所注意到的,这有一些内在函数,但这些是unsafe的并且使用起来有些烦人。

Before Rust 1.0, the standard library provided wrappers that detect the overflow for the 4 arithmetic operations in the form of CheckedAdd , CheckedSub , CheckedMul and CheckedDiv .在 Rust 1.0 之前,标准库以CheckedAddCheckedSubCheckedMulCheckedDiv的形式提供了检测 4 种算术运算溢出的包装器。

As of Rust 1.0, these traits no longer exist and there are just inherent methods on each numeric type, such as i32::checked_add .从 Rust 1.0 开始,这些特征不再存在,每个数字类型只有固有的方法,例如i32::checked_add

However, these just detect overflow and do not return the overflowed-result:但是,这些只是检测溢出而不返回溢出结果:

fn main() {
    println!("{:?}", 5u16.checked_add(65530u16));
    println!("{:?}", 6u16.checked_add(65530u16));
}

( playground ) 操场

Prints:印刷:

Some(65535)
None

Rust has integer arithmetic intrinsics such as add_with_overflow . Rust 具有整数算术内在函数,例如add_with_overflow

pub unsafe extern "rust-intrinsic" fn add_with_overflow<T>(
    x: T, 
    y: T
) -> (T, bool)
  • Wrapping operations return the value equivalent to the mathematically correct result modulo the range of the value:包装操作返回的值等于数学上正确的结果模值的范围:

     fn main() { { let s=500_u16.wrapping_mul(500); println!("{}", s); } }

in this case在这种情况下

   s=53392 // (500*500) module 2^16 =53392
  • Overflowing operations return a tuple (result, overflowed) , result is the wrapping version of the function would return as above, and overflowed is a bool indicating whether an overflow occurred.溢出操作返回一个元组(result, overflowed) ,result 是函数的包装版本将如上返回, overflowed是一个布尔值,指示是否发生溢出。 You can use this bool as the flag:您可以将此布尔值用作标志:

     fn main() { { // because u8 0 to 2^8 –1 (0 to 255) let s=255_u8.overflowing_add(2); // {:?} is used to print a value that implements Debug trait println!("{:?}", s); // s= (1, true) } }

You can test the code here: https://play.rust-lang.org/你可以在这里测试代码: https ://play.rust-lang.org/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM