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 方法。

相关推荐
一抓掉一大把1 分钟前
秒杀-StackExchangeRedisHelper连接单例
java·开发语言·jvm
Source.Liu13 分钟前
【iso8601库】Time 类型解析模块详解(time.rs文件)
rust·iso8601
星释15 分钟前
Rust 练习册 :Minesweeper与二维数组处理
开发语言·后端·rust
开发者小天1 小时前
React中的useRef的用法
开发语言·前端·javascript·react.js
xixixin_1 小时前
【React】检测元素是否出现在用户视窗内
开发语言·前端·javascript·react.js
Js_cold1 小时前
Verilog局部参数localparam
开发语言·fpga开发·verilog
Acrelhuang1 小时前
小小电能表,如何撬动家庭能源革命?
java·大数据·开发语言·人工智能·物联网
头发还没掉光光2 小时前
Linux网络初始及网络通信基本原理
linux·运维·开发语言·网络·c++
疏狂难除2 小时前
spiderdemo第22题与webassembly的跨域
开发语言·javascript·爬虫·rust·wasm·mitmproxy
WenGyyyL2 小时前
微信小程序开发——第二章:微信小程序开发环境搭建
开发语言·python·微信小程序