-
Notifications
You must be signed in to change notification settings - Fork 160
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
Avoid overflows when converting rationals with large denominator and/or numerator to floating point #4144
Conversation
Unfortunately, this still isn't good enough if the denominator is still "large" after reduction:
but of course it should give 1. One idea would be to multiply the "fractional" part by something like 2^53, turn that into an integer, and finally divide by |
478bb76
to
7d8f948
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The change you've made is obviously mathematically correct, and improves the situation.
How do you want to proceed with this PR? If you're happy for it to be merged, then go for it. But if you want this PR to not be merged until it contains a complete fix, then I suggest adding the 'Do not merge' label.
I was kinda hoping that @laurentbartholdi or @stevelinton who wrote the float support in GAP would have a comment on this... |
The very early float support I did, if I recall correctly, did not provide a conversion from Rationals -- my plan was to keep rationals as separate from floats as possible. So I don't think I have any special insight here. I would still argue that such conversions should not be part of inner loops of calculations -- they are useful for UI purposes and a few "hybrid" algorithms, but performance is not really a concern. A more accurate conversion is necessarily going to have to know details of the currently selected FP implementation, essentially the precision, so that it can find the nearest FP value to the rational. For IEEE FP that will means first identifying which k so that 2^k < Abs(x) < 2^{k+1} (k may be negative) and then finding the the closest multiple of 2^{k-53} (or something similar) to x. I don't think there is a short and slick way to do it. |
I'm fine with all solutions, but would prefer just throwing an error when
the conversion cannot be done easily.
…On Fri, Nov 20, 2020 at 12:48 PM Steve Linton ***@***.***> wrote:
The very early float support I did, if I recall correctly, did not provide
a conversion from Rationals -- my plan was to keep rationals as separate
from floats as possible. So I don't think I have any special insight here.
I would still argue that such conversions should not be part of inner
loops of calculations -- they are useful for UI purposes and a few "hybrid"
algorithms, but performance is not really a concern.
A more accurate conversion is necessarily going to have to know details of
the currently selected FP implementation, essentially the precision, so
that it can find the nearest FP value to the rational. For IEEE FP that
will means first identifying which k so that 2^k < Abs(x) < 2^{k+1} (k may
be negative) and then finding the the closest multiple of 2^{k-53} (or
something similar) to x. I don't think there is a short and slick way to do
it.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#4144 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AARAQUA3GRJACSBMCEBEK43SQZJSTANCNFSM4STGRFHQ>
.
--
Laurent Bartholdi laurent.bartholdi<at>gmail<dot>com
Mathematisches Institut, Georg-August Universität zu Göttingen
Bunsenstrasse 3-5, D-37073 Göttingen, Germany
|
@laurentbartholdi I think the conversion can always be done "easily", the problem is how accurate it is (right now it can have zero accurate digits...). I am not sure whether "throwing an error when the conversion cannot be done easily" is substantially easier than doing the conversion? Perhaps it would make more sense to always raise an error in the generic conversion methods, something like "not implemented for this floating point type", and then instead provide methods only for the machine integers, for which we can implement the conversion fairly accurately (I think)? |
I don't have strong feelings about this; but looking at the PR I think it's
fixing the wrong problem: it would be better to ask
MakeFloat(filter,10^309+1) to trigger an error, rather than to attempt to
force this huge integer into IEEE754. The code for converting rationals to
fp should be as clean as possible: convert numerator and denominator, and
divide.
…On Fri, Nov 20, 2020 at 5:27 PM Max Horn ***@***.***> wrote:
@laurentbartholdi <https://github.com/laurentbartholdi> I think the
conversion can always be done "easily", the problem is how accurate it is
(right now it can have zero accurate digits...). I am not sure whether
"throwing an error when the conversion cannot be done easily" is
substantially easier than doing the conversion?
Perhaps it would make more sense to always raise an error in the generic
conversion methods, something like "not implemented for this floating point
type", and then instead provide methods only for the machine integers, for
which we can implement the conversion fairly accurately (I think)?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#4144 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AARAQUDIH54RMNA45QI4UGDSQ2KG7ANCNFSM4STGRFHQ>
.
--
Laurent Bartholdi laurent.bartholdi<at>gmail<dot>com
Mathematisches Institut, Georg-August Universität zu Göttingen
Bunsenstrasse 3-5, D-37073 Göttingen, Germany
|
The question is, what is the goal? I would have thought that it is "produce a useful conversion which minimizes the numerical error". I don't see the value in producing one that is "as clean as possible" in the vein @laurentbartholdi mentions; this is how the code this PR is replacing looks like -- and as documented here, this needlessly produces atrocious numerical errors, and overall seems mostly useless. I think not providing any conversion would be preferable over that, as coding this "clean" conversion is trivial anyway. @stevelinton has a point in that we can implement a good quality conversion for machine floats, as we know their precision. So, I am tempted to do that. The "generic" conversion then can either be implemented by first converting to machine floats and then to the actual target (assuming that all reasonable float implementations will allow conversion from/to machine floats). Or we replace the "generic" conversion with a "not implemented" errors: I don't think providing a bad default is good, indeed I think it's actively harmful. So, overall, it seems we all agree that an error would be best in the general case :-) |
7d8f948
to
bd0104a
Compare
bd0104a
to
ae974ef
Compare
Codecov Report
@@ Coverage Diff @@
## master #4144 +/- ##
===========================================
+ Coverage 82.23% 93.40% +11.17%
===========================================
Files 685 716 +31
Lines 290627 812429 +521802
Branches 8626 0 -8626
===========================================
+ Hits 238994 758888 +519894
- Misses 49743 53541 +3798
+ Partials 1890 0 -1890
|
Fixes #2734