2016-08-18 04:51:37 +08:00
|
|
|
use core::mem;
|
|
|
|
|
|
|
|
pub mod add;
|
|
|
|
|
|
|
|
/// Trait for some basic operations on floats
|
2016-09-27 13:22:10 +08:00
|
|
|
pub trait Float: Sized + Copy {
|
2016-08-18 04:51:37 +08:00
|
|
|
/// A uint of the same with as the float
|
|
|
|
type Int;
|
2016-09-27 13:22:10 +08:00
|
|
|
|
2016-08-18 04:51:37 +08:00
|
|
|
/// Returns the bitwidth of the float type
|
|
|
|
fn bits() -> u32;
|
|
|
|
|
2016-09-30 09:48:20 +08:00
|
|
|
/// Returns the bitwidth of the exponent
|
|
|
|
fn exponent_bits() -> u32;
|
|
|
|
|
2016-08-18 04:51:37 +08:00
|
|
|
/// Returns the bitwidth of the significand
|
|
|
|
fn significand_bits() -> u32;
|
|
|
|
|
2016-09-30 09:48:33 +08:00
|
|
|
/// Returns a mask for the sign bit of `self`
|
|
|
|
fn sign_mask() -> Self::Int;
|
2016-08-18 04:51:37 +08:00
|
|
|
|
2016-09-30 09:48:33 +08:00
|
|
|
/// Returns a mask for the exponent portion of `self`
|
|
|
|
fn exponent_mask() -> Self::Int;
|
2016-08-22 00:24:58 +08:00
|
|
|
|
2016-09-30 09:48:33 +08:00
|
|
|
/// Returns a mask for the significand portion of `self`
|
|
|
|
fn significand_mask() -> Self::Int;
|
2016-08-18 04:51:37 +08:00
|
|
|
|
2016-09-30 09:48:20 +08:00
|
|
|
/// Returns the sign bit of `self`
|
|
|
|
fn sign(self) -> bool;
|
|
|
|
|
|
|
|
/// Returns the exponent portion of `self`, shifted to the right
|
|
|
|
fn exponent(self) -> Self::Int;
|
|
|
|
|
|
|
|
/// Returns the significand portion of `self`
|
|
|
|
fn significand(self) -> Self::Int;
|
|
|
|
|
2016-09-30 09:48:33 +08:00
|
|
|
/// 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 method 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;
|
|
|
|
|
|
|
|
/// Constructs a `Self` from its parts
|
|
|
|
fn from_parts(sign: bool, exponent: Self::Int, significand: Self::Int) -> Self;
|
|
|
|
|
2016-08-18 04:51:37 +08:00
|
|
|
/// Returns (normalized exponent, normalized significand)
|
|
|
|
fn normalize(significand: Self::Int) -> (i32, Self::Int);
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Float for f32 {
|
|
|
|
type Int = u32;
|
|
|
|
fn bits() -> u32 {
|
|
|
|
32
|
|
|
|
}
|
2016-09-30 09:48:20 +08:00
|
|
|
fn exponent_bits() -> u32 {
|
|
|
|
8
|
|
|
|
}
|
2016-08-18 04:51:37 +08:00
|
|
|
fn significand_bits() -> u32 {
|
|
|
|
23
|
|
|
|
}
|
2016-09-30 09:48:33 +08:00
|
|
|
fn sign_mask() -> Self::Int {
|
|
|
|
1 << (Self::bits() - 1)
|
|
|
|
}
|
|
|
|
fn exponent_mask() -> Self::Int {
|
|
|
|
((1 << Self::exponent_bits()) - 1) << Self::significand_bits()
|
|
|
|
}
|
|
|
|
fn significand_mask() -> Self::Int {
|
|
|
|
(1 << Self::significand_bits()) - 1
|
|
|
|
}
|
2016-08-18 04:51:37 +08:00
|
|
|
fn repr(self) -> Self::Int {
|
|
|
|
unsafe { mem::transmute(self) }
|
|
|
|
}
|
2016-08-22 00:24:58 +08:00
|
|
|
#[cfg(test)]
|
|
|
|
fn eq_repr(self, rhs: Self) -> bool {
|
|
|
|
if self.is_nan() && rhs.is_nan() {
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
self.repr() == rhs.repr()
|
|
|
|
}
|
|
|
|
}
|
2016-08-18 04:51:37 +08:00
|
|
|
fn from_repr(a: Self::Int) -> Self {
|
|
|
|
unsafe { mem::transmute(a) }
|
|
|
|
}
|
2016-09-30 09:48:33 +08:00
|
|
|
|
|
|
|
fn from_parts(sign: bool, exponent: Self::Int, significand: Self::Int) -> Self {
|
|
|
|
Self::from_repr(((sign as Self::Int) << (Self::bits() - 1)) |
|
|
|
|
exponent & Self::exponent_mask() |
|
|
|
|
significand & Self::significand_mask())
|
|
|
|
}
|
2016-09-30 09:48:20 +08:00
|
|
|
fn sign(self) -> bool {
|
2016-09-30 09:48:33 +08:00
|
|
|
(self.repr() & Self::sign_mask()) != 0
|
2016-09-30 09:48:20 +08:00
|
|
|
}
|
|
|
|
fn exponent(self) -> Self::Int {
|
2016-09-30 09:48:33 +08:00
|
|
|
self.repr() >> Self::significand_bits() & Self::exponent_mask()
|
2016-09-30 09:48:20 +08:00
|
|
|
}
|
|
|
|
fn significand(self) -> Self::Int {
|
2016-09-30 09:48:33 +08:00
|
|
|
self.repr() & Self::significand_mask()
|
2016-09-30 09:48:20 +08:00
|
|
|
}
|
2016-08-18 04:51:37 +08:00
|
|
|
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
|
|
|
|
}
|
2016-09-30 09:48:20 +08:00
|
|
|
fn exponent_bits() -> u32 {
|
|
|
|
11
|
|
|
|
}
|
2016-08-18 04:51:37 +08:00
|
|
|
fn significand_bits() -> u32 {
|
|
|
|
52
|
|
|
|
}
|
2016-09-30 09:48:33 +08:00
|
|
|
fn sign_mask() -> Self::Int {
|
|
|
|
1 << (Self::bits() - 1)
|
|
|
|
}
|
|
|
|
fn exponent_mask() -> Self::Int {
|
|
|
|
((1 << Self::exponent_bits()) - 1) << Self::significand_bits()
|
|
|
|
}
|
|
|
|
fn significand_mask() -> Self::Int {
|
|
|
|
(1 << Self::significand_bits()) - 1
|
|
|
|
}
|
2016-08-18 04:51:37 +08:00
|
|
|
fn repr(self) -> Self::Int {
|
|
|
|
unsafe { mem::transmute(self) }
|
|
|
|
}
|
2016-08-22 00:24:58 +08:00
|
|
|
#[cfg(test)]
|
|
|
|
fn eq_repr(self, rhs: Self) -> bool {
|
|
|
|
if self.is_nan() && rhs.is_nan() {
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
self.repr() == rhs.repr()
|
|
|
|
}
|
|
|
|
}
|
2016-08-18 04:51:37 +08:00
|
|
|
fn from_repr(a: Self::Int) -> Self {
|
|
|
|
unsafe { mem::transmute(a) }
|
|
|
|
}
|
2016-09-30 09:48:33 +08:00
|
|
|
fn from_parts(sign: bool, exponent: Self::Int, significand: Self::Int) -> Self {
|
|
|
|
Self::from_repr(((sign as Self::Int) << (Self::bits() - 1)) |
|
|
|
|
exponent & Self::exponent_mask() |
|
|
|
|
significand & Self::significand_mask())
|
|
|
|
}
|
2016-09-30 09:48:20 +08:00
|
|
|
fn sign(self) -> bool {
|
2016-09-30 09:48:33 +08:00
|
|
|
(self.repr() & Self::sign_mask()) != 0
|
2016-09-30 09:48:20 +08:00
|
|
|
}
|
|
|
|
fn exponent(self) -> Self::Int {
|
2016-09-30 09:48:33 +08:00
|
|
|
self.repr() >> Self::significand_bits() & Self::exponent_mask()
|
2016-09-30 09:48:20 +08:00
|
|
|
}
|
|
|
|
fn significand(self) -> Self::Int {
|
2016-09-30 09:48:33 +08:00
|
|
|
self.repr() & Self::significand_mask()
|
2016-09-30 09:48:20 +08:00
|
|
|
}
|
2016-08-18 04:51:37 +08:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|