对于大多数可能溢出的操作符,Rust提供了一个检查版本。例如,要测试加法是否溢出,可以使用checked_add
:
match 255u8.checked_add(1) {
Some(_) => println!("no overflow"),
None => println!("overflow!"),
}
这将打印"overflow!"
。还有一个checked_shl
,但根据文档,它只检查移位是否大于或等于self
中的位数。这意味着,虽然这:
match 255u8.checked_shl(8) {
Some(val) => println!("{}", val),
None => println!("overflow!"),
}
被捕获并打印"overflow!"
,如下:
match 255u8.checked_shl(7) {
Some(val) => println!("{}", val),
None => println!("overflow!"),
}
简单地打印128
,显然没有捕获溢出。检查左移时是否溢出的正确方法是什么?
3条答案
按热度按时间ou6hu8tu1#
我不知道有什么惯用的方法可以做到这一点,但是像实现你自己的特质这样的方法会起作用:Playground
该算法基本上是检查数字中的前导零是否不少于移位大小
jdgnovmf2#
你可以做一个互补的右移(右移8 - requested_number_of_bits)并检查是否还有0。如果是,则意味着左移不会丢失任何位:
也可以编写一个接受任何数字类型的泛型版本,包括bigint(应用于
u8
会生成与上面完全相同的代码):Playground
gywdnpxw3#
我总是取移位后的值,将其右移相同的量,然后与原始数字进行比较。如果它们不相等,则一定发生了移位溢出。