rust


How to do a binary search on a Vec of floats?


If you have a Vec<u32> you would use the slice::binary_search method.
For reasons I don't understand, f32 and f64 do not implement Ord. Since the primitive types are from the standard library, you cannot implement Ord on them yourself, so it does not appear you can use this method.
How can you effectively do this?
Do I really have to wrap f64 in a wrapper struct and implement Ord on it? It seems extremely painful to have to do this, and involves a great deal of transmute to cast blocks of data back and forth unsafely for effectively no reason.
for reasons I don't understand, f32 and f64 do not implement Ord.
Because floating point is hard! The short version is that floating point numbers have a special value NaN - Not a Number. The IEEE spec for floating point numbers states that 1 < NaN, 1 > NaN, and NaN == NaN are all false.
Ord says:
Trait for types that form a total order.
This means that the comparisons need to have totality:
a ≤ b or b ≤ a
but we just saw that floating points do not have this property.
So yes, you will need to create a wrapper type that somehow deals with comparing the large number of NaN values. Maybe your case you can just assert that the float value is never NaN and then call out to the regular PartialOrd trait. Here's an example:
use std::cmp::Ordering;
#[derive(PartialEq,PartialOrd)]
struct NonNan(f64);
impl NonNan {
fn new(val: f64) -> Option<NonNan> {
if val.is_nan() {
None
} else {
Some(NonNan(val))
}
}
}
impl Eq for NonNan {}
impl Ord for NonNan {
fn cmp(&self, other: &NonNan) -> Ordering {
self.partial_cmp(other).unwrap()
}
}
fn main() {
let mut v: Vec<_> = [2.0, 1.0, 3.0].iter().map(|v| NonNan::new(*v).unwrap()).collect();
v.sort();
let r = v.binary_search(&NonNan::new(2.0).unwrap());
println!("{:?}", r);
}
One of the slice methods is binary_search_by, which you could use. f32/f64 implement PartialOrd, so if you know they can never be NaN, you can unwrap the result of partial_cmp:
fn main() {
let values = [1.0, 2.0, 3.0, 4.0, 5.0];
let location = values.binary_search_by(|v| {
v.partial_cmp(&3.14).expect("Couldn't compare values")
});
match location {
Ok(i) => println!("Found at {}", i),
Err(i) => println!("Not found, could be inserted at {}", i),
}
}

Related Links

Using pointer casting to change the “type” of data in memory [duplicate]
Export function only to module test?
Take slice of certain length known at compile time
Is it possible to deactivate file locking in cargo?
“does not live long enough” error in same function
What ways exist to create containers of several types? [duplicate]
How can I optimize reading a UTF-8 string from a file with a known offset and size?
Create vector of objects implementing a trait in Rust
Using loop variable from “..” loop causes type conversion?
What is RFC 401's coerce_inner useful for?
Rust Borrow checker only complains about borrowing as mutable multiple times when a function that returns a reference with the same lifetime assigned
How can I remove `let _ : () = …`?
Does if-let with a pair short-circuit?
Rust borrow lasts beyond the scope it's in?
How can I include an arbitrary set of Protobuf-built files without knowing their names?
Specialization of method in inherent impl

Categories

HOME
oracle
livecode
bots
selenium-builder
nsis
lvm
drag-and-drop
linker
video-streaming
wagtail
sympy
tup
selection
nexus3
fireloop
cqrs
twisted
heap-dump
google-tasks-api
data-type-conversion
ava
react-dnd
uilocalnotification
marquee
miniprofiler
adapter
basic-authentication
windowsiot
argv
commonsware-cwac
gsp
xmlunit
orchardcms-1.8
assertions
identify
rdp
ejml
robust
rightnow-crm
swift2.3
comm
android-sharing
simple-schema
watir-webdriver
word-2016
email-injection
java-2d
conan
wolfram-language
fragmentstatepageradapter
maven-release-plugin
processor
jeditable
mercurial-extension
lovefield
bayesglm
linuxbrew
android-mapview
smart-tv
sqlbase
wlanapi
physicsjs
scala-macros
nssortdescriptor
lifetime
n-tier-architecture
xml-signature
nidaqmx
thruway
gpu-programming
nosql-aggregation
sensormanager
iirf
arel
simplecov
linkbutton
spark-view-engine
image-scanner
jzmq
opends
netstream
space-partitioning
winsxs
aptitude
urchin
data-retrieval
main-method
autobench
motif
twitter-feed
datagridcolumn

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App