preserves/implementations/rust/oo/src/float.rs

95 lines
2.0 KiB
Rust

use std::cmp::Ordering;
use std::hash::{Hash, Hasher};
/// Single-precision IEEE 754 Value
#[derive(Clone, Copy, Debug)]
pub struct Float(pub f32);
/// Double-precision IEEE 754 Value
#[derive(Clone, Copy, Debug)]
pub struct Double(pub f64);
impl From<f32> for Float {
fn from(v: f32) -> Self {
Float(v)
}
}
impl From<Float> for f32 {
fn from(v: Float) -> Self {
v.0
}
}
impl Hash for Float {
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.to_bits().hash(state);
}
}
impl PartialEq for Float {
fn eq(&self, other: &Self) -> bool {
self.0.to_bits() == other.0.to_bits()
}
}
impl Ord for Float {
fn cmp(&self, other: &Self) -> Ordering {
let mut a: u32 = self.0.to_bits();
let mut b: u32 = other.0.to_bits();
if a & 0x8000_0000 != 0 { a ^= 0x7fff_ffff; }
if b & 0x8000_0000 != 0 { b ^= 0x7fff_ffff; }
(a as i32).cmp(&(b as i32))
}
}
impl PartialOrd for Float {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Eq for Float {}
impl From<f64> for Double {
fn from(v: f64) -> Self {
Double(v)
}
}
impl From<Double> for f64 {
fn from(v: Double) -> Self {
v.0
}
}
impl Hash for Double {
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.to_bits().hash(state);
}
}
impl PartialEq for Double {
fn eq(&self, other: &Self) -> bool {
self.0.to_bits() == other.0.to_bits()
}
}
impl Ord for Double {
fn cmp(&self, other: &Self) -> Ordering {
let mut a: u64 = self.0.to_bits();
let mut b: u64 = other.0.to_bits();
if a & 0x8000_0000_0000_0000 != 0 { a ^= 0x7fff_ffff_ffff_ffff; }
if b & 0x8000_0000_0000_0000 != 0 { b ^= 0x7fff_ffff_ffff_ffff; }
(a as i64).cmp(&(b as i64))
}
}
impl PartialOrd for Double {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Eq for Double {}