Rust编程中的浮点数比较

缘由:在看Rust编写的代码,发现了一行浮点数等于比较的代码,于是编辑如下内容。

在Rust中,进行浮点数比较时需要特别小心,因为浮点数由于精度限制无法精确表示小数,可能会导致直接比较(如 ==)的结果不符合预期。这里是一些注意事项和常见的解决方案:

1. 避免直接使用 ==!= 比较

浮点数运算中的精度误差,可能导致直接比较不准确。例如:

rust 复制代码
let a = 0.1 + 0.2;
let b = 0.3;
println!("{}", a == b); // 输出: false

虽然理论上 ab 应该相等,但计算误差会让它们的值稍有不同。因此,避免使用 ==!= 直接比较浮点数。

2. 使用允许误差(误差容限)进行比较

通常,在比较浮点数时引入一个允许的误差范围(即误差容限)。例如,如果两个浮点数的差异在某个很小的范围内,就可以认为它们相等。

rust 复制代码
fn approx_equal(a: f64, b: f64, epsilon: f64) -> bool {
    (a - b).abs() < epsilon
}

fn main() {
    let a = 0.1 + 0.2;
    let b = 0.3;
    println!("{}", approx_equal(a, b, 1e-10)); // 输出: true
}

这里 epsilon 是误差容限,根据实际情况选择合适的值,比如 1e-10 或更小的值。

3. 使用 f64::EPSILONf32::EPSILON

Rust 提供了 f64::EPSILONf32::EPSILON,表示浮点数计算中能表示的最小差值。通常 EPSILON 可以作为误差容限的基础,不过更常见的是在其基础上进行放大:

rust 复制代码
fn approx_equal(a: f64, b: f64) -> bool {
    (a - b).abs() < f64::EPSILON * 10.0 // 放大 epsilon 以确保误差范围足够
}

4. 使用内置的 f64::total_cmp

如果需要对浮点数进行排序,可以使用 total_cmp 方法。这个方法会考虑特殊的浮点数情况,比如 NaN-0.0,避免精度误差对排序结果的影响:

rust 复制代码
fn main() {
    let mut values = vec![0.1 + 0.2, 0.3];
    values.sort_by(|a, b| a.total_cmp(b));
    println!("{:?}", values);
}

5. 尽量避免不必要的浮点计算

尽量避免将多个浮点计算组合在一起,特别是涉及较小或较大的数。浮点数计算误差是累积的,因此计算越复杂,误差越明显。

6. 避免与 NaN 进行比较

任何浮点数与 NaN(非数)进行比较都会返回 false。如果可能存在 NaN 值,应提前检查和处理。

rust 复制代码
let x = f64::NAN;
if x.is_nan() {
    println!("x is NaN");
}

总结

浮点数的精度误差是比较时的一大挑战。在 Rust 中进行浮点数比较时,应尽量避免直接比较,使用误差容限或 total_cmp 方法。

相关推荐
Kiri霧3 小时前
Linux下的Rust 与 C 的互操作性解析
c语言·开发语言·rust
雪芽蓝域zzs3 小时前
uniapp AES 加密解密
开发语言·uni-app·c#
雨夜的星光3 小时前
Python JSON处理:load/loads/dump/dumps全解析
开发语言·python·json
fen_fen4 小时前
Java打包时,不将本地Jar打包到项目的最终 JAR 中
开发语言·python·pycharm
wjs20246 小时前
SQL AND & OR 操作符详解
开发语言
~光~~6 小时前
【环境配置 】WSL2 +ubuntu20.04 +Qt配置+Kits配置
开发语言·qt·ubuntu
·心猿意码·7 小时前
C++右值语义解析
开发语言·c++
小龙报7 小时前
《彻底理解C语言指针全攻略(2)》
c语言·开发语言·c++·visualstudio·github·学习方法
zzzsde7 小时前
【c++】深入理解string类(4)
开发语言·c++
大鱼七成饱8 小时前
Rust 多线程编程入门:从 thread::spawn 步入 Rust 并发世界
后端·rust