use arithmetica::counters::{self, Predicate};
use arithmetica::orient2d;
struct SplitMix64(u64);
impl SplitMix64 {
fn next_f64(&mut self) -> f64 {
self.0 = self.0.wrapping_add(0x9E37_79B9_7F4A_7C15);
let mut z = self.0;
z = (z ^ (z >> 30)).wrapping_mul(0xBF58_476D_1CE4_E5B9);
z = (z ^ (z >> 27)).wrapping_mul(0x94D0_49BB_1331_11EB);
z ^= z >> 31;
#[allow(clippy::cast_precision_loss)]
let unit = (z >> 11) as f64 / (1_u64 << 53) as f64;
unit
}
}
fn report(label: &str) {
let counts = counters::snapshot(Predicate::Orient2d);
let rate = counts.exact_rate().unwrap_or(0.0);
println!(
"{label:<22} calls {:>7} exact stage {:>7} ({:.2}%)",
counts.total(),
counts.exact,
100.0 * rate
);
}
fn main() {
let mut rng = SplitMix64(1);
counters::reset();
for _ in 0..100_000 {
let p = |rng: &mut SplitMix64| [rng.next_f64(), rng.next_f64()];
let (a, b, c) = (p(&mut rng), p(&mut rng), p(&mut rng));
let _ = orient2d(a, b, c);
}
report("random triples");
counters::reset();
for i in 1..=1_000 {
let t = f64::from(i);
let _ = orient2d([t, 3.0 * t], [2.0 * t, 6.0 * t], [5.0 * t, 15.0 * t]);
}
report("collinear triples");
}