Fix testcases on x87
This commit is contained in:
parent
d3fb52a7af
commit
17c9073298
5 changed files with 78 additions and 6 deletions
|
|
@ -1,3 +1,4 @@
|
|||
#![allow(unreachable_code)]
|
||||
use core::f64;
|
||||
|
||||
const TOINT: f64 = 1. / f64::EPSILON;
|
||||
|
|
@ -15,6 +16,24 @@ pub fn ceil(x: f64) -> f64 {
|
|||
return unsafe { ::core::intrinsics::ceilf64(x) }
|
||||
}
|
||||
}
|
||||
#[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
|
||||
{
|
||||
//use an alternative implementation on x86, because the
|
||||
//main implementation fails with the x87 FPU used by
|
||||
//debian i386, probablly due to excess precision issues.
|
||||
//basic implementation taken from https://github.com/rust-lang/libm/issues/219
|
||||
use super::fabs;
|
||||
if fabs(x).to_bits() < 4503599627370496.0_f64.to_bits() {
|
||||
let truncated = x as i64 as f64;
|
||||
if truncated < x {
|
||||
return truncated + 1.0;
|
||||
} else {
|
||||
return truncated;
|
||||
}
|
||||
} else {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
let u: u64 = x.to_bits();
|
||||
let e: i64 = (u >> 52 & 0x7ff) as i64;
|
||||
let y: f64;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#![allow(unreachable_code)]
|
||||
use core::f64;
|
||||
|
||||
const TOINT: f64 = 1. / f64::EPSILON;
|
||||
|
|
@ -15,6 +16,24 @@ pub fn floor(x: f64) -> f64 {
|
|||
return unsafe { ::core::intrinsics::floorf64(x) }
|
||||
}
|
||||
}
|
||||
#[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
|
||||
{
|
||||
//use an alternative implementation on x86, because the
|
||||
//main implementation fails with the x87 FPU used by
|
||||
//debian i386, probablly due to excess precision issues.
|
||||
//basic implementation taken from https://github.com/rust-lang/libm/issues/219
|
||||
use super::fabs;
|
||||
if fabs(x).to_bits() < 4503599627370496.0_f64.to_bits() {
|
||||
let truncated = x as i64 as f64;
|
||||
if truncated > x {
|
||||
return truncated - 1.0;
|
||||
} else {
|
||||
return truncated;
|
||||
}
|
||||
} else {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
let ui = x.to_bits();
|
||||
let e = ((ui >> 52) & 0x7ff) as i32;
|
||||
|
||||
|
|
|
|||
|
|
@ -369,6 +369,10 @@ mod tests {
|
|||
}
|
||||
#[test]
|
||||
fn test_y1f_2002() {
|
||||
assert_eq!(y1f(2.0000002_f32), -0.10703229_f32);
|
||||
//allow slightly different result on x87
|
||||
let res = y1f(2.0000002_f32);
|
||||
if res != -0.10703231_f32 {
|
||||
assert_eq!(res, -0.10703229_f32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,9 @@ pub(crate) fn rem_pio2f(x: f32) -> (i32, f64) {
|
|||
if ix < 0x4dc90fdb {
|
||||
/* |x| ~< 2^28*(pi/2), medium size */
|
||||
/* Use a specialized rint() to get fn. Assume round-to-nearest. */
|
||||
let f_n = x64 * INV_PIO2 + TOINT - TOINT;
|
||||
// use to_bits and from_bits to force rounding to storage format on
|
||||
// x87.
|
||||
let f_n = f64::from_bits((x64 * INV_PIO2 + TOINT).to_bits()) - TOINT;
|
||||
return (f_n as i32, x64 - f_n * PIO2_1 - f_n * PIO2_1T);
|
||||
}
|
||||
if ix >= 0x7f800000 {
|
||||
|
|
|
|||
|
|
@ -147,10 +147,38 @@ mod tests {
|
|||
let (s_minus, c_minus) = sincosf(theta - 2. * PI);
|
||||
|
||||
const TOLERANCE: f32 = 1e-6;
|
||||
assert!((s - s_plus).abs() < TOLERANCE);
|
||||
assert!((s - s_minus).abs() < TOLERANCE);
|
||||
assert!((c - c_plus).abs() < TOLERANCE);
|
||||
assert!((c - c_minus).abs() < TOLERANCE);
|
||||
assert!(
|
||||
(s - s_plus).abs() < TOLERANCE,
|
||||
"|{} - {}| = {} >= {}",
|
||||
s,
|
||||
s_plus,
|
||||
(s - s_plus).abs(),
|
||||
TOLERANCE
|
||||
);
|
||||
assert!(
|
||||
(s - s_minus).abs() < TOLERANCE,
|
||||
"|{} - {}| = {} >= {}",
|
||||
s,
|
||||
s_minus,
|
||||
(s - s_minus).abs(),
|
||||
TOLERANCE
|
||||
);
|
||||
assert!(
|
||||
(c - c_plus).abs() < TOLERANCE,
|
||||
"|{} - {}| = {} >= {}",
|
||||
c,
|
||||
c_plus,
|
||||
(c - c_plus).abs(),
|
||||
TOLERANCE
|
||||
);
|
||||
assert!(
|
||||
(c - c_minus).abs() < TOLERANCE,
|
||||
"|{} - {}| = {} >= {}",
|
||||
c,
|
||||
c_minus,
|
||||
(c - c_minus).abs(),
|
||||
TOLERANCE
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue