Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

Testing latest pari + WASM + node.js... and it works?! Wow.

28495 views
License: GPL3
ubuntu2004
1
#line 2 "../src/kernel/gmp/gcd.c"
2
/* Copyright (C) 2000-2003 The PARI group.
3
4
This file is part of the PARI/GP package.
5
6
PARI/GP is free software; you can redistribute it and/or modify it under the
7
terms of the GNU General Public License as published by the Free Software
8
Foundation; either version 2 of the License, or (at your option) any later
9
version. It is distributed in the hope that it will be useful, but WITHOUT
10
ANY WARRANTY WHATSOEVER.
11
12
Check the License for details. You should have received a copy of it, along
13
with the package; see the file 'COPYING'. If not, write to the Free Software
14
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
15
16
/* assume y > x > 0. return y mod x */
17
static ulong
18
resiu(GEN y, ulong x)
19
{
20
return mpn_mod_1(LIMBS(y), NLIMBS(y), x);
21
}
22
23
GEN
24
gcdii(GEN a, GEN b)
25
{
26
long v, w;
27
pari_sp av;
28
GEN t;
29
30
switch (abscmpii(a,b))
31
{
32
case 0: return absi(a);
33
case -1: swap(a,b);
34
}
35
if (!signe(b)) return absi(a);
36
/* here |a|>|b|>0. Try single precision first */
37
if (lgefint(a)==3)
38
return igcduu((ulong)a[2], (ulong)b[2]);
39
if (lgefint(b)==3)
40
{
41
ulong u = resiu(a,(ulong)b[2]);
42
if (!u) return absi(b);
43
return igcduu((ulong)b[2], u);
44
}
45
/* larger than gcd: "set_avma(av)" gerepile (erasing t) is valid */
46
av = avma; (void)new_chunk(lgefint(b)+1); /* HACK */
47
t = remii(a,b);
48
if (!signe(t)) { set_avma(av); return absi(b); }
49
50
a = b; b = t;
51
v = vali(a); a = shifti(a,-v); setabssign(a);
52
w = vali(b); b = shifti(b,-w); setabssign(b);
53
if (w < v) v = w;
54
switch(abscmpii(a,b))
55
{
56
case 0: set_avma(av); a=shifti(a,v); return a;
57
case -1: swap(a,b);
58
}
59
if (is_pm1(b)) { set_avma(av); return int2n(v); }
60
{
61
/* general case */
62
/*This serve two purposes: 1) mpn_gcd destroy its input and need an extra
63
* limb 2) this allows us to use icopy instead of gerepile later. NOTE: we
64
* must put u before d else the final icopy could fail.
65
*/
66
GEN res= cgeti(lgefint(a)+1);
67
GEN ca = icopy_ef(a,lgefint(a)+1);
68
GEN cb = icopy_ef(b,lgefint(b)+1);
69
long l = mpn_gcd(LIMBS(res), LIMBS(ca), NLIMBS(ca), LIMBS(cb), NLIMBS(cb));
70
res[1] = evalsigne(1)|evallgefint(l+2);
71
set_avma(av);
72
return shifti(res,v);
73
}
74
}
75
76