Code coverage tests

This page documents the degree to which the PARI/GP source code is tested by our public test suite, distributed with the source distribution in directory src/test/. This is measured by the gcov utility; we then process gcov output using the lcov frond-end.

We test a few variants depending on Configure flags on the pari.math.u-bordeaux.fr machine (x86_64 architecture), and agregate them in the final report:

The target is to exceed 90% coverage for all mathematical modules (given that branches depending on DEBUGLEVEL or DEBUGMEM are not covered). This script is run to produce the results below.

LCOV - code coverage report
Current view: top level - kernel/none - gcd.c (source / functions) Hit Total Coverage
Test: PARI/GP v2.16.2 lcov report (development 29115-f22e516b23) Lines: 67 67 100.0 %
Date: 2024-03-28 08:06:56 Functions: 4 4 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #line 2 "../src/kernel/none/gcd.c"
       2             : /* Copyright (C) 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    23368041 : resiu(GEN y, ulong x)
      19             : {
      20    23368041 :   long i, ly = lgefint(y);
      21    23368041 :   ulong xi = get_Fl_red(x);
      22             :   LOCAL_HIREMAINDER;
      23             : 
      24    23368041 :   hiremainder = 0;
      25   242463678 :   for (i=2; i<ly; i++) (void)divll_pre(y[i],x,xi);
      26    23368041 :   return hiremainder;
      27             : }
      28             : 
      29             : /* Assume x>y>0, both of them odd. return x-y if x=y mod 4, x+y otherwise */
      30             : static void
      31   561868161 : gcd_plus_minus(GEN x, GEN y, GEN res)
      32             : {
      33   561868161 :   pari_sp av = avma;
      34   561868161 :   long lx = lgefint(x)-1;
      35   561868161 :   long ly = lgefint(y)-1, lt,m,i;
      36             :   GEN t;
      37             : 
      38   561868161 :   if ((x[lx]^y[ly]) & 3) /* x != y mod 4*/
      39   281555631 :     t = addiispec(x+2,y+2,lx-1,ly-1);
      40             :   else
      41   280312530 :     t = subiispec(x+2,y+2,lx-1,ly-1);
      42             : 
      43   562594632 :   lt = lgefint(t)-1; while (!t[lt]) lt--;
      44   561868161 :   m = vals(t[lt]); lt++;
      45   561868161 :   if (m == 0) /* 2^32 | t */
      46             :   {
      47       27309 :     for (i = 2; i < lt; i++) res[i] = t[i];
      48             :   }
      49   561856158 :   else if (t[2] >> m)
      50             :   {
      51   529261095 :     shift_right(res,t, 2,lt, 0,m);
      52             :   }
      53             :   else
      54             :   {
      55    32595063 :     lt--; t++;
      56    32595063 :     shift_right(res,t, 2,lt, t[1],m);
      57             :   }
      58   561868161 :   res[1] = evalsigne(1)|evallgefint(lt);
      59   561868161 :   set_avma(av);
      60   561868161 : }
      61             : 
      62             : /* uses modified right-shift binary algorithm now --GN 1998Jul23 */
      63             : static GEN
      64   314001207 : gcdii_basecase(GEN a, GEN b)
      65             : {
      66             :   long v, w;
      67             :   pari_sp av;
      68             :   GEN t, p1;
      69             : 
      70   314001207 :   switch (abscmpii(a,b))
      71             :   {
      72    52797942 :     case 0: return absi(a);
      73   112012860 :     case -1: swap(a,b);
      74             :   }
      75   261203265 :   if (!signe(b)) return absi(a);
      76             :   /* here |a|>|b|>0. Try single precision first */
      77   191000751 :   if (lgefint(a)==3)
      78   154246818 :     return igcduu((ulong)a[2], (ulong)b[2]);
      79    36753933 :   if (lgefint(b)==3)
      80             :   {
      81    23368041 :     ulong u = resiu(a,(ulong)b[2]);
      82    23368041 :     if (!u) return absi(b);
      83    14997756 :     return igcduu((ulong)b[2], u);
      84             :   }
      85             : 
      86             :   /* larger than gcd: "set_avma(av)" gerepile (erasing t) is valid */
      87    13385892 :   av = avma; (void)new_chunk(lgefint(b)); /* HACK */
      88    13385892 :   t = remii(a,b);
      89    13385892 :   if (!signe(t)) { set_avma(av); return absi(b); }
      90             : 
      91     9744438 :   a = b; b = t;
      92     9744438 :   v = vali(a); a = shifti(a,-v); setabssign(a);
      93     9744438 :   w = vali(b); b = shifti(b,-w); setabssign(b);
      94     9744438 :   if (w < v) v = w;
      95     9744438 :   switch(abscmpii(a,b))
      96             :   {
      97      169296 :     case  0: set_avma(av); a = shifti(a,v); return a;
      98     2663829 :     case -1: swap(a,b);
      99             :   }
     100     9575142 :   if (is_pm1(b)) { set_avma(av); return int2n(v); }
     101             : 
     102             :   /* we have three consecutive memory locations: a,b,t.
     103             :    * All computations are done in place */
     104             : 
     105             :   /* a and b are odd now, and a>b>1 */
     106     9512982 :   while (lgefint(a) > 3)
     107             :   {
     108             :     /* if a=b mod 4 set t=a-b, otherwise t=a+b, then strip powers of 2 */
     109             :     /* so that t <= (a+b)/4 < a/2 */
     110   561868161 :     gcd_plus_minus(a,b, t);
     111   561868161 :     if (is_pm1(t)) { set_avma(av); return int2n(v); }
     112   561622488 :     switch(abscmpii(t,b))
     113             :     {
     114   363076497 :       case -1: p1 = a; a = b; b = t; t = p1; break;
     115   197278896 :       case  1: swap(a,t); break;
     116     1267095 :       case  0: set_avma(av); b = shifti(b,v); return b;
     117             :     }
     118   569868375 :   }
     119             :   {
     120     8000214 :     long r[] = {evaltyp(t_INT)|_evallg(3), evalsigne(1)|evallgefint(3), 0};
     121     8000214 :     r[2] = (long) gcduodd((ulong)b[2], (ulong)a[2]);
     122     8000214 :     set_avma(av); return shifti(r,v);
     123             :   }
     124             : }
     125             : 
     126             : GEN
     127   314001207 : gcdii(GEN x, GEN y)
     128             : {
     129   314001207 :   pari_sp av=avma;
     130   317834331 :   while (lgefint(y)-2 >= GCD_HALFGCD_LIMIT)
     131             :   {
     132     3833124 :     GEN M = HGCD0(x,y);
     133     3833124 :     x = gel(M,2); y = gel(M,3);
     134     3833124 :     if (signe(y) && expi(y)<magic_threshold(x))
     135             :     {
     136     1735236 :       swap(x,y);
     137     1735236 :       y = remii(y,x);
     138             :     }
     139     3833124 :     if (gc_needed(av, 1)) gerepileall(av,2,&x,&y);
     140             :   }
     141   314001207 :   return gerepileuptoint(av, gcdii_basecase(x,y));
     142             : }

Generated by: LCOV version 1.14