@@ -165,24 +165,34 @@ end
165
165
166
166
# return (gcd(a, b), x, y) such that ax+by == gcd(a, b)
167
167
"""
168
- gcdx(a, b)
168
+ gcdx(a, b... )
169
169
170
170
Computes the greatest common (positive) divisor of `a` and `b` and their Bézout
171
171
coefficients, i.e. the integer coefficients `u` and `v` that satisfy
172
- ``ua+vb = d = gcd(a, b)``. ``gcdx(a, b)`` returns ``(d, u, v)``.
172
+ ``u*a + v*b = d = gcd(a, b)``. ``gcdx(a, b)`` returns ``(d, u, v)``.
173
+
174
+ For more arguments than two, i.e., `gcdx(a, b, c, ...)` the Bézout coefficients are computed
175
+ recursively, returning a solution `(d, u, v, w, ...)` to
176
+ ``u*a + v*b + w*c + ... = d = gcd(a, b, c, ...)``.
173
177
174
178
The arguments may be integer and rational numbers.
175
179
176
180
!!! compat "Julia 1.4"
177
181
Rational arguments require Julia 1.4 or later.
178
182
183
+ !!! compat "Julia 1.11"
184
+ More or fewer arguments than two require Julia 1.11 or later.
185
+
179
186
# Examples
180
187
```jldoctest
181
188
julia> gcdx(12, 42)
182
189
(6, -3, 1)
183
190
184
191
julia> gcdx(240, 46)
185
192
(2, -9, 47)
193
+
194
+ julia> gcdx(15, 12, 20)
195
+ (1, 7, -7, -1)
186
196
```
187
197
188
198
!!! note
@@ -215,6 +225,18 @@ Base.@assume_effects :terminates_locally function gcdx(a::Integer, b::Integer)
215
225
end
216
226
gcdx (a:: Real , b:: Real ) = gcdx (promote (a,b)... )
217
227
gcdx (a:: T , b:: T ) where T<: Real = throw (MethodError (gcdx, (a,b)))
228
+ gcdx (a:: Real ) = (gcd (a), signbit (a) ? - one (a) : one (a))
229
+ function gcdx (a:: Real , b:: Real , cs:: Real... )
230
+ # a solution to the 3-arg `gcdx(a,b,c)` problem, `u*a + v*b + w*c = gcd(a,b,c)`, can be
231
+ # obtained recursively from the 2-arg problem, in three steps:
232
+ # 1. solve `gcdx(a, b)`: `i*a + j*b = d′ = gcd(a,b)` for `(i,j)`
233
+ # 2. solve `gcdx(d′, c)`: `x*gcd(a,b) + yc = gcd(gcd(a,b),c) = gcd(a,b,c)` for `(x,y)`
234
+ # 3. return `d = gcd(a,b,c)`, `u = i*x`, `v = j*x`, and `w = y`
235
+ # the N-arg solution proceeds similarly, by recursion
236
+ d, i, j = gcdx (a, b)
237
+ d′, x, ys... = gcdx (d, cs... )
238
+ return d′, i* x, j* x, ys...
239
+ end
218
240
219
241
# multiplicative inverse of n mod m, error if none
220
242
0 commit comments