Saturating<T>
Khi nhìn vào ví dụ này, khi cộng (+
) hoặc trừ (-
) hai số unsigned u8
có thể dẫn đến tràn số (overflow) (playground):
fn main() { println!("{:?}", 10_u8 - 20_u8); }
--> src/main.rs:2:22
|
2 | println!("{:?}", 10_u8 - 20_u8);
| ^^^^^^^^^^^^^ attempt to compute `10_u8 - 20_u8`, which would overflow
Tương tự, nếu ta cố gắng cộng hai int
, điều này cũng có thể gây ra lỗi tương tự. Ví dụ (playground):
fn main() { println!("{:?}", i32::MAX + 1); }
--> src/main.rs:2:22
|
2 | println!("{:?}", i32::MAX + 1);
| ^^^^^^^^^^^^ attempt to compute `i32::MAX + 1_i32`, which would overflow
Saturating<T>
là một bọc toán học với chức năng bão hòa. Các phép toán như +
trên các giá trị u32
được thiết kế để không bao giờ tràn số, và trong một số cấu hình debug, tràn số được phát hiện và dẫn đến một sự cố. Trong khi hầu hết các phép toán thuộc loại này, một số mã cụ thể mong muốn và phụ thuộc vào toán học bão hòa.
use std::num::Saturating; fn main() { let a = Saturating(10_u8); let b = Saturating(20_u8); println!("{:?}", a - b); // 0 // Giá trịgốc có thể được truy xuất thông qua `.0` let res = (a - b).0; // 0 }
Một ví dụ khác là cố gắng +
gây tràn số khi giá trị kết quả lớn hơn giá trị tối đa của kiểu dữ liệu số đó (playground):
use std::num::Saturating; fn main() { let max = Saturating(u32::MAX); let one = Saturating(1u32); assert_eq!(u32::MAX, (max + one).0); }
Một số methods hữu ích khác
Saturating<T>::MIN
và Saturating<T>::MAX
trả về giá trị nhỏ nhất và lớn nhất có thể được biểu diễn bởi kiểu số nguyên này:
#![allow(unused)] fn main() { use std::num::Saturating; assert_eq!(<Saturating<usize>>::MIN, Saturating(usize::MIN)); assert_eq!(<Saturating<usize>>::MAX, Saturating(usize::MAX)); }
pow
:
#![allow(unused)] fn main() { use std::num::Saturating; assert_eq!(Saturating(3usize).pow(4), Saturating(81)); assert_eq!(Saturating(3i8).pow(5), Saturating(127)); }