[Rust] 对整形溢出的处理

东湖之滨  金牌会员 | 2023-12-6 09:52:49 | 来自手机 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 962|帖子 962|积分 2890

1. 两种不同模式下的整形溢出

坑了个爹的,书上说的没理解清楚,在Rust程序语言设计中文版3.2中提到了,当使用--release参数进行发布模式构建时,Rust不会检测导致panic的整形溢出,这里需要分两种情况考虑:

  • 编译期就可以发现的整形溢出
  • 程序运行过程中会发生的整形溢出
1.1 编译阶段

如果是编译期能够确定会发生的整形溢出(程序1-1),无论是不是执行了--release参数都会在构建阶段(cargo build)发生报错
  1. // 程序1-1
  2. fn main() {
  3.     let i:u8 = 254;
  4.     let i = i + 4;
  5.     println!("{}!",i);
  6. }
复制代码
上述变量i的类型为u8类型,值的范围在(0..=255),
经过运算的结果最终的i的值为258,这个值在编译期已经可以检测到整形溢出,最终构建会报错如下:

  • debug模式

  • release模式

    这种编译期可以确定的溢出错误,两种模式下都会发生崩溃

1.2 运行阶段

在运行期发生的整形溢出(程序1-2),不会在build阶段报错
  1. // 程序1-2
  2. fn main() {
  3.     let i:u8 = 254;
  4.     for j in 0..=4 {
  5.         println!("{}!",i+j);
  6.     }
  7. }
复制代码
上述代码,只有在j>1的情况下才会发生整形溢出,这种错误在编译期是发现不了的

  • debug模式执行

    在不使用--release的时候,在运行阶段报错

  • release模式

    在使用--release        的情况下,溢出值对256进行了取模运算

1.3 说明

当使用--release进行构建发布模式时,当检测到整形溢出,将会使用一种进制补码包裹(two’s complement wrapping的操作。就是最终的计算出来的结果对2N取模。N为类型的bit位,u8是8位,N=8
2 Rust对溢出的操作

摘自:数据类型 - Rust 程序设计语言 中文版 (rustwiki.org)
要显式处理溢出的可能性,可以使用标准库针对原始数字类型提供的以下一系列方法:

  • 使用 wrapping_* 方法在所有模式下进行包裹,例如 wrapping_add
  • 如果使用 checked_* 方法时发生溢出,则返回 None 值
  • 使用 overflowing_* 方法返回该值和一个指示是否存在溢出的布尔值
  • 使用 saturating_* 方法使值达到最小值或最大值
这么处理,在debug模式下就不会panic
2.1 wrapping_*

当计算结果发生溢出执行取模操作(程序2-1)
  1. // 2-1
  2. fn main() {
  3.     let i:u8 = 254;
  4.     for j in 2..=4 {
  5.         println!("=======================");
  6.         println!("i+j={}!",i.wrapping_add(j));
  7.         println!("j-i={}!",j.wrapping_sub(i));
  8.         println!("j*i={}!",j.wrapping_mul(i));
  9.         println!("j/i={}!",j.wrapping_div(i));
  10.     }
  11. }
复制代码
结果如下:


<strong>那么问题来了,负数怎么取整?
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

东湖之滨

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表