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 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 19230-c71492b) Lines: 76 76 100.0 %
Date: 2016-07-30 07:10:28 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          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     5440325 : invmod(GEN a, GEN b, GEN *res)
      23             : {
      24     5440325 :   if (!signe(b)) { *res=absi(a); return 0; }
      25     5440325 :   if (NLIMBS(b) < INVMOD_GMP_LIMIT)
      26     4308239 :     return invmod_pari(a,b,res);
      27             :   { /* General case: use gcdext(a+b, b) since mpn_gcdext require S1>=S2 */
      28     1132086 :     pari_sp av = avma;
      29             :     GEN  ca, cb, u, d;
      30     1132086 :     long l, su, sa = signe(a), lb,lna;
      31             :     mp_size_t lu;
      32             :     GEN na;
      33     1132086 :     if (!sa) { avma = av; *res = absi(b); return 0; }
      34     1132082 :     if (signe(b) < 0) b = negi(b);
      35     1132082 :     if (absi_cmp(a, b) < 0)
      36     1131470 :       na = sa > 0? addii(a, b): subii(a, b);
      37             :     else
      38         612 :       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     1132082 :     lb = lgefint(b); lna = lgefint(na);
      43     1132082 :     ca = icopy_ef(na,lna+1);
      44     1132082 :     cb = icopy_ef( b,lb+1);
      45             :     /* must create u first else final icopy could fail. */
      46     1132082 :     u = cgeti(lna+1);
      47     1132081 :     d = cgeti(lna+1);
      48             :     /* na >= b */
      49     1132079 :     l = mpn_gcdext(LIMBS(d), LIMBS(u), &lu, LIMBS(ca), NLIMBS(ca), LIMBS(cb), NLIMBS(cb));
      50     1132082 :     d[1] = evalsigne(1)|evallgefint(l+2);
      51     1132082 :     if (!is_pm1(d)) {avma=av; *res=icopy(d); return 0;}
      52     1132044 :     su = lu?((sa ^ lu) < 0)? -1: 1: 0;
      53     1132044 :     u[1] = evalsigne(su) | evallgefint(labs(lu)+2);
      54     1132044 :     if (su < 0) u = addii(u, b);
      55     1132044 :     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    89830740 : 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    89830740 :   s = absi_cmp(a,b);
      81    89830741 :   if (s < 0) { swap(a,b); pswap(pu,pv); }
      82             :   /* now |a| >= |b| */
      83             : 
      84    89830741 :   sa = signe(a); sb = signe(b);
      85    89830741 :   if (!sb)
      86             :   {
      87     1971408 :     if (pv) *pv = gen_0;
      88     1971408 :     switch(sa)
      89             :     {
      90           4 :     case  0: if (pu) *pu = gen_0;  return gen_0;
      91     1969196 :     case  1: if (pu) *pu = gen_1;  return icopy(a);
      92        2208 :     case -1: if (pu) *pu = gen_m1; return negi(a);
      93             :     }
      94             :   }
      95    87859333 :   if (s == 0)                        /* |a| == |b| != 0 */
      96             :   {
      97     9415601 :     if (pu) *pu = gen_0;
      98     9415601 :     if (sb > 0)
      99     8880289 :     { if (pv) *pv = gen_1;  return icopy(b); }
     100             :     else
     101      535312 :     { if (pv) *pv = gen_m1; return negi(b); }
     102             :   }
     103             :   /* now |a| > |b| > 0 */
     104             : 
     105    78443732 :   if (lgefint(a) == 3)                /* single-word affair */
     106             :   {
     107    78036266 :     g = xxgcduu((ulong)a[2], (ulong)b[2], 0, &xu, &xu1, &xv, &xv1, &s);
     108    78036269 :     sa = s > 0 ? sa : -sa;
     109    78036269 :     sb = s > 0 ? -sb : sb;
     110    78036269 :     if (pu)
     111             :     {
     112    25522438 :       if (xu == 0) *pu = gen_0; /* can happen when b divides a */
     113    13096708 :       else if (xu == 1) *pu = sa < 0 ? gen_m1 : gen_1;
     114     5270279 :       else if (xu == 2) *pu = sa < 0 ? gen_m2 : gen_2;
     115             :       else
     116             :       {
     117     4555033 :         *pu = cgeti(3);
     118     4555033 :         (*pu)[1] = evalsigne(sa)|evallgefint(3);
     119     4555033 :         (*pu)[2] = xu;
     120             :       }
     121             :     }
     122    78036269 :     if (pv)
     123             :     {
     124    70897819 :       if (xv == 1) *pv = sb < 0 ? gen_m1 : gen_1;
     125    40045681 :       else if (xv == 2) *pv = sb < 0 ? gen_m2 : gen_2;
     126             :       else
     127             :       {
     128    35581821 :         *pv = cgeti(3);
     129    35581821 :         (*pv)[1] = evalsigne(sb)|evallgefint(3);
     130    35581821 :         (*pv)[2] = xv;
     131             :       }
     132             :     }
     133    78036269 :     if (g == 1) return gen_1;
     134    19765483 :     else if (g == 2) return gen_2;
     135    12382008 :     else return utoipos(g);
     136             :   }
     137             :   else
     138             :   { /* general case */
     139      407466 :     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      407466 :     GEN ca = icopy_ef(a,lgefint(a)+1);
     145      407466 :     GEN cb = icopy_ef(b,lgefint(b)+1);
     146      407466 :     GEN u = cgeti(lgefint(a)+1), v = NULL;
     147      407466 :     GEN d = cgeti(lgefint(a)+1);
     148             :     long su,l;
     149             :     mp_size_t lu;
     150      407466 :     l = mpn_gcdext(LIMBS(d), LIMBS(u), &lu, LIMBS(ca), NLIMBS(ca), LIMBS(cb), NLIMBS(cb));
     151      407466 :     if (lu<=0)
     152             :     {
     153      342721 :       if (lu==0) su=0;
     154       53857 :       else {su=-1;lu=-lu;}
     155             :     }
     156             :     else
     157       64745 :       su=1;
     158      407466 :     if (sa<0) su=-su;
     159      407466 :     d[1] = evalsigne(1)|evallgefint(l+2);
     160      407466 :     u[1] = evalsigne(su)|evallgefint(lu+2);
     161      407466 :     if (pv) v=diviiexact(subii(d,mulii(u,a)),b);
     162      407466 :     avma = av;
     163      407466 :     if (pu) *pu=icopy(u);
     164      407466 :     if (pv) *pv=icopy(v);
     165      407466 :     return icopy(d);
     166             :   }
     167             : }

Generated by: LCOV version 1.11