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 16827-3d78da8) Lines: 76 76 100.0 %
Date: 2014-09-29 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                 :    2696373 : invmod(GEN a, GEN b, GEN *res)
      23                 :            : {
      24         [ -  + ]:    2696373 :   if (!signe(b)) { *res=absi(a); return 0; }
      25         [ +  + ]:    2696373 :   if (NLIMBS(b) < INVMOD_GMP_LIMIT)
      26                 :    1926792 :     return invmod_pari(a,b,res);
      27                 :            :   { /* General case: use gcdext(a+b, b) since mpn_gcdext require S1>=S2 */
      28                 :     769581 :     pari_sp av = avma;
      29                 :            :     GEN  ca, cb, u, d;
      30                 :     769581 :     long lu, l, su, sa = signe(a), lb,lna;
      31                 :            :     GEN na;
      32         [ -  + ]:     769581 :     if (!sa) { avma = av; *res = absi(b); return 0; }
      33         [ -  + ]:     769581 :     if (signe(b) < 0) b = negi(b);
      34         [ +  + ]:     769581 :     if (absi_cmp(a, b) < 0)
      35         [ +  + ]:     768971 :       na = sa > 0? addii(a, b): subii(a, b);
      36                 :            :     else
      37                 :        610 :       na = a;
      38                 :            :     /* Copy serves two purposes:
      39                 :            :      * 1) mpn_gcdext destroys its input and needs an extra limb
      40                 :            :      * 2) allows us to use icopy instead of gerepile later. */
      41                 :     769581 :     lb = lgefint(b); lna = lgefint(na);
      42                 :     769581 :     ca = icopy_ef(na,lna+1);
      43                 :     769581 :     cb = icopy_ef( b,lb+1);
      44                 :            :     /* must create u first else final icopy could fail. */
      45                 :     769581 :     u = cgeti(lna+1);
      46                 :     769581 :     d = cgeti(lna+1);
      47                 :            :     /* na >= b */
      48                 :     769581 :     l = mpn_gcdext(LIMBS(d), LIMBS(u), &lu, LIMBS(ca), NLIMBS(ca), LIMBS(cb), NLIMBS(cb));
      49                 :     769581 :     d[1] = evalsigne(1)|evallgefint(l+2);
      50         [ +  + ]:     769581 :     if (!is_pm1(d)) {avma=av; *res=icopy(d); return 0;}
      51 [ +  - ][ +  + ]:     769549 :     su = lu?((sa ^ lu) < 0)? -1: 1: 0;
      52                 :     769549 :     u[1] = evalsigne(su) | evallgefint(labs(lu)+2);
      53         [ +  + ]:     769549 :     if (su < 0) u = addii(u, b);
      54                 :    2696373 :     avma=av; *res=icopy(u); return 1;
      55                 :            :   }
      56                 :            : }
      57                 :            : 
      58                 :            : /*==================================
      59                 :            :  * bezout(a,b,pu,pv)
      60                 :            :  *==================================
      61                 :            :  *    Return g = gcd(a,b) >= 0, and assign GENs u,v through pointers pu,pv
      62                 :            :  *    such that g = u*a + v*b.
      63                 :            :  * Special cases:
      64                 :            :  *    a == b == 0 ==> pick u=1, v=0
      65                 :            :  *    a != 0 == b ==> keep v=0
      66                 :            :  *    a == 0 != b ==> keep u=0
      67                 :            :  *    |a| == |b| != 0 ==> keep u=0, set v=+-1
      68                 :            :  * Assignments through pu,pv will be suppressed when the corresponding
      69                 :            :  * pointer is NULL  (but the computations will happen nonetheless).
      70                 :            :  */
      71                 :            : 
      72                 :            : GEN
      73                 :   17787335 : bezout(GEN a, GEN b, GEN *pu, GEN *pv)
      74                 :            : {
      75                 :            :   long s, sa, sb;
      76                 :            :   ulong g;
      77                 :            :   ulong xu,xu1,xv,xv1;                /* Lehmer stage recurrence matrix */
      78                 :            : 
      79                 :   17787335 :   s = absi_cmp(a,b);
      80         [ +  + ]:   17787335 :   if (s < 0) { swap(a,b); pswap(pu,pv); }
      81                 :            :   /* now |a| >= |b| */
      82                 :            : 
      83                 :   17787335 :   sa = signe(a); sb = signe(b);
      84         [ +  + ]:   17787335 :   if (!sb)
      85                 :            :   {
      86         [ +  - ]:     119371 :     if (pv) *pv = gen_0;
      87   [ +  +  +  - ]:     119371 :     switch(sa)
      88                 :            :     {
      89         [ +  - ]:          4 :     case  0: if (pu) *pu = gen_0;  return gen_0;
      90         [ +  + ]:     118351 :     case  1: if (pu) *pu = gen_1;  return icopy(a);
      91         [ +  - ]:       1016 :     case -1: if (pu) *pu = gen_m1; return negi(a);
      92                 :            :     }
      93                 :            :   }
      94         [ +  + ]:   17667964 :   if (s == 0)                        /* |a| == |b| != 0 */
      95                 :            :   {
      96         [ +  + ]:    3771767 :     if (pu) *pu = gen_0;
      97         [ +  + ]:    3771767 :     if (sb > 0)
      98         [ +  + ]:    3298147 :     { if (pv) *pv = gen_1;  return icopy(b); }
      99                 :            :     else
     100         [ +  - ]:     473620 :     { if (pv) *pv = gen_m1; return negi(b); }
     101                 :            :   }
     102                 :            :   /* now |a| > |b| > 0 */
     103                 :            : 
     104         [ +  + ]:   13896197 :   if (lgefint(a) == 3)                /* single-word affair */
     105                 :            :   {
     106                 :   13614846 :     g = xxgcduu((ulong)a[2], (ulong)b[2], 0, &xu, &xu1, &xv, &xv1, &s);
     107         [ +  + ]:   13614846 :     sa = s > 0 ? sa : -sa;
     108         [ +  + ]:   13614846 :     sb = s > 0 ? -sb : sb;
     109         [ +  + ]:   13614846 :     if (pu)
     110                 :            :     {
     111         [ +  + ]:    9279945 :       if (xu == 0) *pu = gen_0; /* can happen when b divides a */
     112 [ +  + ][ +  + ]:    3944192 :       else if (xu == 1) *pu = sa < 0 ? gen_m1 : gen_1;
     113 [ +  + ][ +  + ]:    2744705 :       else if (xu == 2) *pu = sa < 0 ? gen_m2 : gen_2;
     114                 :            :       else
     115                 :            :       {
     116                 :    2610035 :         *pu = cgeti(3);
     117                 :    2610035 :         (*pu)[1] = evalsigne(sa)|evallgefint(3);
     118                 :    2610035 :         (*pu)[2] = xu;
     119                 :            :       }
     120                 :            :     }
     121         [ +  + ]:   13614846 :     if (pv)
     122                 :            :     {
     123 [ +  + ][ +  + ]:   11460235 :       if (xv == 1) *pv = sb < 0 ? gen_m1 : gen_1;
     124 [ +  + ][ +  + ]:    5536720 :       else if (xv == 2) *pv = sb < 0 ? gen_m2 : gen_2;
     125                 :            :       else
     126                 :            :       {
     127                 :    5432518 :         *pv = cgeti(3);
     128                 :    5432518 :         (*pv)[1] = evalsigne(sb)|evallgefint(3);
     129                 :    5432518 :         (*pv)[2] = xv;
     130                 :            :       }
     131                 :            :     }
     132         [ +  + ]:   13614846 :     if (g == 1) return gen_1;
     133         [ +  + ]:    3736407 :     else if (g == 2) return gen_2;
     134                 :    2685367 :     else return utoipos(g);
     135                 :            :   }
     136                 :            :   else
     137                 :            :   { /* general case */
     138                 :     281351 :     pari_sp av = avma;
     139                 :            :     /*Copy serves two purposes:
     140                 :            :      * 1) mpn_gcdext destroys its input and needs an extra limb
     141                 :            :      * 2) allows us to use icopy instead of gerepile later.
     142                 :            :      * NOTE: we must put u before d else the final icopy could fail. */
     143                 :     281351 :     GEN ca = icopy_ef(a,lgefint(a)+1);
     144                 :     281351 :     GEN cb = icopy_ef(b,lgefint(b)+1);
     145                 :     281351 :     GEN u = cgeti(lgefint(a)+1), v = NULL;
     146                 :     281351 :     GEN d = cgeti(lgefint(a)+1);
     147                 :            :     long su,l,lu;
     148                 :     281351 :     l = mpn_gcdext(LIMBS(d), LIMBS(u), &lu, LIMBS(ca), NLIMBS(ca), LIMBS(cb), NLIMBS(cb));
     149         [ +  + ]:     281351 :     if (lu<=0)
     150                 :            :     {
     151         [ +  + ]:     249837 :       if (lu==0) su=0;
     152                 :      24994 :       else {su=-1;lu=-lu;}
     153                 :            :     }
     154                 :            :     else
     155                 :      31514 :       su=1;
     156         [ +  + ]:     281351 :     if (sa<0) su=-su;
     157                 :     281351 :     d[1] = evalsigne(1)|evallgefint(l+2);
     158                 :     281351 :     u[1] = evalsigne(su)|evallgefint(lu+2);
     159         [ +  + ]:     281351 :     if (pv) v=diviiexact(subii(d,mulii(u,a)),b);
     160                 :     281351 :     avma = av;
     161         [ +  + ]:     281351 :     if (pu) *pu=icopy(u);
     162         [ +  + ]:     281351 :     if (pv) *pv=icopy(v);
     163                 :   17787335 :     return icopy(d);
     164                 :            :   }
     165                 :            : }

Generated by: LCOV version 1.9