-
Notifications
You must be signed in to change notification settings - Fork 1.6k
<complex>: Replace handwritten transcendental functions
#5956
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
`_LDtest` is used only for 80-bit `long double`.
They return the same values:
C:\Temp>type meow.cpp
#include <cmath>
#include <limits>
#include <print>
using namespace std;
extern "C" _CRTIMP2_PURE short __CLRCALL_PURE_OR_CDECL _Dtest(double*) noexcept;
void classify(double dbl) {
const short stl = _Dtest(&dbl);
const int crt = fpclassify(dbl);
println("dbl: {:6}; stl: {:2}; crt: {:2}; Equal: {}", dbl, stl, crt, stl == crt);
}
int main() {
classify(numeric_limits<double>::denorm_min());
classify(3.14);
classify(0.0);
classify(-0.0);
classify(numeric_limits<double>::infinity());
classify(numeric_limits<double>::quiet_NaN());
}
C:\Temp>cl /EHsc /nologo /W4 /std:c++latest /MTd /Od meow.cpp && meow
meow.cpp
dbl: 5e-324; stl: -2; crt: -2; Equal: true
dbl: 3.14; stl: -1; crt: -1; Equal: true
dbl: 0; stl: 0; crt: 0; Equal: true
dbl: -0; stl: 0; crt: 0; Equal: true
dbl: inf; stl: 1; crt: 1; Equal: true
dbl: nan; stl: 2; crt: 2; Equal: true
I verified that this preserves their observable behavior (occasionally differing by 1 or 2 ULPs). This will allow `<complex>` to benefit from future compiler improvements to the accuracy of UCRT functions. Note that `<complex>` never used the `short` return value (an `fpclassify`-style code), and it always passed 0 for `short eoff`.
…underflow` functions, the `_Dval` and `_Fval` unions, and now-unused macros.
…lts. We're much closer to Wolfram Alpha now, although not quite perfect.
This comment was marked as resolved.
This comment was marked as resolved.
|
This still doesn't look serious enough: STL/tests/std/tests/GH_001059_hyperbolic_truncation/env.lst Lines 1 to 4 in 88db4d5
I think |
|
#include <complex>
#include <print>
using namespace std;
#define EVAL_AND_PRINT(expr) \
{ \
const auto result = (expr); \
println("{} = complex{{{}, {}}}", #expr, real(result), imag(result)); \
}
int main() {
EVAL_AND_PRINT(exp(complex{710.0, 0.8}));
EVAL_AND_PRINT(sin(complex{0.5, 710.5}));
}Before PR: After PR: |
|
Thanks, that's what I feared. I'll abandon this attempt for now, but may salvage smaller pieces. |
Followup to #5836. This is unusually daring, even for me, and I would appreciate reviews from our math wizards.
This purges what I believe is the last of our legacy math machinery, which was powering various
<complex>transcendental functions. As their previous comments indicated, they appeared to be equivalent to simple combinations of UCRT functions (which I verified through spot checks of behavior).I'm a little worried that I'm removing important special cases, but I got all of the tests to pass (I did have to restore one special case for zero that made sense). One positive sign is that a couple of libcxx tests started passing. We also had a very picky test
GH_001059_hyperbolic_truncationthat was comparing one set of function calls to another set of function calls, instead of ground truth. This was failing until I took the original values, ran them through Wolfram Alpha to get known-good results forcoshandsinh, and then overhauled the test to expect them. The previous implementation gets most of the results incorrect according to Wolfram Alpha. The new implementation gets all but one correct, with only 1 ULP of difference, which I regard as an improvement. And x86 actually behaves correctly, so I believe that UCRT behavior variation is responsible.I've verified that the dllexport surface is unchanged.
Commits
_CSTD _Cosh(_Left, _Right)=>_STD cosh(_Left) * _Right_CSTD _Sinh(_Left, _Right)=>_STD sinh(_Left) * _Right_Xbig,_FXbig._Feraise()and its macros.DSIGN,FSIGNmacros._Dtest,_LDtest,_FDtestfor bincompat._LDtestis used only for 80-bitlong double._Dtestwithfpclassify._Exp,_FExp,_LExpfor bincompat.<complex>to benefit from future compiler improvements to the accuracy of UCRT functions.<complex>never used theshortreturn value (anfpclassify-style code), and it always passed 0 forshort eoff._FDnorm,_FDscale,_Xfe_overflow,_Xfe_underflowfunctions, the_Dvaland_Fvalunions, and now-unused macros.<cmath>.<ymath.h>, fuse remnants into<complex>._Expcodepaths. Enable passing libcxx tests.GH_001059_hyperbolic_truncationto expect more accurate results.