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 数据结构
22KB
386 行
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