Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.

Commit 705ce5f

Browse files
author
Peter Michael Green
committed
Add forced rounding to storage format for x87 to rem_pio2.rs as well.
1 parent 1b21019 commit 705ce5f

File tree

2 files changed

+79
-1
lines changed

2 files changed

+79
-1
lines changed

libm/src/math/rem_pio2.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@ 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")))]force_eval!(tmp);
57+
let f_n = tmp - TO_INT;
5458
let n = f_n as i32;
5559
let mut r = x - f_n * PIO2_1;
5660
let mut w = f_n * PIO2_1T; /* 1st round, good to 85 bits */

libm/src/math/sincos.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,77 @@ pub fn sincos(x: f64) -> (f64, f64) {
5757
_ => (0.0, 1.0),
5858
}
5959
}
60+
61+
// These tests are based on those from sincosf.rs
62+
#[cfg(test)]
63+
mod tests {
64+
use super::sincos;
65+
66+
const TOLERANCE: f64 = 1e-6;
67+
68+
#[test]
69+
fn with_pi() {
70+
let (s, c) = sincos(core::f64::consts::PI);
71+
assert!(
72+
(s - 0.0).abs() < TOLERANCE,
73+
"|{} - {}| = {} >= {}",
74+
s,
75+
0.0,
76+
(s - 0.0).abs(),
77+
TOLERANCE
78+
);
79+
assert!(
80+
(c + 1.0).abs() < TOLERANCE,
81+
"|{} + {}| = {} >= {}",
82+
c,
83+
1.0,
84+
(s + 1.0).abs(),
85+
TOLERANCE
86+
);
87+
}
88+
89+
#[test]
90+
fn rotational_symmetry() {
91+
use core::f64::consts::PI;
92+
const N: usize = 24;
93+
for n in 0..N {
94+
let theta = 2. * PI * (n as f64) / (N as f64);
95+
let (s, c) = sincos(theta);
96+
let (s_plus, c_plus) = sincos(theta + 2. * PI);
97+
let (s_minus, c_minus) = sincos(theta - 2. * PI);
98+
99+
assert!(
100+
(s - s_plus).abs() < TOLERANCE,
101+
"|{} - {}| = {} >= {}",
102+
s,
103+
s_plus,
104+
(s - s_plus).abs(),
105+
TOLERANCE
106+
);
107+
assert!(
108+
(s - s_minus).abs() < TOLERANCE,
109+
"|{} - {}| = {} >= {}",
110+
s,
111+
s_minus,
112+
(s - s_minus).abs(),
113+
TOLERANCE
114+
);
115+
assert!(
116+
(c - c_plus).abs() < TOLERANCE,
117+
"|{} - {}| = {} >= {}",
118+
c,
119+
c_plus,
120+
(c - c_plus).abs(),
121+
TOLERANCE
122+
);
123+
assert!(
124+
(c - c_minus).abs() < TOLERANCE,
125+
"|{} - {}| = {} >= {}",
126+
c,
127+
c_minus,
128+
(c - c_minus).abs(),
129+
TOLERANCE
130+
);
131+
}
132+
}
133+
}

0 commit comments

Comments
 (0)