面试题答案
一键面试检测浮点数溢出错误
在Rust中,浮点数运算默认是不检查溢出的,因为检查溢出会带来性能开销。不过,可以使用checked_*
系列方法来检测溢出。
例如,对于加法运算:
let a: f64 = f64::MAX;
let b: f64 = 1.0;
let result = a.checked_add(b);
match result {
Some(sum) => println!("Sum: {}", sum),
None => println!("Overflow occurred"),
}
预防浮点数溢出的策略
1. 提前范围检查
在进行运算之前,先检查操作数是否在合理范围内,避免可能导致溢出的计算。
fn safe_add(a: f64, b: f64) -> Option<f64> {
if (a.is_sign_positive() && b.is_sign_positive() && a > f64::MAX - b) ||
(a.is_sign_negative() && b.is_sign_negative() && a < f64::MIN - b) {
None
} else {
Some(a + b)
}
}
2. 使用checked系列方法
在每次运算时使用checked_*
方法,这样当溢出发生时会返回None
。
let a: f64 = f64::MAX;
let b: f64 = 1.0;
let result = a.checked_add(b);
match result {
Some(sum) => println!("Sum: {}", sum),
None => println!("Overflow occurred"),
}
3. 缩放操作数
如果可能,对操作数进行缩放,使运算在安全范围内进行,然后再将结果缩放回原始范围。例如,在进行乘法运算时,可以将两个数都除以一个较大的数,运算后再乘回来。
fn scaled_multiply(a: f64, b: f64) -> Option<f64> {
let scale = 1e10;
let scaled_a = a / scale;
let scaled_b = b / scale;
let scaled_result = scaled_a.checked_mul(scaled_b)?;
Some(scaled_result * scale * scale)
}