123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- use core::mem;
- pub mod add;
- /// Trait for some basic operations on floats
- pub trait Float: Sized {
- /// A uint of the same with as the float
- type Int;
-
- /// Returns the bitwidth of the float type
- fn bits() -> u32;
- /// Returns the bitwidth of the significand
- fn significand_bits() -> u32;
- /// Returns `self` transmuted to `Self::Int`
- fn repr(self) -> Self::Int;
- #[cfg(test)]
- /// Checks if two floats have the same bit representation. *Except* for NaNs! NaN can be
- /// represented in multiple different ways. This methods returns `true` if two NaNs are
- /// compared.
- fn eq_repr(self, rhs: Self) -> bool;
- /// Returns a `Self::Int` transmuted back to `Self`
- fn from_repr(a: Self::Int) -> Self;
- /// Returns (normalized exponent, normalized significand)
- fn normalize(significand: Self::Int) -> (i32, Self::Int);
- }
- impl Float for f32 {
- type Int = u32;
- fn bits() -> u32 {
- 32
- }
- fn significand_bits() -> u32 {
- 23
- }
- fn repr(self) -> Self::Int {
- unsafe { mem::transmute(self) }
- }
- #[cfg(test)]
- fn eq_repr(self, rhs: Self) -> bool {
- if self.is_nan() && rhs.is_nan() {
- true
- } else {
- self.repr() == rhs.repr()
- }
- }
- fn from_repr(a: Self::Int) -> Self {
- unsafe { mem::transmute(a) }
- }
- fn normalize(significand: Self::Int) -> (i32, Self::Int) {
- let shift = significand.leading_zeros()
- .wrapping_sub((1u32 << Self::significand_bits()).leading_zeros());
- (1i32.wrapping_sub(shift as i32), significand << shift as Self::Int)
- }
- }
- impl Float for f64 {
- type Int = u64;
- fn bits() -> u32 {
- 64
- }
- fn significand_bits() -> u32 {
- 52
- }
- fn repr(self) -> Self::Int {
- unsafe { mem::transmute(self) }
- }
- #[cfg(test)]
- fn eq_repr(self, rhs: Self) -> bool {
- if self.is_nan() && rhs.is_nan() {
- true
- } else {
- self.repr() == rhs.repr()
- }
- }
- fn from_repr(a: Self::Int) -> Self {
- unsafe { mem::transmute(a) }
- }
- fn normalize(significand: Self::Int) -> (i32, Self::Int) {
- let shift = significand.leading_zeros()
- .wrapping_sub((1u64 << Self::significand_bits()).leading_zeros());
- (1i32.wrapping_sub(shift as i32), significand << shift as Self::Int)
- }
- }
|