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

inconsistent sign of gcd #4810

Closed
stevengj opened this issue Nov 14, 2013 · 13 comments
Closed

inconsistent sign of gcd #4810

stevengj opened this issue Nov 14, 2013 · 13 comments
Labels
bug Indicates an unexpected problem or unintended behavior needs decision A decision on this change is needed
Milestone

Comments

@stevengj
Copy link
Member

gcd(-7, 37) returns -1, but gcd(big(-7), big(37)) (via GMP) returns 1.

In the gcd(a,b) implementation in intfuncs.jl, there is an explicit rule that the gcd return value has the same sign as a. If there is a good reason for this rule(??), we should modify the BigInt call to implement the same rule (since GMP seems to always return a positive result).

@JeffBezanson
Copy link
Member

It makes more sense to me for a gcd to be positive.

@stevengj
Copy link
Member Author

For variety, Python's fractions.gcd function gives gcd(a,b) the same sign as b.

@johnmyleswhite
Copy link
Member

I'd also prefer having gcd always return a positive value.

@stevengj
Copy link
Member Author

If the gcd is the greatest common divisor, and the divisors are defined as positive integers, then it seems like the gcd should always be positive.

@stevengj
Copy link
Member Author

Note that the same inconsistency occurs for lcm(a,b): GMP always returns a positive quantity, but our return value depends upon the signs of the arguments.

@StefanKarpinski
Copy link
Member

If we make gcd and lcm always positive, then the Rational implementation will have to be modified. IIRC, having this return a value with the same sign as the first argument (which is the only one that's guaranteed to exist) makes certain algorithms much easier to write.

@StefanKarpinski
Copy link
Member

I just checked that this means that construction of Rational{BigInt} values was broken:

julia> big(2)//big(-3)
2//-3

That should produce -2//3 instead.

@stevengj
Copy link
Member Author

Since gcd is only used in two places in rational.jl, and the sign only matters in one place, it seems reasonable to just modify rational.jl to handle a positive gcd.

@StefanKarpinski
Copy link
Member

Agreed. Just pointing out the issue.

@StefanKarpinski
Copy link
Member

If anything, the fact that the difference between built-in integers and bigints was causing broken rational behavior demonstrates the fragility of relying on this rather subtle and non-obvious behavior. FWIW, the gcd and Rational type is some of the first Julia code we ever wrote – 70efab8.

@JeffBezanson
Copy link
Member

Wow, I forgot about the conversion keyword. What were we thinking? :)

@stevengj
Copy link
Member Author

By the way, the old behavior was also causing a bug in invmod, since that function was checking gcd(a,b) == 1 to decide whether the inverse exists. In my mind, checking gcd(a,b) == 1 should be a correct way to determine whether two numbers are coprime, and any other behavior is likely to be bug-inducing.

@StefanKarpinski
Copy link
Member

Wow, I forgot about the conversion keyword. What were we thinking? :)

What we were thinking was "crap, how the hell are we going to deal with numeric conversion and promotion?" – because we hadn't yet figured out how to do all of it with dispatch. The conversion keyword was a terrible idea.

fp4code added a commit to MiNaO/julia that referenced this issue Apr 5, 2016
fp4code added a commit to MiNaO/julia that referenced this issue Apr 5, 2016
…tions-1

Update �gcd and �lcm doc. (Cf. issue JuliaLang#4810)
vtjnash pushed a commit that referenced this issue Apr 6, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Indicates an unexpected problem or unintended behavior needs decision A decision on this change is needed
Projects
None yet
Development

No branches or pull requests

4 participants