Reputation: 367
I would like to have a sorted array which has an f64 as key and an f64 as value. I need to update, delete and insert to this array by finding the right key. I need to get the first 1000 sorted entries, and also the first entry. These operations must be fast.
By reading the documentation, I thought BTreeMap is good for me.
However, when I try to insert into it I got this error message:
the trait bound `f64: Ord` is not satisfied
the trait `Ord` is not implemented for `f64`rustcE0277
What is the recommended way to do this with Rust?
My code:
use std::collections::BTreeMap;
pub struct MyStruct {
pub map: BTreeMap<f64, f64>
}
impl MyStruct {
pub fn new() -> MyStruct {
MyStruct {
map: BTreeMap::new()
}
}
}
fn main() {
let mut my_struct = MyStruct::new();
my_struct.map.insert(1.0, 2.0);
}
Upvotes: 5
Views: 1587
Reputation: 3970
You can use nutype crate.
With nutype you can add finite
validation on your newtype, which excludes NaN
and Infinity
.
This allows to derive Eq
and Ord
:
use nutype::nutype;
use std::collections::BTreeMap;
#[nutype(
validate(finite),
derive(Debug, PartialEq, Eq, PartialOrd, Ord),
)]
pub struct Float(f64);
#[derive(Debug)]
pub struct MyStruct {
pub map: BTreeMap<Float, Float>
}
impl MyStruct {
pub fn new() -> MyStruct {
MyStruct {
map: BTreeMap::new()
}
}
}
fn main() {
let mut my_struct = MyStruct::new();
let one = Float::new(1.0).unwrap();
let two = Float::new(2.0).unwrap();
my_struct.map.insert(one, two);
println!("{my_struct:?}");
}
Output:
MyStruct { map: {Float(1.0): Float(2.0)} }
Upvotes: 0
Reputation: 13750
I think you may be looking for the ordered_float
crate and either the OrderedFloat
(can store NaN, sorts it above +inf
) or NotNan
(cannot store NaN) structs, which both are a float-like type that is Eq
and Ord
(in violation of the IEEE standard).
Upvotes: 7
Reputation: 89
Floating point numbers are not good candidates for keys. Maybe you should consider converting them to integers or strings. For example, if you only care about 2 digits after the decimal separator, you can do something like n*100, rounded and converted to an integer type.
Upvotes: 2