[Edu-sig] the importance of divmod
Andrew Harrington
aharrin at luc.edu
Thu Jan 13 15:30:11 CET 2011
The Euclidean Algorithm only needs %. The*Extended* Euclidean Algorithm can
use divmod.
The code below is from my cryptography course last semester, where I wanted
to use polymorphism and have the xgcd also work for my polynomial classes
implementing finite fields. Hence I do not take absolute values that give
the official definition with integers. I kept the function docs for
integers, and they would get a lot shorter if you just threw in the absolute
value (or assume nonnegative inputs).
Andy
#! /usr/bin/python
def gcd(a,b):
"""Returns the gcd of its inputs times the sign of b if b is nonzero,
and times the sign of a if b is 0.
"""
while b != 0:
a,b = b, a % b
return a
def xgcd(a,b):
"""Extended GCD:
Returns (gcd, x, y) where gcd is the greatest common divisor of a and b
with the sign of b if b is nonzero, and with the sign of a if b is 0.
The numbers x,y are such that gcd = ax+by."""
prevx, x = 1, 0; prevy, y = 0, 1
while b:
q, r = divmod(a,b)
x, prevx = prevx - q*x, x
y, prevy = prevy - q*y, y
a, b = b, r
return a, prevx, prevy
# EXPLANATION:
# Mathematical analysis reveals that at each stage in the calculation
# the current remainder can be expressed in the form ax + by for some
# integers x, y. Moreover, the x-sequence and y-sequence are
# generated by the recursion (where q is the integer quotient of the
# current division):
#
# new x = prev x - q * x; new y = prev y - q * y
#
# and where the initial values are x = 0, prev x = 1, y = 1, prev y = 0.
# Moreover, upon termination the x and y sequences have gone one step
# too far, (as has the remainder), so return the previous x, y values.
def mgcd(a,b):
"""Returns (gcd, x, y, s, t) where
gcd is the greatest common divisor of a and b, with the sign of b
if b is nonzero, and with the sign of a if b is 0;
the numbers x,y, s, t are such that
gcd = xa+yb
0 = sa+tb
and abs(xt-ys) = 1
Otherwise put: the determinant of matrix (hence m in name)
x y
s t
has magnitude 1, and multiplied by column vector
a
b
is column vector
gcd
0
"""
prevx, x = 1, 0; prevy, y = 0, 1
while b:
q, r = divmod(a, b)
x, prevx = prevx - q*x, x
y, prevy = prevy - q*y, y
a, b = b, r
return a, prevx, prevy, x, y
## Change from xgcd:
## The coefficients for next iteration of xgcd that give 0 there,
## and are excluded on purpose, are just included here as the last two
## returned values, so only the end of the last line is differentfrom
xgcd.
On Thu, Jan 13, 2011 at 4:49 AM, Andre Alexander Bell <news at andre-bell.de>wrote:
> Hello Michel,
>
> On 13.01.2011 07:16, michel paul wrote:
> > But then, what if we want to think about it in purely mathematical
> > terms? If we agree that, for whatever reason, we cannot convert to
> > strings, how might we think about reversing digits using purely
> > functional reasoning, just % and recursion? That's how I initially
> > presented it, and then a kid suggested using divmod, and I was
> > delighted. It totally simplified the expression.
>
> You mean it simplified to something like this:
>
> n = 0
> d = 1234
> while d!=0:
> d,r = divmod(d,10)
> n = n*10 + r
>
> > I think it would be great to come up with a list of divmod math
> > problems. Anybody have some? I think developing fluency in divmod
> > sorts of reasoning would do a whole lot of good for understanding
> > ratio. Our current state of high school mathematical literacy that
> > equates a rational number with some bizarre decimal is horrible.
>
> I think that is an interesting point. Actually the Euclid Algorithm is
> another good divmod example.
> On the other hand you might as well argue that numbers in the given
> number system should have an access method to their digits like strings
> to their chars. In that case however, it would feel more natural if the
> indices are reverse. Then each index directly maps to the power of the
> base used. Example:
>
> i = 1234
> i[0] == 4
> i[1] == 3
> i[2] == 2
> i[3] == 1
>
> This would allow for
>
> a = 0
> a[3] = 1
> a == 1000
>
> Regards
>
>
> Andre
>
> _______________________________________________
> Edu-sig mailing list
> Edu-sig at python.org
> http://mail.python.org/mailman/listinfo/edu-sig
>
--
Dr. Andrew N. Harrington
Computer Science Department
Loyola University Chicago
512B Lewis Towers (office)
Snail mail to Lewis Towers 416
820 North Michigan Avenue
Chicago, Illinois 60611
http://www.cs.luc.edu/~anh
Phone: 312-915-7982
Fax: 312-915-7998
aharrin at luc.edu
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/edu-sig/attachments/20110113/2c9f499b/attachment.html>
More information about the Edu-sig
mailing list