/*
Copyright (C) 2009, 2015 William Hart
Copyright (C) 2014 Abhinav Baid
This file is part of FLINT.
FLINT is free software: you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License (LGPL) as published
by the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version. See .
*/
#include
#include "flint.h"
#include "ulong_extras.h"
#if (defined (__amd64__) || defined (__i386__) || defined (__i486__))
ulong
n_gcd(ulong x, ulong y)
{
register ulong s0, s1, f;
if (x == 0)
return y;
if (y == 0)
return x;
count_trailing_zeros(s0, x);
count_trailing_zeros(s1, y);
f = FLINT_MIN(s0, s1);
x >>= s0;
y >>= s1;
while (x != y)
{
if (x < y)
{
y -= x;
count_trailing_zeros(s1, y);
y >>= s1;
}
else
{
x -= y;
count_trailing_zeros(s0, x);
x >>= s0;
}
}
return x << f;
}
#else
ulong
n_gcd(ulong x, ulong y)
{
ulong d, v, quot, rem;
if (x >= y)
v = y;
else
{
v = x;
x = y;
}
/* x and y both have top bit set */
if ((slong) (x & v) < WORD(0))
{
d = x - v;
x = v;
v = d;
}
/* second value has second msb set */
while ((slong) (v << 1) < WORD(0))
{
d = x - v;
x = v;
if (d < v)
v = d; /* quot = 1 */
else if (d < (v << 1))
v = d - x; /* quot = 2 */
else
v = d - (x << 1); /* quot = 3 */
}
while (v)
{
/* overflow not possible due to top 2 bits of v not being set */
if (x < (v << 2)) /* avoid divisions when quotient < 4 */
{
d = x - v;
x = v;
if (d < v)
v = d; /* quot = 1 */
else if (d < (v << 1))
v = d - x; /* quot = 2 */
else
v = d - (x << 1); /* quot = 3 */
}
else
{
quot = x / v;
rem = x - v * quot;
x = v;
v = rem;
}
}
return x;
}
#endif