-
Notifications
You must be signed in to change notification settings - Fork 103
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
Error in rational -> float conversion #390
Comments
Indeed. If you want a But it would be nice if On macOS intel:
It would be nice too if we had:
Otherwise note that the result obtained is not too bad. It's not the closest single-float, but it's the closest above:
|
Are there any workarounds? Returning 411071.03 when the value is 411071.00000541273 is a rather significant error in many situations. Just confirmed that SBCL behaviour is 'correct' (i.e., returns the closest). |
Yes, use: |
Found a big difference:
Formatted with |
I noted ECL actually give the same answers. I used mainly SBCL, except ECL has support over IOS ... wonder I may try to side test also ECL. Let us see. |
I don't understand what the issue is - maybe someone can explain it: Floating point numbers carry between 6-7 digits of precision (as per IBM page). The single precision result of 411071.03 is correct to 7 digits. The last digit shown (3) is the eight digit and should not be taken into account. To me this looks like a user error - not understanding floating point precision. But then again, maybe I am missing something. Thanks, |
On Sun, Jul 3, 2022 at 2:29 AM Mirko ***@***.***> wrote:
I don't understand what the issue is - maybe someone can explain it:
Floating point numbers carry between 6-7 digits of precision (as per IBM
page
<https://www.ibm.com/support/pages/single-precision-floating-point-accuracy#:~:text=A%20single%2Dprecision%20float%20only,left%20for%20floating%20part%20precision.>
.
SINGLE floats. The problem is with DOUBLE floats.
…
Message ID: ***@***.***>
|
Sorry, I still don't get it:
|
I think the issue is that 411071.0 is closer to the fraction than 411071.03. 411071.03 and 411071 differ by 1 bit. Consider:
It's pretty clear that the error from the first is less than the second. So you would want |
This is demonstrated by:
So, it appears for CCL the
SBCL's If anyone have more experience with SBCL, could you please give me some hints on where I could find the rational to float conversion? |
I think this is SBCL's implementation that coverts rational to float https://github.com/sbcl/sbcl/blob/ac267f21721663b196aefe4bfd998416e3cc4332/src/code/float.lisp#L444 See the comments above it on how they attempt to avoid inaccuracies. It seems what SBCL did is in fact very simple: down scale the numerator and denominator by power of 2 if they exceeds the mantissa size. When I have time I might write a patch to CCL to fix the issue. |
There are [at least] two issues here:
Let's take these one at a time: There are several places in CCL that assume a fixnum has roughly the same number of significant bits as a short-float, which was roughly true in the days of CCL-32:
Thus in CCL-32 if you convert a fixnum to a short-float you won't lose much precision. Unfortunately, this assumption is quite invalid in CCL-64:
So in CCL-64, if you convert a fixnum to a short-float, you can lose a great deal of precision. In principle it's easy to fix
After this fix, And now CCL-64 passes @metayan's test above too, returning the same value as ABCL. But there's a problem, which brings us to the second issue. Now CCL's RATIONALIZE.1 test fails.
Only the least significant digit is wrong, but it's enough to make I've investigated this issue enough to know that nothing is wrong with
|
@svspire I think the rational to double conversion needs also been patched and follows SBCL’s implementation that to single and to double conversion is treated in the same way (only the idea, not necessarily using same implementation). It is a bad idea assuming nothing would be wrong if double-precision is used. I think the proper way to fix this is replace the bignump test by more proper conditions. Which as you observed is not a valid assumption for x86-64 also, I doubt the in consistencies for rationalize is caused by incorrect rounding in rational to float conversion instead of a flaw in rationalize implementation. I have only viewed the function definition but cannot notice any problems yet, but I’ll test them after I get back to the computer. |
Adopting the solution from SBCL is easier than I think: and this does not suffer from the rationalize problem that the ad hoc fix @svspire would produce
Now the question would be should I do the same to |
Hmm. If you work out the decimal points, the float is: 411071.00000541273, that's a long way from .03
Maybe coerce? Nope, that's even worse:
Interestingly, taking one digit off the rational produces a correct result:
The text was updated successfully, but these errors were encountered: