Merge pull request #50 from japaric/post-43
use utility function to compare the repr of floats
This commit is contained in:
commit
7811f92bea
|
@ -1,4 +1,6 @@
|
||||||
|
use core::mem;
|
||||||
use core::num::Wrapping;
|
use core::num::Wrapping;
|
||||||
|
|
||||||
use float::Float;
|
use float::Float;
|
||||||
|
|
||||||
macro_rules! add {
|
macro_rules! add {
|
||||||
|
@ -74,7 +76,7 @@ macro_rules! add {
|
||||||
|
|
||||||
// Swap a and b if necessary so that a has the larger absolute value.
|
// Swap a and b if necessary so that a has the larger absolute value.
|
||||||
if b_abs > a_abs {
|
if b_abs > a_abs {
|
||||||
::core::mem::swap(&mut a_rep, &mut b_rep);
|
mem::swap(&mut a_rep, &mut b_rep);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract the exponent and significand from the (possibly swapped) a and b.
|
// Extract the exponent and significand from the (possibly swapped) a and b.
|
||||||
|
@ -212,22 +214,14 @@ mod tests {
|
||||||
let (a, b) = (f32::from_repr(a.0), f32::from_repr(b.0));
|
let (a, b) = (f32::from_repr(a.0), f32::from_repr(b.0));
|
||||||
let x = super::__addsf3(a, b);
|
let x = super::__addsf3(a, b);
|
||||||
let y = a + b;
|
let y = a + b;
|
||||||
if !(x.is_nan() && y.is_nan()) {
|
x.eq_repr(y)
|
||||||
x.repr() == y.repr()
|
|
||||||
} else {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn adddf3(a: U64, b: U64) -> bool {
|
fn adddf3(a: U64, b: U64) -> bool {
|
||||||
let (a, b) = (f64::from_repr(a.0), f64::from_repr(b.0));
|
let (a, b) = (f64::from_repr(a.0), f64::from_repr(b.0));
|
||||||
let x = super::__adddf3(a, b);
|
let x = super::__adddf3(a, b);
|
||||||
let y = a + b;
|
let y = a + b;
|
||||||
if !(x.is_nan() && y.is_nan()) {
|
x.eq_repr(y)
|
||||||
x.repr() == y.repr()
|
|
||||||
} else {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,14 +231,14 @@ mod tests {
|
||||||
fn test_float_tiny_plus_tiny() {
|
fn test_float_tiny_plus_tiny() {
|
||||||
let tiny = f32::from_repr(1);
|
let tiny = f32::from_repr(1);
|
||||||
let r = super::__addsf3(tiny, tiny);
|
let r = super::__addsf3(tiny, tiny);
|
||||||
assert_eq!(r, tiny + tiny);
|
assert!(r.eq_repr(tiny + tiny));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_double_tiny_plus_tiny() {
|
fn test_double_tiny_plus_tiny() {
|
||||||
let tiny = f64::from_repr(1);
|
let tiny = f64::from_repr(1);
|
||||||
let r = super::__adddf3(tiny, tiny);
|
let r = super::__adddf3(tiny, tiny);
|
||||||
assert_eq!(r, tiny + tiny);
|
assert!(r.eq_repr(tiny + tiny));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -252,7 +246,7 @@ mod tests {
|
||||||
let a = f32::from_repr(327);
|
let a = f32::from_repr(327);
|
||||||
let b = f32::from_repr(256);
|
let b = f32::from_repr(256);
|
||||||
let r = super::__addsf3(a, b);
|
let r = super::__addsf3(a, b);
|
||||||
assert_eq!(r, a + b);
|
assert!(r.eq_repr(a + b));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -260,19 +254,19 @@ mod tests {
|
||||||
let a = f64::from_repr(327);
|
let a = f64::from_repr(327);
|
||||||
let b = f64::from_repr(256);
|
let b = f64::from_repr(256);
|
||||||
let r = super::__adddf3(a, b);
|
let r = super::__adddf3(a, b);
|
||||||
assert_eq!(r, a + b);
|
assert!(r.eq_repr(a + b));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_float_one_plus_one() {
|
fn test_float_one_plus_one() {
|
||||||
let r = super::__addsf3(1f32, 1f32);
|
let r = super::__addsf3(1f32, 1f32);
|
||||||
assert_eq!(r, 1f32 + 1f32);
|
assert!(r.eq_repr(1f32 + 1f32));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_double_one_plus_one() {
|
fn test_double_one_plus_one() {
|
||||||
let r = super::__adddf3(1f64, 1f64);
|
let r = super::__adddf3(1f64, 1f64);
|
||||||
assert_eq!(r, 1f64 + 1f64);
|
assert!(r.eq_repr(1f64 + 1f64));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -281,9 +275,7 @@ mod tests {
|
||||||
let b = f32::from_repr(0b11111111100100010001001010101010);
|
let b = f32::from_repr(0b11111111100100010001001010101010);
|
||||||
let x = super::__addsf3(a, b);
|
let x = super::__addsf3(a, b);
|
||||||
let y = a + b;
|
let y = a + b;
|
||||||
if !(x.is_nan() && y.is_nan()) {
|
assert!(x.eq_repr(y));
|
||||||
assert_eq!(x.repr(), y.repr());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -293,9 +285,7 @@ mod tests {
|
||||||
0b1111111111110010001000100101010101001000101010000110100011101011);
|
0b1111111111110010001000100101010101001000101010000110100011101011);
|
||||||
let x = super::__adddf3(a, b);
|
let x = super::__adddf3(a, b);
|
||||||
let y = a + b;
|
let y = a + b;
|
||||||
if !(x.is_nan() && y.is_nan()) {
|
assert!(x.eq_repr(y));
|
||||||
assert_eq!(x.repr(), y.repr());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -16,6 +16,12 @@ pub trait Float: Sized {
|
||||||
/// Returns `self` transmuted to `Self::Int`
|
/// Returns `self` transmuted to `Self::Int`
|
||||||
fn repr(self) -> 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`
|
/// Returns a `Self::Int` transmuted back to `Self`
|
||||||
fn from_repr(a: Self::Int) -> Self;
|
fn from_repr(a: Self::Int) -> Self;
|
||||||
|
|
||||||
|
@ -34,6 +40,14 @@ impl Float for f32 {
|
||||||
fn repr(self) -> Self::Int {
|
fn repr(self) -> Self::Int {
|
||||||
unsafe { mem::transmute(self) }
|
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 {
|
fn from_repr(a: Self::Int) -> Self {
|
||||||
unsafe { mem::transmute(a) }
|
unsafe { mem::transmute(a) }
|
||||||
}
|
}
|
||||||
|
@ -54,6 +68,14 @@ impl Float for f64 {
|
||||||
fn repr(self) -> Self::Int {
|
fn repr(self) -> Self::Int {
|
||||||
unsafe { mem::transmute(self) }
|
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 {
|
fn from_repr(a: Self::Int) -> Self {
|
||||||
unsafe { mem::transmute(a) }
|
unsafe { mem::transmute(a) }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue