This repository was archived by the owner on Apr 28, 2025. It is now read-only.
File tree Expand file tree Collapse file tree 5 files changed +78
-6
lines changed Expand file tree Collapse file tree 5 files changed +78
-6
lines changed Original file line number Diff line number Diff line change 1+ #![ allow( unreachable_code) ]
12use core:: f64;
23
34const TOINT : f64 = 1. / f64:: EPSILON ;
@@ -15,6 +16,24 @@ pub fn ceil(x: f64) -> f64 {
1516 return unsafe { :: core:: intrinsics:: ceilf64( x) }
1617 }
1718 }
19+ #[ cfg( all( target_arch = "x86" , not( target_feature = "sse2" ) ) ) ]
20+ {
21+ //use an alternative implementation on x86, because the
22+ //main implementation fails with the x87 FPU used by
23+ //debian i386, probablly due to excess precision issues.
24+ //basic implementation taken from https://github.com/rust-lang/libm/issues/219
25+ use super :: fabs;
26+ if fabs ( x) . to_bits ( ) < 4503599627370496.0_f64 . to_bits ( ) {
27+ let truncated = x as i64 as f64 ;
28+ if truncated < x {
29+ return truncated + 1.0 ;
30+ } else {
31+ return truncated;
32+ }
33+ } else {
34+ return x;
35+ }
36+ }
1837 let u: u64 = x. to_bits ( ) ;
1938 let e: i64 = ( u >> 52 & 0x7ff ) as i64 ;
2039 let y: f64 ;
Original file line number Diff line number Diff line change 1+ #![ allow( unreachable_code) ]
12use core:: f64;
23
34const TOINT : f64 = 1. / f64:: EPSILON ;
@@ -15,6 +16,24 @@ pub fn floor(x: f64) -> f64 {
1516 return unsafe { :: core:: intrinsics:: floorf64( x) }
1617 }
1718 }
19+ #[ cfg( all( target_arch = "x86" , not( target_feature = "sse2" ) ) ) ]
20+ {
21+ //use an alternative implementation on x86, because the
22+ //main implementation fails with the x87 FPU used by
23+ //debian i386, probablly due to excess precision issues.
24+ //basic implementation taken from https://github.com/rust-lang/libm/issues/219
25+ use super :: fabs;
26+ if fabs ( x) . to_bits ( ) < 4503599627370496.0_f64 . to_bits ( ) {
27+ let truncated = x as i64 as f64 ;
28+ if truncated > x {
29+ return truncated - 1.0 ;
30+ } else {
31+ return truncated;
32+ }
33+ } else {
34+ return x;
35+ }
36+ }
1837 let ui = x. to_bits ( ) ;
1938 let e = ( ( ui >> 52 ) & 0x7ff ) as i32 ;
2039
Original file line number Diff line number Diff line change @@ -369,6 +369,10 @@ mod tests {
369369 }
370370 #[ test]
371371 fn test_y1f_2002 ( ) {
372- assert_eq ! ( y1f( 2.0000002_f32 ) , -0.10703229_f32 ) ;
372+ //allow slightly different result on x87
373+ let res = y1f ( 2.0000002_f32 ) ;
374+ if res != -0.10703231_f32 {
375+ assert_eq ! ( res, -0.10703229_f32 ) ;
376+ }
373377 }
374378}
Original file line number Diff line number Diff line change @@ -43,7 +43,9 @@ pub(crate) fn rem_pio2f(x: f32) -> (i32, f64) {
4343 if ix < 0x4dc90fdb {
4444 /* |x| ~< 2^28*(pi/2), medium size */
4545 /* Use a specialized rint() to get fn. Assume round-to-nearest. */
46- let f_n = x64 * INV_PIO2 + TOINT - TOINT ;
46+ // use to_bits and from_bits to force rounding to storage format on
47+ // x87.
48+ let f_n = f64:: from_bits ( ( x64 * INV_PIO2 + TOINT ) . to_bits ( ) ) - TOINT ;
4749 return ( f_n as i32 , x64 - f_n * PIO2_1 - f_n * PIO2_1T ) ;
4850 }
4951 if ix >= 0x7f800000 {
Original file line number Diff line number Diff line change @@ -147,10 +147,38 @@ mod tests {
147147 let ( s_minus, c_minus) = sincosf ( theta - 2. * PI ) ;
148148
149149 const TOLERANCE : f32 = 1e-6 ;
150- assert ! ( ( s - s_plus) . abs( ) < TOLERANCE ) ;
151- assert ! ( ( s - s_minus) . abs( ) < TOLERANCE ) ;
152- assert ! ( ( c - c_plus) . abs( ) < TOLERANCE ) ;
153- assert ! ( ( c - c_minus) . abs( ) < TOLERANCE ) ;
150+ assert ! (
151+ ( s - s_plus) . abs( ) < TOLERANCE ,
152+ "|{} - {}| = {} >= {}" ,
153+ s,
154+ s_plus,
155+ ( s - s_plus) . abs( ) ,
156+ TOLERANCE
157+ ) ;
158+ assert ! (
159+ ( s - s_minus) . abs( ) < TOLERANCE ,
160+ "|{} - {}| = {} >= {}" ,
161+ s,
162+ s_minus,
163+ ( s - s_minus) . abs( ) ,
164+ TOLERANCE
165+ ) ;
166+ assert ! (
167+ ( c - c_plus) . abs( ) < TOLERANCE ,
168+ "|{} - {}| = {} >= {}" ,
169+ c,
170+ c_plus,
171+ ( c - c_plus) . abs( ) ,
172+ TOLERANCE
173+ ) ;
174+ assert ! (
175+ ( c - c_minus) . abs( ) < TOLERANCE ,
176+ "|{} - {}| = {} >= {}" ,
177+ c,
178+ c_minus,
179+ ( c - c_minus) . abs( ) ,
180+ TOLERANCE
181+ ) ;
154182 }
155183 }
156184}
You can’t perform that action at this time.
0 commit comments