summaryrefslogtreecommitdiff
path: root/mpz/lcm.c
diff options
context:
space:
mode:
authorKevin Ryde <user42@zip.com.au>2001-04-30 00:58:01 +0200
committerKevin Ryde <user42@zip.com.au>2001-04-30 00:58:01 +0200
commita1814d70bfa98dfba574026509c4c4397627d564 (patch)
treeb1468d5bfada75f519bf6dac8268c8739bd16a9c /mpz/lcm.c
parent2c32e72be340d9cfe6d9f543dd7ddfd63da020d2 (diff)
downloadgmp-a1814d70bfa98dfba574026509c4c4397627d564.tar.gz
* mpz/lcm.c: Add one limb special case.
Diffstat (limited to 'mpz/lcm.c')
-rw-r--r--mpz/lcm.c38
1 files changed, 34 insertions, 4 deletions
diff --git a/mpz/lcm.c b/mpz/lcm.c
index 9539b633e..b1ae973c1 100644
--- a/mpz/lcm.c
+++ b/mpz/lcm.c
@@ -1,4 +1,4 @@
-/* mpz/lcm.c: Calculate the least common multiple of two integers.
+/* mpz_lcm -- mpz/mpz least common multiple.
Copyright 1996, 2000, 2001 Free Software Foundation, Inc.
@@ -34,15 +34,45 @@ mpz_lcm (mpz_ptr r, mpz_srcptr u, mpz_srcptr v)
TMP_MARK (marker);
- usize = ABS (SIZ (u));
- vsize = ABS (SIZ (v));
-
+ usize = SIZ (u);
+ vsize = SIZ (v);
if (usize == 0 || vsize == 0)
{
SIZ (r) = 0;
return;
}
+ usize = ABS (usize);
+ vsize = ABS (vsize);
+
+ if (vsize == 1)
+ {
+ mp_limb_t vl, gl, c;
+ mp_srcptr up;
+ mp_ptr rp;
+ one:
+ MPZ_REALLOC (r, usize+1);
+
+ up = PTR(u);
+ vl = PTR(v)[0];
+ gl = mpn_gcd_1 (up, usize, vl);
+ vl /= gl;
+
+ rp = PTR(r);
+ c = mpn_mul_1 (rp, up, usize, vl);
+ rp[usize] = c;
+ usize += (c != 0);
+ SIZ(r) = usize;
+ return;
+ }
+
+ if (usize == 1)
+ {
+ usize = vsize;
+ MPZ_SRCPTR_SWAP (u, v);
+ goto one;
+ }
+
size = MAX (usize, vsize);
MPZ_TMP_INIT (g, size);