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

Importing mio::tcp::TcpStream but get std::net::tcp::TcpStream
It is possible to always have Cargo show warnings?
Copy files to the target directory after build
Is it ok to return in main?
Why is this trait/implementation incompatible - bound lifetime vs concrete lifetime
Cannot move out of `req` because it is borrowed
remove duplicates from vector of custom struct
error with % operator inside closure
How can I open a file with the standard text editor?
How to use multiple variables in routes with Nickel?
sdl2-sys won't compile - could not exec the linker: No such file or directory
Cannot borrow as mutable more than once at a time in one code - but can in another very similar
Forcing a move for an implemented `Copy` type
When do I need to specify explicit lifetimes in Rust?
cannot borrow `self.x` as immutable because `*self` is also borrowed as mutable
Getting sequence of bytes (u8) from a char

Categories

HOME
qt
xpath
typelite
barcode-scanner
applescript
devexpress
mongoid
tabs
yql
azure-data-lake
hyperledger
bittorrent
video-streaming
clone
google-search-console
sentry
firebase-dynamic-links
log4j2
lc3
watch-os-3
nsstring
clish
spring-amqp
createjs
ex
mailgun
temperature
pickle
sipp
mdns
openbr
commonsware-cwac
mongodb-3.4
wampsharp
john-the-ripper
universal
nppexec
subclassing
runtimeexception
fastlane
aurelia-cli
elastica
mars-simulator
swfupload
system-on-chip
fiware-wirecloud
code-push
xcode8.2
daz3d
rightnow-crm
xcglogger
sony-future-lab-n
embedded-v8
msxml
google-shopping-api
cefpython
pjax
livecycle
p6spy
nunit-console
piping
groovyfx
apache-pig-grunt
apple-configurator
timestamping
utf-16
vimperator
webgrind
juniper-network-connect
ruby-on-rails-4.1
place
highest
gitlab-omnibus
enaml
roxygen2
cache-manifest
unidata
webproject
azure-xplat-cli
python-c-extension
html-escape-characters
kognitio-wx2
microsoft-expression-web
flurry-analytics
iodocs
zend-mail
angular-ui-select
jini
air-native-extension
accountmanager
pre
san
jquery-transit
2d-vector
stretch
chronometer
border-box
msinfo32
system-information
data-dump
rtd
css-friendly
bll
regression-testing
git-log
ccl
reliability
facebook-fbml
.net-client-profile
comment-conventions

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