/* Copyright (C) 2009, 2015 William Hart 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" ulong n_gcdinv(ulong * s, ulong x, ulong y) { slong v1, v2, t2; ulong d, r, quot, rem; FLINT_ASSERT(y > x); v1 = 0; v2 = 1; r = x; x = y; /* y and x both have top bit set */ if ((slong) (x & r) < 0) { d = x - r; t2 = v2; x = r; v2 = v1 - v2; v1 = t2; r = d; } /* second value has second msb set */ while ((slong) (r << 1) < 0) { d = x - r; if (d < r) /* quot = 1 */ { t2 = v2; x = r; v2 = v1 - v2; v1 = t2; r = d; } else if (d < (r << 1)) /* quot = 2 */ { x = r; t2 = v2; v2 = v1 - (v2 << 1); v1 = t2; r = d - x; } else /* quot = 3 */ { x = r; t2 = v2; v2 = v1 - 3 * v2; v1 = t2; r = d - (x << 1); } } while (r) { /* overflow not possible due to top 2 bits of r not being set */ if (x < (r << 2)) /* if quot < 4 */ { d = x - r; if (d < r) /* quot = 1 */ { t2 = v2; x = r; v2 = v1 - v2; v1 = t2; r = d; } else if (d < (r << 1)) /* quot = 2 */ { x = r; t2 = v2; v2 = v1 - (v2 << 1); v1 = t2; r = d - x; } else /* quot = 3 */ { x = r; t2 = v2; v2 = v1 - 3 * v2; v1 = t2; r = d - (x << 1); } } else { quot = x / r; rem = x - r * quot; x = r; t2 = v2; v2 = v1 - quot * v2; v1 = t2; r = rem; } } if (v1 < WORD(0)) v1 += y; (*s) = v1; return x; }