#![cfg_attr(feature = "cargo-clippy", allow(float_cmp))] extern crate quickersort; extern crate rand; extern crate num_traits; mod bench { use std::f64; use num_traits::{ToPrimitive}; use quickersort::{sort_floats}; use rand::{Rng, weak_rng}; #[test] fn test_sort_floats() { let sorted_negs: Vec<_> = (0..10u32).map(|i| -1.0f64 * (11 - i).to_f64().unwrap()).collect(); let sorted_pos: Vec<_> = (0..10u32).map(|i| (i + 1).to_f64().unwrap()).collect(); let mut sorted = vec![f64::NEG_INFINITY]; sorted.extend(sorted_negs); sorted.push(-0.0); sorted.push(0.0); sorted.extend(sorted_pos); sorted.push(f64::INFINITY); for _ in 0..10 { sorted.push(f64::NAN); } let mut rng = weak_rng(); for _ in 0..1000 { let mut w = sorted.clone(); rng.shuffle(&mut w[..]); sort_floats(&mut w[..]); assert_float_eq(&w[..], &sorted[..]); } let mut xs = [0.0f64, -0.0]; sort_floats(&mut xs[..1]); sort_floats(&mut xs[..2]); sort_floats(&mut xs[..]); } #[test] fn test_sort_random_floats() { let mut rng = weak_rng(); for _ in 0..1000 { let mut v = rng.gen_iter::().map(|x| 100.0 * (x - 0.5)).take(20).collect::>(); v.push(f64::NAN); v.push(0.0); v.push(-0.0); rng.shuffle(&mut v[..]); sort_floats(&mut v[..]); assert_floats_sorted(&v[..]); } } #[test] fn test_sort_zeros() { let mut rng = weak_rng(); let mut v = rng.gen_iter::().map(|x| if x > 0.5 { 0.0 } else { -0.0 }).take(50).collect::>(); sort_floats(&mut v[..]); assert_floats_sorted(&v[..]); } #[test] fn test_sort_few_zeros() { let mut v = [0.0, -0.0]; sort_floats(&mut v[..]); assert_floats_sorted(&v[..]); } fn assert_float_eq(a: &[f64], b: &[f64]) { if a.len() != b.len() { panic!("different lengths, {} vs. {}", a.len(), b.len()); } for i in 0..a.len() { if !((a[i] == b[i] && a[i].signum() == b[i].signum()) || (a[i].is_nan() && b[i].is_nan())) { panic!("\n{:?} !=\n{:?}\n{} != {}", a, b, a[i], b[i]); } } } fn assert_floats_sorted(v: &[f64]) { let (not_nans, nans) = match v.iter().position(|x| x.is_nan()) { Some(i) => v.split_at(i), None => (v, &[][..]) }; let is_ordered = |w: &[f64]| { let (a, b) = (w[0], w[1]); a < b || (a == b && !(b.is_sign_negative() && a.is_sign_positive())) }; assert!(not_nans.windows(2).all(is_ordered)); assert!(nans.iter().all(|x| x.is_nan())); } }