From: Ian Jackson Date: Sun, 4 Oct 2020 18:46:56 +0000 (+0100) Subject: ord etc. for bigfloat X-Git-Tag: otter-0.2.0~759 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=b8dfb2ee67668ba03ad21ef53ef314d23b145a95;p=otter.git ord etc. for bigfloat Signed-off-by: Ian Jackson --- diff --git a/src/bigfloat.rs b/src/bigfloat.rs index e1a58ee1..91a31777 100644 --- a/src/bigfloat.rs +++ b/src/bigfloat.rs @@ -2,7 +2,8 @@ use crate::imports::*; -enum Sign { Pos, Neg, } +#[derive(Copy,Clone,Debug,Ord,Eq,PartialOrd,PartialEq)] +enum Sign { Neg, Pos, } use Sign::*; type Sz = u16; @@ -208,6 +209,41 @@ impl Debug for Bigfloat { } } +impl Ord for Bigfloat { + fn cmp(&self, other: &Bigfloat) -> Ordering { + let (ah, al) = self.as_parts(); + let (bh, bl) = other.as_parts(); + + { + + ah.sign.cmp(&bh.sign) + + }.then_with(||{ + + let mut x = ah.exp.cmp(&bh.exp); + if ah.sign == Neg { x = x.reverse() } + x + + }.then_with(||{ + + al.cmp(bl) + + })) + } +} +impl PartialOrd for Bigfloat { + fn partial_cmp(&self, other: &Bigfloat) -> Option { + Some(self.cmp(other)) + } +} +impl Eq for Bigfloat { +} +impl PartialEq for Bigfloat { + fn eq(&self, other: &Bigfloat) -> bool { + self.cmp(other) == Ordering::Equal + } +} + #[derive(Error,Clone,Copy,Debug)] #[error("error parsing bigfloat (z value)")] pub struct ParseError; @@ -242,4 +278,19 @@ mod test { assert_eq!(format!("{:?}", &b2), format!(r#"Bf"{}""#, &b2)); } + + #[test] + fn equality() { + assert!( Bigfloat::from_str("!0000 ffff_ffff_fff0") < + Bigfloat::from_str("!0000 ffff_ffff_fff3") ); + + assert!( Bigfloat::from_str("!0001 ffff_ffff_ffff") < + Bigfloat::from_str("!0000 ffff_ffff_0000") ); + + assert!( Bigfloat::from_str("+0000 ffff_ffff_0000") < + Bigfloat::from_str("+0001 ffff_ffff_ffff") ); + + assert!( Bigfloat::from_str("+0000 ffff_ffff_0000") < + Bigfloat::from_str("+0000 ffff_ffff_0000 1234_ffff_0000") ); + } } diff --git a/src/imports.rs b/src/imports.rs index 9cdcaed4..f8809df7 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -20,7 +20,7 @@ pub use std::iter; pub use std::iter::repeat_with; pub use std::collections::VecDeque; pub use std::num::Wrapping; -pub use std::cmp::{self,min,max}; +pub use std::cmp::{self,min,max,Ordering}; pub use std::error::Error; pub use std::marker::PhantomData; pub use std::ops::{Deref,DerefMut};