summaryrefslogtreecommitdiff
path: root/src/libbiguint/bu_gcd.c
blob: d6c57916ad77c09d741395d18edbcff578a3fcb0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/* ISC license. */

#include <skalibs/uint32.h>
#include <skalibs/biguint.h>

int bu_gcd (uint32 *r, unsigned int rn, uint32 const *a, unsigned int an, uint32 const *b, unsigned int bn)
{
  if (bu_cmp(a, an, b, bn) < 0)
  {
    register uint32 const *t = a ;
    register unsigned int tn = an ;
    a = b ; an = bn ;
    b = t ; bn = tn ;
  }
  {
    uint32 trash[an] ;
    uint32 aa[an] ;
    uint32 bb[an] ;
    uint32 *aaa = aa, *bbb = bb ;
    bu_copy_internal(aa, a, an) ;
    bu_copy_internal(bb, b, bn) ;
    bu_zero(bb+bn, an-bn) ;

    while (bu_len(bbb, an))
    {
      register uint32 *ttt = aaa ;
      bu_div_internal(aaa, an, bbb, an, trash, an) ;
      aaa = bbb ;
      bbb = ttt ;
    }
    return bu_copy(r, rn, aaa, an) ;
  }
}