#ord #hash #hash-values #ff64 #ff32 #total-cmp

fix_float

固定浮点类型,允许在浮点数上实现有用的特性和数据结构

5个版本

0.1.4 2022年7月3日
0.1.3 2022年7月2日
0.1.2 2022年7月2日
0.1.1 2022年7月2日
0.1.0 2022年7月2日

#1579 in 数据结构

MIT 许可证

22KB
386

Workflow Status Coverage Status Crates.io Maintenance

fix_float

Rust的默认浮点类型没有实现标准特性 Ord 和 Hash,这在理论上是对的,但非常令人烦恼。这个crate试图处理一些关于浮点值的限制,以最终实现这些特性。

因为我们谈论的是浮点数,比较和哈希都是微妙的。我们创建了一个名为ff64和ff32的浮点数包装器,它禁止边缘值,如Nan(非数字)和+/- 无穷大。这种限制相当好,因为我们想单独处理这些边缘情况,然后集中精力在“快乐路径”上。

固定浮点数是可以固定的浮点数。在这个范例中,每个正常、亚正常或零数都可以固定,而Nan(非数字)和无穷大则不能。

此外,不能执行任何数学运算,这是为了防止可能导致Nan或无穷大的任何禁止操作,例如 (-1f64).sqrt()0f64.recip()

负零(-0)被转换为正零。

入门

let a = ff64!(42.42);
let b = ff64!(0f64);

以下三个片段应该会引发panic!

// NAN
let a = ff64!(0f64 / 0f64);
// INFINITY
let a = ff64!(1f64 / 0f64);
// NEG_INFINITY
let a = ff64!(-1f64 / 0f64);

示例

分离边缘情况数字并排序有效的固定浮点数。

use fix_float::*;

// inputs: A random list of float numbers
// outputs: A tuple of three elements:
//    .0: sorted list of fix floats numbers
//    .1: numbers of NAN
//    .2: numbers of INFINITY (positive or negative)
fn double_triage(v: Vec<f64>) -> (Vec<ff64>, usize, usize) {
    let mut vff64 = Vec::new();
    let mut nb_nan = 0;
    let mut nb_infinity = 0;

    for &elem in &v {
        match ff64::try_from(elem) {
            Ok(x) => vff64.push(x),
            Err(ErrorTryFrom::CannotFixNan) => nb_nan += 1,
            Err(ErrorTryFrom::CannotFixInfinity) => nb_infinity += 1,
        }
    }

    vff64.sort();

    (vff64, nb_nan, nb_infinity)
}

排序固定浮点数

use fix_float::*;
use rand;

let mut v: Vec<ff64> = vec![];

for _ in 0..10 {
    v.push(ff64!(rand::random::<f64>()));
}

println!("values:");
for &elem in &v {
    println!("  {:.2}", *elem);
}

v.sort();

println!("values sorted:");
for &elem in &v {
    println!("  {:.2}", *elem);
}

有用的数据结构

一个直接的结果是,现在我们可以在HashMap、HashSet、BinaryHeap等有用的数据结构中使用固定浮点数。例如,在图算法中,这非常有用。

let map: HashMap<ff64, ()> = HashMap::new();
let set: HashSet<ff64> = HashSet::new();
let heap: BinaryHeap<ff64> = BinaryHeap::new();

当前版本:0.1.4
许可证:MIT

依赖项

~185KB