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-bordeaux1.fr machine (x86_64 architecture), and agregate them in the final report:

The target is 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/gmp - gcdext.c (source / functions) Hit Total Coverage
Test: PARI/GP v2.8.0 lcov report (development 17953-c39f2e6) Lines: 76 76 100.0 %
Date: 2015-08-31 Functions: 2 2 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 81 90 90.0 %

           Branch data     Line data    Source code
       1                 :            : #line 2 "../src/kernel/gmp/gcdext.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. It is distributed in the hope that it will be useful, but WITHOUT
       9                 :            : ANY WARRANTY WHATSOEVER.
      10                 :            : 
      11                 :            : Check the License for details. You should have received a copy of it, along
      12                 :            : with the package; see the file 'COPYING'. If not, write to the Free Software
      13                 :            : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
      14                 :            : 
      15                 :            : /*==================================
      16                 :            :  * invmod(a,b,res)
      17                 :            :  *==================================
      18                 :            :  *    If a is invertible, return 1, and set res  = a^{ -1 }
      19                 :            :  *    Otherwise, return 0, and set res = gcd(a,b)
      20                 :            :  */
      21                 :            : int
      22                 :    5715385 : invmod(GEN a, GEN b, GEN *res)
      23                 :            : {
      24         [ -  + ]:    5715385 :   if (!signe(b)) { *res=absi(a); return 0; }
      25         [ +  + ]:    5715385 :   if (NLIMBS(b) < INVMOD_GMP_LIMIT)
      26                 :    4578962 :     return invmod_pari(a,b,res);
      27                 :            :   { /* General case: use gcdext(a+b, b) since mpn_gcdext require S1>=S2 */
      28                 :    1136423 :     pari_sp av = avma;
      29                 :            :     GEN  ca, cb, u, d;
      30                 :    1136423 :     long l, su, sa = signe(a), lb,lna;
      31                 :            :     mp_size_t lu;
      32                 :            :     GEN na;
      33         [ -  + ]:    1136423 :     if (!sa) { avma = av; *res = absi(b); return 0; }
      34         [ -  + ]:    1136423 :     if (signe(b) < 0) b = negi(b);
      35         [ +  + ]:    1136423 :     if (absi_cmp(a, b) < 0)
      36         [ +  + ]:    1135813 :       na = sa > 0? addii(a, b): subii(a, b);
      37                 :            :     else
      38                 :        610 :       na = a;
      39                 :            :     /* Copy serves two purposes:
      40                 :            :      * 1) mpn_gcdext destroys its input and needs an extra limb
      41                 :            :      * 2) allows us to use icopy instead of gerepile later. */
      42                 :    1136423 :     lb = lgefint(b); lna = lgefint(na);
      43                 :    1136423 :     ca = icopy_ef(na,lna+1);
      44                 :    1136423 :     cb = icopy_ef( b,lb+1);
      45                 :            :     /* must create u first else final icopy could fail. */
      46                 :    1136423 :     u = cgeti(lna+1);
      47                 :    1136423 :     d = cgeti(lna+1);
      48                 :            :     /* na >= b */
      49                 :    1136423 :     l = mpn_gcdext(LIMBS(d), LIMBS(u), &lu, LIMBS(ca), NLIMBS(ca), LIMBS(cb), NLIMBS(cb));
      50                 :    1136423 :     d[1] = evalsigne(1)|evallgefint(l+2);
      51         [ +  + ]:    1136423 :     if (!is_pm1(d)) {avma=av; *res=icopy(d); return 0;}
      52 [ +  - ][ +  + ]:    1136385 :     su = lu?((sa ^ lu) < 0)? -1: 1: 0;
      53                 :    1136385 :     u[1] = evalsigne(su) | evallgefint(labs(lu)+2);
      54         [ +  + ]:    1136385 :     if (su < 0) u = addii(u, b);
      55                 :    5694816 :     avma=av; *res=icopy(u); return 1;
      56                 :            :   }
      57                 :            : }
      58                 :            : 
      59                 :            : /*==================================
      60                 :            :  * bezout(a,b,pu,pv)
      61                 :            :  *==================================
      62                 :            :  *    Return g = gcd(a,b) >= 0, and assign GENs u,v through pointers pu,pv
      63                 :            :  *    such that g = u*a + v*b.
      64                 :            :  * Special cases:
      65                 :            :  *    a == b == 0 ==> pick u=1, v=0
      66                 :            :  *    a != 0 == b ==> keep v=0
      67                 :            :  *    a == 0 != b ==> keep u=0
      68                 :            :  *    |a| == |b| != 0 ==> keep u=0, set v=+-1
      69                 :            :  * Assignments through pu,pv will be suppressed when the corresponding
      70                 :            :  * pointer is NULL  (but the computations will happen nonetheless).
      71                 :            :  */
      72                 :            : 
      73                 :            : GEN
      74                 :   34373849 : bezout(GEN a, GEN b, GEN *pu, GEN *pv)
      75                 :            : {
      76                 :            :   long s, sa, sb;
      77                 :            :   ulong g;
      78                 :            :   ulong xu,xu1,xv,xv1;                /* Lehmer stage recurrence matrix */
      79                 :            : 
      80                 :   34373849 :   s = absi_cmp(a,b);
      81         [ +  + ]:   34373849 :   if (s < 0) { swap(a,b); pswap(pu,pv); }
      82                 :            :   /* now |a| >= |b| */
      83                 :            : 
      84                 :   34373849 :   sa = signe(a); sb = signe(b);
      85         [ +  + ]:   34373849 :   if (!sb)
      86                 :            :   {
      87         [ +  - ]:     482518 :     if (pv) *pv = gen_0;
      88   [ +  +  +  - ]:     482518 :     switch(sa)
      89                 :            :     {
      90         [ +  - ]:          4 :     case  0: if (pu) *pu = gen_0;  return gen_0;
      91         [ +  + ]:     481110 :     case  1: if (pu) *pu = gen_1;  return icopy(a);
      92         [ +  - ]:       1404 :     case -1: if (pu) *pu = gen_m1; return negi(a);
      93                 :            :     }
      94                 :            :   }
      95         [ +  + ]:   33891331 :   if (s == 0)                        /* |a| == |b| != 0 */
      96                 :            :   {
      97         [ +  + ]:    4930163 :     if (pu) *pu = gen_0;
      98         [ +  + ]:    4930163 :     if (sb > 0)
      99         [ +  + ]:    4384273 :     { if (pv) *pv = gen_1;  return icopy(b); }
     100                 :            :     else
     101         [ +  - ]:     545890 :     { if (pv) *pv = gen_m1; return negi(b); }
     102                 :            :   }
     103                 :            :   /* now |a| > |b| > 0 */
     104                 :            : 
     105         [ +  + ]:   28961168 :   if (lgefint(a) == 3)                /* single-word affair */
     106                 :            :   {
     107                 :   28556528 :     g = xxgcduu((ulong)a[2], (ulong)b[2], 0, &xu, &xu1, &xv, &xv1, &s);
     108         [ +  + ]:   28556528 :     sa = s > 0 ? sa : -sa;
     109         [ +  + ]:   28556528 :     sb = s > 0 ? -sb : sb;
     110         [ +  + ]:   28556528 :     if (pu)
     111                 :            :     {
     112         [ +  + ]:   13739786 :       if (xu == 0) *pu = gen_0; /* can happen when b divides a */
     113 [ +  + ][ +  + ]:    6366807 :       else if (xu == 1) *pu = sa < 0 ? gen_m1 : gen_1;
     114 [ +  + ][ +  + ]:    3630974 :       else if (xu == 2) *pu = sa < 0 ? gen_m2 : gen_2;
     115                 :            :       else
     116                 :            :       {
     117                 :    3365923 :         *pu = cgeti(3);
     118                 :    3365923 :         (*pu)[1] = evalsigne(sa)|evallgefint(3);
     119                 :    3365923 :         (*pu)[2] = xu;
     120                 :            :       }
     121                 :            :     }
     122         [ +  + ]:   28556528 :     if (pv)
     123                 :            :     {
     124 [ +  + ][ +  + ]:   25368417 :       if (xv == 1) *pv = sb < 0 ? gen_m1 : gen_1;
     125 [ +  + ][ +  + ]:   13758206 :       else if (xv == 2) *pv = sb < 0 ? gen_m2 : gen_2;
     126                 :            :       else
     127                 :            :       {
     128                 :   12738384 :         *pv = cgeti(3);
     129                 :   12738384 :         (*pv)[1] = evalsigne(sb)|evallgefint(3);
     130                 :   12738384 :         (*pv)[2] = xv;
     131                 :            :       }
     132                 :            :     }
     133         [ +  + ]:   28556528 :     if (g == 1) return gen_1;
     134         [ +  + ]:    7256313 :     else if (g == 2) return gen_2;
     135                 :    4870536 :     else return utoipos(g);
     136                 :            :   }
     137                 :            :   else
     138                 :            :   { /* general case */
     139                 :     404640 :     pari_sp av = avma;
     140                 :            :     /*Copy serves two purposes:
     141                 :            :      * 1) mpn_gcdext destroys its input and needs an extra limb
     142                 :            :      * 2) allows us to use icopy instead of gerepile later.
     143                 :            :      * NOTE: we must put u before d else the final icopy could fail. */
     144                 :     404640 :     GEN ca = icopy_ef(a,lgefint(a)+1);
     145                 :     404640 :     GEN cb = icopy_ef(b,lgefint(b)+1);
     146                 :     404640 :     GEN u = cgeti(lgefint(a)+1), v = NULL;
     147                 :     404640 :     GEN d = cgeti(lgefint(a)+1);
     148                 :            :     long su,l;
     149                 :            :     mp_size_t lu;
     150                 :     404640 :     l = mpn_gcdext(LIMBS(d), LIMBS(u), &lu, LIMBS(ca), NLIMBS(ca), LIMBS(cb), NLIMBS(cb));
     151         [ +  + ]:     404640 :     if (lu<=0)
     152                 :            :     {
     153         [ +  + ]:     341080 :       if (lu==0) su=0;
     154                 :      52054 :       else {su=-1;lu=-lu;}
     155                 :            :     }
     156                 :            :     else
     157                 :      63560 :       su=1;
     158         [ +  + ]:     404640 :     if (sa<0) su=-su;
     159                 :     404640 :     d[1] = evalsigne(1)|evallgefint(l+2);
     160                 :     404640 :     u[1] = evalsigne(su)|evallgefint(lu+2);
     161         [ +  + ]:     404640 :     if (pv) v=diviiexact(subii(d,mulii(u,a)),b);
     162                 :     404640 :     avma = av;
     163         [ +  + ]:     404640 :     if (pu) *pu=icopy(u);
     164         [ +  + ]:     404640 :     if (pv) *pv=icopy(v);
     165                 :   34373849 :     return icopy(d);
     166                 :            :   }
     167                 :            : }

Generated by: LCOV version 1.9