-
Notifications
You must be signed in to change notification settings - Fork 134
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
Exp and pow return infinity too early #600
Comments
Hello @MattyMuir, thanks for reporting this! We will try to adjust the threshold so it is a little closer to general expectation. I also think that constants should be represented using hexfloat, they currently use too many digits, which I don't think is necessary. Please consider the 2 following notes just FYI Note 1: I take back my original note, the ieee754 standard does mandate overflow for exp and pow (table 9.1) in the way defined in section 7.4:
Note 2: Other math libraries like Arm Optimized routines have a more elaborate approach, it evacuates the early overflow to a separate branch where it is fixed, see https://github.com/ARM-software/optimized-routines/blob/master/math/aarch64/sv_exp_1u5.c. |
Just edited my notes above, as the first one was mistaken. |
Just had a look at some of the single precision functions. Looks like similar bugs are present in |
Hello @MattyMuir, Thank you for reporting these too. It does seem to impact several routines indeed. |
I'll soon upload a PR to fix this and add some tests. I just realised #523 reported the same issue, and confirms that the ulp error is still 1.0 in the interval between the old and new thresholds. |
Similarly the log1pf issue was pointed out in #473. |
Hello @shibatch, We are looking at a range of functions for which SLEEF implements an early overflow bound (as in earlier than what the standard recommends). I suspect these bounds were set to maintain accuracy, could you please confirm that? If so we need to be careful if we are going to update them. Luckily it turns out that I will run tests as thoroughly as I can, but I would appreciate your insight on this. If you have specific comments on |
Hello, |
Ok, good to know. I think it is fair, they are relatively minor issues. Thanks! |
Issue shibatch#600 highlighted a limit of current implementation where early overflow is noticed, which diverges from the C99 standard. This patch adds test to catch this type of cases. It only checks a few points therefore we don't know for sure if overflow occurs at the right time but we know if something is wrong in the overflow region. Fix both scalar and simd implementation (double precision) Fixes shibatch#523.
I've just created a PR to fix the threshold. As indicated in #523 we can confidently say that the change does not affect overall accuracy in exp. I have checked pow accuracy with our in-house ulp error assessment program, and here is what I get
@shibatch Can you please confirm wether the 1.0ULP threshold include the extra 0.5ULP offset introduced by the rounding of the input value (worst case in round to nearest)?
These max are independent of the change in oflow threshold, since
Note that it is quite difficult to isolate cases for which |
I have confirmed that the error exceeds 1ulp when arguments are (0x1.7fed001e5f0edp-1,0x1.1b5ce4d1fb0aep+11). pow : arg0 = 0x1.7fed001e5f0edp-1 (0.749855), arg1 = 0x1.1b5ce4d1fb0aep+11 (2266.9), ulp = 1.00511, t = 3.852255144842898e-284, c = 3.85226e-284 |
Thanks for confirming.
|
Rounding of inputs is not taken into account in calculating accuracy. |
Testing with these same arguments in the latest version also exceeds 1ULP error. It looks like this inaccuracy is unrelated to the new PR. |
Describe the bug
The
exp
function (for SIMD and pure C) returns infinity for all values past a certain threshold, but this threshold is slightly lower than it should be. Looking at the code for double precision, infinity is returned for allx > 709.78271114955742909217217426
. However, there are values past this limit whose exponential can still be represented with a finite double. All standard libraries I've tested use the following, slightly larger, threshold insteadx > 709.782712893384
(0x1.62e42fefa39efp+9
in binary). This doesn't appear to be an issue for the single precision implementation.This same threshold is also used in the
pow
function, so the bug is present there as well.Command lines, logs and environment
All the build steps, environment and configuration are the same as in my other issue, #570, though they shouldn't matter in this case.
To Reproduce
This produces the following output on my machine
Fixing this issue might be as simple as just changing the constant in the implementation, provided the series is still accurate past this point.
The text was updated successfully, but these errors were encountered: