Skip to content
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

Check for overflow in gcd algorithm #15228

Merged
merged 1 commit into from
Feb 27, 2016
Merged

Conversation

eschnett
Copy link
Contributor

The gcd algorithm is somewhat expensive (requiring a loop and shifts or divisions), so an overflow check doesn't hurt performance much.

@eschnett
Copy link
Contributor Author

This is related to #15225 (but doesn't solve the issue).

u = abs(a >> za)
v = abs(b >> zb)
u = unsigned(abs(a >> za))
v = unsigned(abs(b >> zb))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would checked_abs give the same exception here as the general T<:Integer version?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

checked_abs is too strict here; if a == b == typemin(Int), then unsigned(abs(...)) is well-defined, but checked_abs would fail.

I just see that this code right-shifts before calling abs, and given that typemin(Int) has many trailing zeros, the code is probably fine.

No, they give different errors. checked_abs returns OverflowError, whereas type conversions return InexactError. (I find that weird, but that's how things are.) The generic gcd algorithm also might return DivideError instead.

@eschnett
Copy link
Contributor Author

The tests fail because of SubArray errors?

@eschnett
Copy link
Contributor Author

The 64-bit Appveyor tests timed out; there wasn't an actual failure reported.

@tkelman
Copy link
Contributor

tkelman commented Feb 25, 2016

And since Int32 and Int64 always go to different algorithms, it would be beneficial for test coverage to always test this for both integer sizes.

@eschnett
Copy link
Contributor Author

Now always throws OverflowError, tests for exactly this error, and tests both Int32 and Int64.

@tkelman
Copy link
Contributor

tkelman commented Feb 25, 2016

👍

@@ -54,7 +57,7 @@ function gcdx{T<:Integer}(a::T, b::T)
s0, s1 = s1, s0 - q*s1
t0, t1 = t1, t0 - q*t1
end
a < 0 ? (-a, -s0, -t0) : (a, s0, t0)
a < 0 ? (checked_neg(a), checked_neg(s0), checked_neg(t0)) : (a, s0, t0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are there tests for this?

@eschnett eschnett force-pushed the eschnett/gcd branch 2 times, most recently from 29a4cde to 4837b86 Compare February 26, 2016 12:46
@tkelman
Copy link
Contributor

tkelman commented Feb 26, 2016

could use a squash to get rid of the whitespace failures at intermediate commits

@eschnett eschnett force-pushed the eschnett/gcd branch 2 times, most recently from 643f7a9 to 3e8388b Compare February 27, 2016 15:31
The gcd and lcm algorithms are somewhat expensive (requiring a loop and shifts or divisions), so an overflow check doesn't hurt performance much.
@eschnett
Copy link
Contributor Author

Rebased and squashed, waiting for Appveyor and Travis

eschnett added a commit that referenced this pull request Feb 27, 2016
Check for overflow in gcd algorithm
@eschnett eschnett merged commit 1fcbc98 into JuliaLang:master Feb 27, 2016
@eschnett eschnett deleted the eschnett/gcd branch February 27, 2016 19:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants