- Algorithm:
- Step 1 - Range reduction: for a double precision input `x`, return `k`
and `u` such that
- k is an integer
- u = x - k * pi / 128, and |u| < pi/256
- Step 2 - Calculate `sin(u)` and `cos(u)` in double-double using Taylor
polynomials with errors < 2^-70 with FMA or < 2^-66 w/o FMA.
- Step 3 - Calculate `sin(x) = sin(k*pi/128) * cos(u) + cos(k*pi/128) *
sin(u)` using look-up table for `sin(k*pi/128)` and `cos(k*pi/128)`.
- Step 4 - Use Ziv's rounding test to decide if the result is correctly
rounded.
- Step 4' - If the Ziv's rounding test failed, redo step 1-3 using
128-bit precision.
- Currently, without FMA instructions, the large range reduction only
works correctly for the default rounding mode (FE_TONEAREST).
- Provide `LIBC_MATH` flag so that users can set `LIBC_MATH =
LIBC_MATH_SKIP_ACCURATE_PASS` to build the `sin` function without step 4
and 4'.
Closes#84689.
Adding @lntue for review.
I was curious about the implementation of
`round_using_current_rounding_mode` used for the `nearbyint` functions.
It has one of the rounding modes as unreachable
([here](https://github.com/llvm/llvm-project/blob/main/libc/src/__support/FPUtil/NearestIntegerOperations.h#L243)),
and I was wondering if this was okay for the `nearbyint` functions.
---------
Co-authored-by: Michael Flanders <mkf727@cs.washington.edu>
Implements the functions `roundeven()`, `roundevenf()`, `roundevenl()`
from the roundeven family of functions introduced in C23. Also
implements `roundevenf128()`.
Re-organizes the tables that listed libc's support for math functions,
and adds two new columns to the tables indicating where the respective
function definitions and error handling methods are located in the C23
standard draft WG14-N3096.
We compute atan2f(y, x) in 2 stages:
- Fast step: perform computations in double precision , with relative
errors < 2^-50
- Accurate step: if the result from the Fast step fails Ziv's rounding
test, then we perform computations in double-double precision, with
relative errors < 2^-100.
On Ryzen 5900X, worst-case latency is ~ 200 clocks, compared to average
latency ~ 60 clocks, and average reciprocal throughput ~ 20 clocks.
Continuing #84689, this one required more changes than the others, so I
am making it a separate PR.
Extends some stuff in `str_to_float.h`, `str_to_integer.h` to work on
types wider than `unsigned long long` and `uint64_t`.
cc @lntue for review.
- Allow `FMod` template to have different computational types and make
it work for 80-bit long double.
- Switch to use `uint64_t` as the intermediate computational types for
`float`, significantly reduce the latency of `fmodf` when the exponent
difference is large.