@@ -50,7 +50,12 @@ pub(crate) fn rem_pio2(x: f64) -> (i32, f64, f64) {
5050
5151 fn medium ( x : f64 , ix : u32 ) -> ( i32 , f64 , f64 ) {
5252 /* rint(x/(pi/2)), Assume round-to-nearest. */
53- let f_n = x as f64 * INV_PIO2 + TO_INT - TO_INT ;
53+ let tmp = x as f64 * INV_PIO2 + TO_INT ;
54+ // force rounding of tmp to it's storage format on x87 to avoid
55+ // excess precision issues.
56+ #[ cfg( all( target_arch = "x86" , not( target_feature = "sse2" ) ) ) ]
57+ let tmp = force_eval ! ( tmp) ;
58+ let f_n = tmp - TO_INT ;
5459 let n = f_n as i32 ;
5560 let mut r = x - f_n * PIO2_1 ;
5661 let mut w = f_n * PIO2_1T ; /* 1st round, good to 85 bits */
@@ -190,20 +195,28 @@ mod tests {
190195
191196 #[ test]
192197 fn test_near_pi ( ) {
198+ let arg = 3.141592025756836 ;
199+ let arg = force_eval ! ( arg) ;
193200 assert_eq ! (
194- rem_pio2( 3.141592025756836 ) ,
201+ rem_pio2( arg ) ,
195202 ( 2 , -6.278329573009626e-7 , -2.1125998133974653e-23 )
196203 ) ;
204+ let arg = 3.141592033207416 ;
205+ let arg = force_eval ! ( arg) ;
197206 assert_eq ! (
198- rem_pio2( 3.141592033207416 ) ,
207+ rem_pio2( arg ) ,
199208 ( 2 , -6.20382377148128e-7 , -2.1125998133974653e-23 )
200209 ) ;
210+ let arg = 3.141592144966125 ;
211+ let arg = force_eval ! ( arg) ;
201212 assert_eq ! (
202- rem_pio2( 3.141592144966125 ) ,
213+ rem_pio2( arg ) ,
203214 ( 2 , -5.086236681942706e-7 , -2.1125998133974653e-23 )
204215 ) ;
216+ let arg = 3.141592979431152 ;
217+ let arg = force_eval ! ( arg) ;
205218 assert_eq ! (
206- rem_pio2( 3.141592979431152 ) ,
219+ rem_pio2( arg ) ,
207220 ( 2 , 3.2584135866119817e-7 , -2.1125998133974653e-23 )
208221 ) ;
209222 }
0 commit comments