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/none - level1.h (source / functions) Hit Total Coverage
Test: PARI/GP v2.12.0 lcov report (development 22872-edcf83abb) Lines: 571 729 78.3 %
Date: 2018-07-20 05:36:03 Functions: 205 269 76.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #line 2 "../src/kernel/none/level1.h"
       2             : /* Copyright (C) 2000  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             : /* This file defines "level 1" kernel functions.
      16             :  * These functions can be inline; they are also defined externally in
      17             :  * mpinl.c, which includes this file and never needs to be changed */
      18             : 
      19             : INLINE long
      20 43464091267 : evallg(long x)
      21             : {
      22 43464091267 :   if (x & ~LGBITS) pari_err_OVERFLOW("lg()");
      23 43465586519 :   return _evallg(x);
      24             : }
      25             : INLINE long
      26    16459684 : evalvalp(long x)
      27             : {
      28    16459684 :   long v = _evalvalp(x);
      29    16459684 :   if (v & ~VALPBITS) pari_err_OVERFLOW("valp()");
      30    16459681 :   return v;
      31             : }
      32             : INLINE long
      33  6021061325 : evalexpo(long x)
      34             : {
      35  6021061325 :   long v = _evalexpo(x);
      36  6021061325 :   if (v & ~EXPOBITS) pari_err_OVERFLOW("expo()");
      37  6021061325 :   return v;
      38             : }
      39             : INLINE long
      40     1875679 : evalprecp(long x)
      41             : {
      42     1875679 :   long v = _evalprecp(x);
      43     1875679 :   if (x & ~((1UL<<(BITS_IN_LONG-VALPnumBITS))-1)) pari_err_OVERFLOW("precp()");
      44     1875679 :   return v;
      45             : }
      46             : 
      47             : INLINE int
      48   146788234 : varncmp(long x, long y)
      49             : {
      50   146788234 :   if (varpriority[x] < varpriority[y]) return  1;
      51   114104660 :   if (varpriority[x] > varpriority[y]) return -1;
      52    61756100 :   return 0;
      53             : }
      54             : INLINE long
      55           0 : varnmin(long x, long y)
      56           0 : { return (varpriority[x] <= varpriority[y])? x: y; }
      57             : INLINE long
      58         196 : varnmax(long x, long y)
      59         196 : { return (varpriority[x] >= varpriority[y])? x: y; }
      60             : 
      61             : /* Inhibit some area gerepile-wise: declare it to be a non recursive
      62             :  * type, of length l. Thus gerepile won't inspect the zone, just copy it.
      63             :  * For the following situation:
      64             :  *   z = cgetg(t,a); av = avma; garbage(); ltop = avma;
      65             :  *   for (i=1; i<HUGE; i++) gel(z,i) = blah();
      66             :  *   stackdummy(av,ltop);
      67             :  * loses (av-ltop) words but save a costly gerepile. */
      68             : INLINE void
      69  1761489910 : stackdummy(pari_sp av, pari_sp ltop) {
      70  1761489910 :   long l = ((GEN)av) - ((GEN)ltop);
      71  1761489910 :   if (l > 0) {
      72   609665222 :     GEN z = (GEN)ltop;
      73   609665222 :     z[0] = evaltyp(t_VECSMALL) | evallg(l);
      74             : #ifdef DEBUG
      75             :     { long i; for (i = 1; i < l; i++) z[i] = 0; }
      76             : #endif
      77             :   }
      78  1761957167 : }
      79             : INLINE void
      80    61132865 : fixlg(GEN x, long ly) {
      81    61132865 :   long lx = lg(x), l = lx - ly;
      82    61132865 :   if (l > 0)
      83             :   { /* stackdummy(x+lx, x+ly) */
      84    42931327 :     GEN z = x + ly;
      85    42931327 :     z[0] = evaltyp(t_VECSMALL) | evallg(l);
      86    42931319 :     setlg(x, ly);
      87             : #ifdef DEBUG
      88             :     { long i; for (i = 1; i < l; i++) z[i] = 0; }
      89             : #endif
      90             :   }
      91    61132821 : }
      92             : /* update lg(z) before affrr(y, z)  [ to cater for precision loss ]*/
      93             : INLINE void
      94    18202924 : affrr_fixlg(GEN y, GEN z) { fixlg(z, lg(y)); affrr(y, z); }
      95             : 
      96             : /*******************************************************************/
      97             : /*                                                                 */
      98             : /*                       ALLOCATE ON STACK                         */
      99             : /*                                                                 */
     100             : /*******************************************************************/
     101             : INLINE GEN
     102 40941611591 : new_chunk(size_t x) /* x is a number of longs */
     103             : {
     104 40941611591 :   GEN z = ((GEN) avma) - x;
     105             :   CHECK_CTRLC
     106 40941611591 :   if (x > (avma-pari_mainstack->bot) / sizeof(long))
     107           7 :     new_chunk_resize(x);
     108 40947031028 :   avma = (pari_sp)z;
     109             : #ifdef MEMSTEP
     110             :   if (DEBUGMEM>1 && pari_mainstack->memused != DISABLE_MEMUSED) {
     111             :     long d = (long)pari_mainstack->memused - (long)z;
     112             :     if (labs(d) > 4*MEMSTEP)
     113             :     {
     114             :       pari_mainstack->memused = (pari_sp)z;
     115             :       err_printf("...%4.0lf Mbytes used\n",
     116             :                 (pari_mainstack->top-pari_mainstack->memused)/1048576.);
     117             :     }
     118             :   }
     119             : #endif
     120 40947031028 :   return z;
     121             : }
     122             : 
     123             : INLINE char *
     124     4143307 : stack_malloc(size_t N)
     125             : {
     126     4143307 :   long n = nchar2nlong(N);
     127     4143307 :   return (char*)new_chunk(n);
     128             : }
     129             : 
     130             : INLINE char *
     131     1198138 : stack_malloc_align(size_t N, long k)
     132             : {
     133     1198138 :   ulong d = ((ulong)avma) % k;
     134     1198138 :   if (d) (void)new_chunk(d/sizeof(long));
     135     1198138 :   return (char*) new_chunk(nchar2nlong(N));
     136             : }
     137             : 
     138             : INLINE char *
     139       41534 : stack_calloc(size_t N)
     140             : {
     141       41534 :   char *p = stack_malloc(N);
     142       41534 :   memset(p, 0, N); return p;
     143             : }
     144             : 
     145             : /* cgetg(lg(x), typ(x)), set *lx. Implicit unsetisclone() */
     146             : INLINE GEN
     147   456543805 : cgetg_copy(GEN x, long *plx) {
     148             :   GEN y;
     149   456543805 :   *plx = lg(x); y = new_chunk((size_t)*plx);
     150   456542042 :   y[0] = x[0] & (TYPBITS|LGBITS); return y;
     151             : }
     152             : INLINE GEN
     153      146256 : cgetg_block(long x, long y)
     154             : {
     155      146256 :   GEN z = newblock((size_t)x);
     156      146312 :   z[0] = CLONEBIT | evaltyp(y) | evallg(x);
     157      146251 :   return z;
     158             : }
     159             : INLINE GEN
     160  5575614277 : cgetg(long x, long y)
     161             : {
     162  5575614277 :   GEN z = new_chunk((size_t)x);
     163  5575007864 :   z[0] = evaltyp(y) | evallg(x);
     164  5574073403 :   return z;
     165             : }
     166             : INLINE GEN
     167 13692624257 : cgeti(long x)
     168             : {
     169 13692624257 :   GEN z = new_chunk((size_t)x);
     170 13682522270 :   z[0] = evaltyp(t_INT) | evallg(x);
     171 13674064051 :   return z;
     172             : }
     173             : INLINE GEN
     174  8441470682 : cgetipos(long x)
     175             : {
     176  8441470682 :   GEN z = cgeti(x);
     177  8441299393 :   z[1] = evalsigne(1) | evallgefint(x);
     178  8441299393 :   return z;
     179             : }
     180             : INLINE GEN
     181   208566938 : cgetineg(long x)
     182             : {
     183   208566938 :   GEN z = cgeti(x);
     184   208566937 :   z[1] = evalsigne(-1) | evallgefint(x);
     185   208566937 :   return z;
     186             : }
     187             : INLINE GEN
     188        2938 : cgetr_block(long x)
     189             : {
     190        2938 :   GEN z = newblock((size_t)x);
     191        2938 :   z[0] = CLONEBIT | evaltyp(t_REAL) | evallg(x);
     192        2938 :   return z;
     193             : }
     194             : INLINE GEN
     195  6268902233 : cgetr(long x)
     196             : {
     197  6268902233 :   GEN z = new_chunk((size_t)x);
     198  6268902233 :   z[0] = evaltyp(t_REAL) | evallg(x);
     199  6268902233 :   return z;
     200             : }
     201             : 
     202             : /*******************************************************************/
     203             : /*                                                                 */
     204             : /*                     COPY, NEGATION, ABSOLUTE VALUE              */
     205             : /*                                                                 */
     206             : /*******************************************************************/
     207             : /* cannot do memcpy because sometimes x and y overlap */
     208             : INLINE GEN
     209  1511253011 : leafcopy(GEN x)
     210             : {
     211  1511253011 :   register long lx = lg(x);
     212  1511253011 :   GEN y = new_chunk(lx); /* can't use cgetg_copy, in case x,y overlap */
     213  1511748662 :   while (--lx > 0) y[lx] = x[lx];
     214  1511748662 :   y[0] = x[0] & (TYPBITS|LGBITS); return y;
     215             : }
     216             : INLINE GEN
     217  4451162905 : icopy(GEN x)
     218             : {
     219  4451162905 :   long i = lgefint(x), lx = i;
     220  4451162905 :   GEN y = new_chunk(lx); /* can't use cgeti, in case x,y overlap */
     221  4455648722 :   while (--i > 0) y[i] = x[i];
     222  4455648722 :   y[0] = evaltyp(t_INT) | evallg(lx);
     223  4454154235 :   return y;
     224             : }
     225             : INLINE GEN
     226    29861481 : icopyspec(GEN x, long nx)
     227             : {
     228    29861481 :   long i = nx+2, lx = i;
     229    29861481 :   GEN y = new_chunk(lx); /* can't use cgeti, in case x,y overlap */
     230    29861435 :   x -= 2; while (--i >= 2) y[i] = x[i];
     231    29861435 :   y[1] = evalsigne(1) | evallgefint(lx);
     232    29861435 :   y[0] = evaltyp(t_INT) | evallg(lx);
     233    29861396 :   return y;
     234             : }
     235   258641394 : INLINE GEN rcopy(GEN x) { return leafcopy(x); }
     236         224 : INLINE GEN mpcopy(GEN x) { return leafcopy(x); }
     237             : 
     238             : INLINE GEN
     239   347650298 : mpabs(GEN x) { GEN y = leafcopy(x); setabssign(y); return y; }
     240             : INLINE GEN
     241     7837416 : mpabs_shallow(GEN x) { return signe(x) < 0? mpabs(x): x; }
     242   306246730 : INLINE GEN absi(GEN x) { return mpabs(x); }
     243    30079637 : INLINE GEN absi_shallow(GEN x) { return signe(x) < 0? negi(x): x; }
     244    31440493 : INLINE GEN absr(GEN x) { return mpabs(x); }
     245             : 
     246             : INLINE GEN
     247   355504277 : mpneg(GEN x) { GEN y = leafcopy(x); togglesign(y); return y; }
     248   247257186 : INLINE GEN negi(GEN x) { return mpneg(x); }
     249     1441184 : INLINE GEN negr(GEN x) { return mpneg(x); }
     250     7832442 : INLINE GEN gmax_shallow(GEN x, GEN y) { return gcmp(x,y)<0? y: x; }
     251       89207 : INLINE GEN gmin_shallow(GEN x, GEN y) { return gcmp(x,y)<0? x: y; }
     252             : 
     253             : /* negate in place */
     254             : INLINE void
     255   784830438 : togglesign(GEN x) { if (x[1] & SIGNBITS) { x[1] ^= HIGHBIT; } }
     256             : INLINE void
     257   385271737 : setabssign(GEN x) { x[1] &= ~HIGHBIT; }
     258             : /* negate in place, except universal constants */
     259             : INLINE void
     260    56904617 : togglesign_safe(GEN *px)
     261             : {
     262    56904617 :   switch(*px - gen_1) /* gen_1, gen_2, gen_m1, gen_m2 */
     263             :   {
     264      663756 :     case 0: *px = gen_m1; break;
     265           0 :     case 3: *px = gen_m2;  break;
     266      155599 :     case 6: *px = gen_1; break;
     267           0 :     case 9: *px = gen_2;  break;
     268    56085262 :     default: togglesign(*px);
     269             :   }
     270    56904617 : }
     271             : /* setsigne(y, signe(x)) */
     272             : INLINE void
     273           0 : affectsign(GEN x, GEN y)
     274             : {
     275           0 :   y[1] = (x[1] & SIGNBITS) | (y[1] & ~SIGNBITS);
     276           0 : }
     277             : /* copies sign in place, except for universal constants */
     278             : INLINE void
     279     5318223 : affectsign_safe(GEN x, GEN *py)
     280             : {
     281     5318223 :   if (((*py)[1] ^ x[1]) & HIGHBIT) togglesign_safe(py);
     282     5318223 : }
     283             : /*******************************************************************/
     284             : /*                                                                 */
     285             : /*                     GEN -> LONG, LONG -> GEN                    */
     286             : /*                                                                 */
     287             : /*******************************************************************/
     288             : /* assume x != 0, return -x as a t_INT */
     289             : INLINE GEN
     290   208381829 : utoineg(ulong x) { GEN y = cgetineg(3); y[2] = x; return y; }
     291             : /* assume x != 0, return utoi(x) */
     292             : INLINE GEN
     293  7428250872 : utoipos(ulong x) { GEN y = cgetipos(3); y[2] = x; return y; }
     294             : INLINE GEN
     295  6157391332 : utoi(ulong x) { return x? utoipos(x): gen_0; }
     296             : INLINE GEN
     297   361085128 : stoi(long x)
     298             : {
     299   361085128 :   if (!x) return gen_0;
     300   230037364 :   return x > 0? utoipos((ulong)x): utoineg((ulong)-x);
     301             : }
     302             : 
     303             : /* x 2^BIL + y */
     304             : INLINE GEN
     305  4464477598 : uutoi(ulong x, ulong y)
     306             : {
     307             :   GEN z;
     308  4464477598 :   if (!x) return utoi(y);
     309   479346919 :   z = cgetipos(4);
     310   479108287 :   *int_W_lg(z, 1, 4) = x;
     311   479108287 :   *int_W_lg(z, 0, 4) = y; return z;
     312             : }
     313             : /* - (x 2^BIL + y) */
     314             : INLINE GEN
     315       88926 : uutoineg(ulong x, ulong y)
     316             : {
     317             :   GEN z;
     318       88926 :   if (!x) return y? utoineg(y): gen_0;
     319       10243 :   z = cgetineg(4);
     320       10243 :   *int_W_lg(z, 1, 4) = x;
     321       10243 :   *int_W_lg(z, 0, 4) = y; return z;
     322             : }
     323             : 
     324             : INLINE long
     325   315508728 : itos(GEN x)
     326             : {
     327   315508728 :   long s = signe(x);
     328             :   long u;
     329             : 
     330   315508728 :   if (!s) return 0;
     331   296803338 :   u = x[2];
     332   296803338 :   if (lgefint(x) > 3 || u < 0)
     333          19 :     pari_err_OVERFLOW("t_INT-->long assignment");
     334   296803323 :   return (s>0) ? u : -u;
     335             : }
     336             : /* as itos, but return 0 if too large. Cf is_bigint */
     337             : INLINE long
     338    11815889 : itos_or_0(GEN x) {
     339             :   long n;
     340    11815889 :   if (lgefint(x) != 3 || (n = x[2]) & HIGHBIT) return 0;
     341    11795782 :   return signe(x) > 0? n: -n;
     342             : }
     343             : INLINE ulong
     344    80073168 : itou(GEN x)
     345             : {
     346    80073168 :   switch(lgefint(x)) {
     347     9746968 :     case 2: return 0;
     348    70326200 :     case 3: return x[2];
     349             :     default:
     350           0 :       pari_err_OVERFLOW("t_INT-->ulong assignment");
     351             :       return 0; /* LCOV_EXCL_LINE */
     352             :   }
     353             : }
     354             : 
     355             : /* as itou, but return 0 if too large. Cf is_bigint */
     356             : INLINE ulong
     357     4590021 : itou_or_0(GEN x) {
     358     4590021 :   if (lgefint(x) != 3) return 0;
     359     4579180 :   return (ulong)x[2];
     360             : }
     361             : 
     362             : INLINE ulong
     363     4870330 : umuluu_or_0(ulong x, ulong y)
     364             : {
     365             :   ulong z;
     366             :   LOCAL_HIREMAINDER;
     367     4870330 :   z = mulll(x, y);
     368     4870330 :   return hiremainder? 0: z;
     369             : }
     370             : /* return x*y if <= n, else 0. Beware overflow */
     371             : INLINE ulong
     372     2854168 : umuluu_le(ulong x, ulong y, ulong n)
     373             : {
     374             :   ulong z;
     375             :   LOCAL_HIREMAINDER;
     376     2854168 :   z = mulll(x, y);
     377     2854168 :   return (hiremainder || z > n)? 0: z;
     378             : }
     379             : 
     380             : INLINE GEN
     381   128994818 : real_0_bit(long bitprec) { GEN x=cgetr(2); x[1]=evalexpo(bitprec); return x; }
     382             : INLINE GEN
     383    32554539 : real_0(long prec) { return real_0_bit(-prec2nbits(prec)); }
     384             : INLINE GEN
     385      578632 : real_1_bit(long bit) { return real_1(nbits2prec(bit)); }
     386             : INLINE GEN
     387    38484302 : real_1(long prec) {
     388    38484302 :   GEN x = cgetr(prec);
     389             :   long i;
     390    38484302 :   x[1] = evalsigne(1) | _evalexpo(0);
     391    38484302 :   x[2] = (long)HIGHBIT; for (i=3; i<prec; i++) x[i] = 0;
     392    38484302 :   return x;
     393             : }
     394             : INLINE GEN
     395          91 : real_m1(long prec) {
     396          91 :   GEN x = cgetr(prec);
     397             :   long i;
     398          91 :   x[1] = evalsigne(-1) | _evalexpo(0);
     399          91 :   x[2] = (long)HIGHBIT; for (i=3; i<prec; i++) x[i] = 0;
     400          91 :   return x;
     401             : }
     402             : 
     403             : /* 2.^n */
     404             : INLINE GEN
     405       94443 : real2n(long n, long prec) { GEN z = real_1(prec); setexpo(z, n); return z; }
     406             : INLINE GEN
     407           0 : real_m2n(long n, long prec) { GEN z = real_m1(prec); setexpo(z, n); return z; }
     408             : INLINE GEN
     409   175084912 : stor(long s, long prec) { GEN z = cgetr(prec); affsr(s,z); return z; }
     410             : INLINE GEN
     411     5940118 : utor(ulong s, long prec){ GEN z = cgetr(prec); affur(s,z); return z; }
     412             : INLINE GEN
     413   182960748 : itor(GEN x, long prec) { GEN z = cgetr(prec); affir(x,z); return z; }
     414             : INLINE GEN
     415   100798406 : rtor(GEN x, long prec) { GEN z = cgetr(prec); affrr(x,z); return z; }
     416             : 
     417    11563022 : INLINE ulong int_bit(GEN x, long n)
     418             : {
     419    11563022 :   long r, q = dvmdsBIL(n, &r);
     420    11557332 :   return q < lgefint(x)-2?((ulong)*int_W(x,q) >> r) & 1UL:0;
     421             : }
     422             : 
     423             : /*******************************************************************/
     424             : /*                                                                 */
     425             : /*                           COMPARISON                            */
     426             : /*                                                                 */
     427             : /*******************************************************************/
     428             : INLINE int
     429      583131 : cmpir(GEN x, GEN y)
     430             : {
     431             :   pari_sp av;
     432             :   GEN z;
     433             : 
     434      583131 :   if (!signe(x)) return -signe(y);
     435      207658 :   if (!signe(y))
     436             :   {
     437        3760 :     if (expo(y) >= expi(x)) return 0;
     438        3732 :     return signe(x);
     439             :   }
     440      203898 :   av=avma; z = itor(x, realprec(y)); avma=av;
     441      203898 :   return cmprr(z,y); /* cmprr does no memory adjustment */
     442             : }
     443             : INLINE int
     444      336056 : cmpri(GEN x, GEN y) { return -cmpir(y,x); }
     445             : INLINE int
     446       75606 : cmpsr(long x, GEN y)
     447             : {
     448             :   pari_sp av;
     449             :   GEN z;
     450             : 
     451       75606 :   if (!x) return -signe(y);
     452       75606 :   av=avma; z = stor(x, LOWDEFAULTPREC); avma=av;
     453       75606 :   return cmprr(z,y);
     454             : }
     455             : INLINE int
     456       38668 : cmprs(GEN x, long y) { return -cmpsr(y,x); }
     457             : /* compare x and y */
     458             : INLINE int
     459         994 : cmpui(ulong x, GEN y)
     460             : {
     461             :   ulong p;
     462         994 :   if (!x) return -signe(y);
     463         994 :   if (signe(y) <= 0) return 1;
     464         994 :   if (lgefint(y) > 3) return -1;
     465         987 :   p = y[2]; if (p == x) return 0;
     466         798 :   return p < x ? 1 : -1;
     467             : }
     468             : INLINE int
     469         994 : cmpiu(GEN x, ulong y) { return -cmpui(y,x); }
     470             : /* compare x and |y| */
     471             : INLINE int
     472    31000685 : abscmpui(ulong x, GEN y)
     473             : {
     474    31000685 :   long l = lgefint(y);
     475             :   ulong p;
     476             : 
     477    31000685 :   if (!x) return (l > 2)? -1: 0;
     478    31000671 :   if (l == 2) return 1;
     479    30804217 :   if (l > 3) return -1;
     480    30792828 :   p = y[2]; if (p == x) return 0;
     481    30389181 :   return p < x ? 1 : -1;
     482             : }
     483             : INLINE int
     484    30944019 : abscmpiu(GEN x, ulong y) { return -abscmpui(y,x); }
     485             : INLINE int
     486     4331362 : cmpsi(long x, GEN y)
     487             : {
     488             :   ulong p;
     489             : 
     490     4331362 :   if (!x) return -signe(y);
     491             : 
     492     4330312 :   if (x > 0)
     493             :   {
     494     4329885 :     if (signe(y)<=0) return 1;
     495     4329689 :     if (lgefint(y)>3) return -1;
     496     4315443 :     p = y[2]; if (p == (ulong)x) return 0;
     497     4254354 :     return p < (ulong)x ? 1 : -1;
     498             :   }
     499             : 
     500         427 :   if (signe(y)>=0) return -1;
     501          63 :   if (lgefint(y)>3) return 1;
     502          63 :   p = y[2]; if (p == (ulong)-x) return 0;
     503          14 :   return p < (ulong)(-x) ? -1 : 1;
     504             : }
     505             : INLINE int
     506     4328359 : cmpis(GEN x, long y) { return -cmpsi(y,x); }
     507             : INLINE int
     508      543841 : mpcmp(GEN x, GEN y)
     509             : {
     510      543841 :   if (typ(x)==t_INT)
     511        7521 :     return (typ(y)==t_INT) ? cmpii(x,y) : cmpir(x,y);
     512      536320 :   return (typ(y)==t_INT) ? -cmpir(y,x) : cmprr(x,y);
     513             : }
     514             : 
     515             : /* x == y ? */
     516             : INLINE int
     517       22646 : equalui(ulong x, GEN y)
     518             : {
     519       22646 :   if (!x) return !signe(y);
     520       22646 :   if (signe(y) <= 0 || lgefint(y) != 3) return 0;
     521       22637 :   return ((ulong)y[2] == (ulong)x);
     522             : }
     523             : /* x == y ? */
     524             : INLINE int
     525      154152 : equalsi(long x, GEN y)
     526             : {
     527      154152 :   if (!x) return !signe(y);
     528      154152 :   if (x > 0)
     529             :   {
     530      154124 :     if (signe(y) <= 0 || lgefint(y) != 3) return 0;
     531      144161 :     return ((ulong)y[2] == (ulong)x);
     532             :   }
     533          28 :   if (signe(y) >= 0 || lgefint(y) != 3) return 0;
     534          28 :   return ((ulong)y[2] == (ulong)-x);
     535             : }
     536             : /* x == |y| ? */
     537             : INLINE int
     538    36534506 : absequalui(ulong x, GEN y)
     539             : {
     540    36534506 :   if (!x) return !signe(y);
     541    36534506 :   return (lgefint(y) == 3 && (ulong)y[2] == x);
     542             : }
     543             : INLINE int
     544    36428030 : absequaliu(GEN x, ulong y) { return absequalui(y,x); }
     545             : INLINE int
     546      153935 : equalis(GEN x, long y) { return equalsi(y,x); }
     547             : INLINE int
     548       22646 : equaliu(GEN x, ulong y) { return equalui(y,x); }
     549             : 
     550             : /* assume x != 0, is |x| == 2^n ? */
     551             : INLINE int
     552      300523 : absrnz_equal2n(GEN x) {
     553      300523 :   if ((ulong)x[2]==HIGHBIT)
     554             :   {
     555       14802 :     long i, lx = lg(x);
     556       67964 :     for (i = 3; i < lx; i++)
     557       61895 :       if (x[i]) return 0;
     558        6069 :     return 1;
     559             :   }
     560      285721 :   return 0;
     561             : }
     562             : /* assume x != 0, is |x| == 1 ? */
     563             : INLINE int
     564      602252 : absrnz_equal1(GEN x) { return !expo(x) && absrnz_equal2n(x); }
     565             : 
     566             : INLINE long
     567  3004621804 : maxss(long x, long y) { return x>y?x:y; }
     568             : INLINE long
     569   772968856 : minss(long x, long y) { return x<y?x:y; }
     570             : INLINE long
     571     1952625 : minuu(ulong x, ulong y) { return x<y?x:y; }
     572             : INLINE long
     573    10444162 : maxuu(ulong x, ulong y) { return x>y?x:y; }
     574             : INLINE double
     575     3464464 : maxdd(double x, double y) { return x>y?x:y; }
     576             : INLINE double
     577     1635252 : mindd(double x, double y) { return x<y?x:y; }
     578             : 
     579             : /*******************************************************************/
     580             : /*                                                                 */
     581             : /*                             ADD / SUB                           */
     582             : /*                                                                 */
     583             : /*******************************************************************/
     584             : INLINE GEN
     585       25046 : subuu(ulong x, ulong y)
     586             : {
     587             :   ulong z;
     588             :   LOCAL_OVERFLOW;
     589       25046 :   z = subll(x, y);
     590       25046 :   return overflow? utoineg(-z): utoi(z);
     591             : }
     592             : INLINE GEN
     593  1729047120 : adduu(ulong x, ulong y) { ulong t = x+y; return uutoi((t < x), t); }
     594             : 
     595             : INLINE GEN
     596       25046 : addss(long x, long y)
     597             : {
     598       25046 :   if (!x) return stoi(y);
     599       25046 :   if (!y) return stoi(x);
     600       25046 :   if (x > 0) return y > 0? adduu(x,y): subuu(x, -y);
     601             : 
     602       25046 :   if (y > 0) return subuu(y, -x);
     603             :   else { /* - adduu(-x, -y) */
     604           0 :     ulong t = (-x)+(-y); return uutoineg((t < (ulong)(-x)), t);
     605             :   }
     606             : }
     607       25046 : INLINE GEN subss(long x, long y) { return addss(-y,x); }
     608             : 
     609             : INLINE GEN
     610  3938242066 : subii(GEN x, GEN y)
     611             : {
     612  3938242066 :   if (x==y) return gen_0; /* frequent with x = y = gen_0 */
     613  2855156643 :   return addii_sign(x, signe(x), y, -signe(y));
     614             : }
     615             : INLINE GEN
     616  4677899450 : addii(GEN x, GEN y) { return addii_sign(x, signe(x), y, signe(y)); }
     617             : INLINE GEN
     618   901121402 : addrr(GEN x, GEN y) { return addrr_sign(x, signe(x), y, signe(y)); }
     619             : INLINE GEN
     620   905756213 : subrr(GEN x, GEN y) { return addrr_sign(x, signe(x), y, -signe(y)); }
     621             : INLINE GEN
     622   134155470 : addir(GEN x, GEN y) { return addir_sign(x, signe(x), y, signe(y)); }
     623             : INLINE GEN
     624    80348086 : subir(GEN x, GEN y) { return addir_sign(x, signe(x), y, -signe(y)); }
     625             : INLINE GEN
     626     1465024 : subri(GEN x, GEN y) { return addir_sign(y, -signe(y), x, signe(x)); }
     627             : INLINE GEN
     628    64481298 : addsi(long x, GEN y) { return addsi_sign(x, y, signe(y)); }
     629             : INLINE GEN
     630    64362438 : addui(ulong x, GEN y) { return addui_sign(x, y, signe(y)); }
     631             : INLINE GEN
     632     5265374 : subsi(long x, GEN y) { return addsi_sign(x, y, -signe(y)); }
     633             : INLINE GEN
     634    33134042 : subui(ulong x, GEN y) { return addui_sign(x, y, -signe(y)); }
     635             : 
     636             : /*******************************************************************/
     637             : /*                                                                 */
     638             : /*                           MOD, REM, DIV                         */
     639             : /*                                                                 */
     640             : /*******************************************************************/
     641    97169088 : INLINE ulong mod2BIL(GEN x) { return *int_LSW(x); }
     642           0 : INLINE long mod64(GEN x) { return mod2BIL(x) & 63; }
     643         259 : INLINE long mod32(GEN x) { return mod2BIL(x) & 31; }
     644       25123 : INLINE long mod16(GEN x) { return mod2BIL(x) & 15; }
     645    49990134 : INLINE long mod8(GEN x)  { return mod2BIL(x) & 7; }
     646    11807536 : INLINE long mod4(GEN x)  { return mod2BIL(x) & 3; }
     647    20909058 : INLINE long mod2(GEN x)  { return mod2BIL(x) & 1; }
     648             : INLINE int
     649    35747598 : mpodd(GEN x) { return signe(x) && mod2(x); }
     650             : /* x mod 2^n, n < BITS_IN_LONG */
     651             : INLINE ulong
     652     4846282 : umodi2n(GEN x, long n)
     653             : {
     654     4846282 :   long s = signe(x);
     655     4846282 :   const ulong _2n = 1UL << n;
     656             :   ulong m;
     657     4846282 :   if (!s) return 0;
     658     4839492 :   m = *int_LSW(x) & (_2n - 1);
     659     4839492 :   if (s < 0 && m) m = _2n - m;
     660     4839492 :   return m;
     661             : }
     662           0 : INLINE ulong Mod64(GEN x){ return umodi2n(x,6); }
     663      166810 : INLINE ulong Mod32(GEN x){ return umodi2n(x,5); }
     664      216692 : INLINE ulong Mod16(GEN x){ return umodi2n(x,4); }
     665     1307999 : INLINE ulong Mod8(GEN x) { return umodi2n(x,3); }
     666     1329979 : INLINE ulong Mod4(GEN x) { return umodi2n(x,2); }
     667     1824732 : INLINE ulong Mod2(GEN x) { return umodi2n(x,1); }
     668             : 
     669             : INLINE GEN
     670    22887893 : truedivii(GEN a,GEN b) { return truedvmdii(a,b,NULL); }
     671             : INLINE GEN
     672        4467 : truedivis(GEN a, long b) { return truedvmdis(a,b,NULL); }
     673             : INLINE GEN
     674     6168028 : truedivsi(long a, GEN b) { return truedvmdsi(a,b,NULL); }
     675             : 
     676             : INLINE GEN
     677     7597941 : divii(GEN a, GEN b) { return dvmdii(a,b,NULL); }
     678             : INLINE GEN
     679  1217093257 : remii(GEN a, GEN b) { return dvmdii(a,b,ONLY_REM); }
     680             : 
     681             : INLINE GEN
     682           0 : divss(long x, long y) { return stoi(x / y); }
     683             : INLINE GEN
     684      658525 : modss(long x, long y) { return stoi(smodss(x, y)); }
     685             : INLINE GEN
     686           0 : remss(long x, long y) { return stoi(x % y); }
     687             : INLINE long
     688   198828228 : smodss(long x, long y)
     689             : {
     690   198828228 :   long r = x%y;
     691   198828228 :   return (r >= 0)? r: labs(y) + r;
     692             : }
     693             : INLINE ulong
     694    11587171 : umodsu(long x, ulong y)
     695             : {
     696    11587171 :   return x>=0 ? x%y: Fl_neg((-x)%y, y);
     697             : }
     698             : 
     699             : INLINE long
     700           0 : sdivss_rem(long x, long y, long *r)
     701             : {
     702             :   long q;
     703             :   LOCAL_HIREMAINDER;
     704           0 :   if (!y) pari_err_INV("sdivss_rem",gen_0);
     705           0 :   hiremainder = 0; q = divll((ulong)labs(x),(ulong)labs(y));
     706           0 :   if (x < 0) { hiremainder = -((long)hiremainder); q = -q; }
     707           0 :   if (y < 0) q = -q;
     708           0 :   *r = hiremainder; return q;
     709             : }
     710             : INLINE GEN
     711           0 : divss_rem(long x, long y, long *r) { return stoi(sdivss_rem(x,y,r)); }
     712             : INLINE ulong
     713    35975507 : udivuu_rem(ulong x, ulong y, ulong *r)
     714             : {
     715    35975507 :   if (!y) pari_err_INV("udivuu_rem",gen_0);
     716    35975507 :   *r = x % y; return x / y;
     717             : }
     718             : INLINE ulong
     719      158386 : ceildivuu(ulong a, ulong b)
     720             : {
     721      158386 :   ulong c = a/b;
     722      158386 :   return (a%b)? c+1: c;
     723             : }
     724             : 
     725             : INLINE ulong
     726       10591 : uabsdivui_rem(ulong x, GEN y, ulong *r)
     727             : {
     728       10591 :   long q, s = signe(y);
     729             :   LOCAL_HIREMAINDER;
     730             : 
     731       10591 :   if (!s) pari_err_INV("uabsdivui_rem",gen_0);
     732       10591 :   if (!x || lgefint(y)>3) { *r = x; return 0; }
     733       10318 :   hiremainder=0; q = (long)divll(x, (ulong)y[2]);
     734       10318 :   if (s < 0) q = -q;
     735       10318 :   *r = hiremainder; return q;
     736             : }
     737             : 
     738             : /* assume d != 0 and |n| / d can be represented as an ulong.
     739             :  * Return |n|/d, set *r = |n| % d */
     740             : INLINE ulong
     741    12480475 : uabsdiviu_rem(GEN n, ulong d, ulong *r)
     742             : {
     743    12480475 :   switch(lgefint(n))
     744             :   {
     745           0 :     case 2: *r = 0; return 0;
     746             :     case 3:
     747             :     {
     748    12480475 :       ulong nn = n[2];
     749    12480475 :       *r = nn % d; return nn / d;
     750             :     }
     751             :     default: /* 4 */
     752             :     {
     753             :       ulong n1, n0, q;
     754             :       LOCAL_HIREMAINDER;
     755           0 :       n0 = *int_W(n,0);
     756           0 :       n1 = *int_W(n,1);
     757           0 :       hiremainder = n1;
     758           0 :       q = divll(n0, d);
     759           0 :       *r = hiremainder; return q;
     760             :     }
     761             :   }
     762             : }
     763             : 
     764             : INLINE long
     765    13900021 : sdivsi_rem(long x, GEN y, long *r)
     766             : {
     767    13900021 :   long q, s = signe(y);
     768             :   LOCAL_HIREMAINDER;
     769             : 
     770    13900021 :   if (!s) pari_err_INV("sdivsi_rem",gen_0);
     771    13900022 :   if (!x || lgefint(y)>3 || ((long)y[2]) < 0) { *r = x; return 0; }
     772    11991901 :   hiremainder=0; q = (long)divll(labs(x), (ulong)y[2]);
     773    11991901 :   if (x < 0) { hiremainder = -((long)hiremainder); q = -q; }
     774    11991901 :   if (s < 0) q = -q;
     775    11991901 :   *r = hiremainder; return q;
     776             : }
     777             : INLINE GEN
     778           0 : divsi_rem(long s, GEN y, long *r) { return stoi(sdivsi_rem(s,y,r)); }
     779             : 
     780             : INLINE long
     781         140 : sdivsi(long x, GEN y)
     782             : {
     783         140 :   long q, s = signe(y);
     784             : 
     785         140 :   if (!s) pari_err_INV("sdivsi",gen_0);
     786         140 :   if (!x || lgefint(y)>3 || ((long)y[2]) < 0) return 0;
     787          98 :   q = labs(x) / y[2];
     788          98 :   if (x < 0) q = -q;
     789          98 :   if (s < 0) q = -q;
     790          98 :   return q;
     791             : }
     792             : 
     793             : INLINE GEN
     794           0 : dvmdss(long x, long y, GEN *z)
     795             : {
     796             :   long r;
     797           0 :   GEN q = divss_rem(x,y, &r);
     798           0 :   *z = stoi(r); return q;
     799             : }
     800             : INLINE long
     801  2984537090 : dvmdsBIL(long n, long *r) { *r = remsBIL(n); return divsBIL(n); }
     802             : INLINE ulong
     803   143593191 : dvmduBIL(ulong n, ulong *r) { *r = remsBIL(n); return divsBIL(n); }
     804             : INLINE GEN
     805           0 : dvmdsi(long x, GEN y, GEN *z)
     806             : {
     807             :   long r;
     808           0 :   GEN q = divsi_rem(x,y, &r);
     809           0 :   *z = stoi(r); return q;
     810             : }
     811             : INLINE GEN
     812           0 : dvmdis(GEN x, long y, GEN *z)
     813             : {
     814             :   long r;
     815           0 :   GEN q = divis_rem(x,y, &r);
     816           0 :   *z = stoi(r); return q;
     817             : }
     818             : 
     819             : INLINE long
     820    19628782 : smodis(GEN x, long y)
     821             : {
     822    19628782 :   pari_sp av = avma;
     823             :   long r;
     824    19628782 :   (void)divis_rem(x,y, &r); avma = av; return (r >= 0) ? r: labs(y) + r;
     825             : }
     826             : INLINE GEN
     827    19590254 : modis(GEN x, long y) { return stoi(smodis(x,y)); }
     828             : INLINE GEN
     829     7731750 : modsi(long x, GEN y) {
     830             :   long r;
     831     7731750 :   (void)sdivsi_rem(x, y, &r);
     832     7731749 :   return (r >= 0)? stoi(r): addsi_sign(r, y, 1);
     833             : }
     834             : 
     835             : INLINE ulong
     836     1259983 : umodui(ulong x, GEN y)
     837             : {
     838     1259983 :   if (!signe(y)) pari_err_INV("umodui",gen_0);
     839     1259983 :   if (!x || lgefint(y) > 3) return x;
     840      234530 :   return x % (ulong)y[2];
     841             : }
     842             : 
     843             : INLINE ulong
     844       42933 : ugcdiu(GEN x, ulong y) { return ugcd(umodiu(x,y), y); }
     845             : INLINE ulong
     846        4792 : ugcdui(ulong y, GEN x) { return ugcd(umodiu(x,y), y); }
     847             : 
     848             : INLINE GEN
     849           0 : remsi(long x, GEN y)
     850           0 : { long r; (void)sdivsi_rem(x,y, &r); return stoi(r); }
     851             : INLINE GEN
     852           0 : remis(GEN x, long y)
     853             : {
     854           0 :   pari_sp av = avma;
     855             :   long r;
     856           0 :   (void)divis_rem(x,y, &r); avma = av; return stoi(r);
     857             : }
     858             : 
     859             : INLINE GEN
     860           0 : rdivis(GEN x, long y, long prec)
     861             : {
     862           0 :   GEN z = cgetr(prec);
     863           0 :   pari_sp av = avma;
     864           0 :   affrr(divrs(itor(x,prec), y),z);
     865           0 :   avma = av; return z;
     866             : }
     867             : INLINE GEN
     868           0 : rdivsi(long x, GEN y, long prec)
     869             : {
     870           0 :   GEN z = cgetr(prec);
     871           0 :   pari_sp av = avma;
     872           0 :   affrr(divsr(x, itor(y,prec)), z);
     873           0 :   avma = av; return z;
     874             : }
     875             : INLINE GEN
     876      839647 : rdivss(long x, long y, long prec)
     877             : {
     878      839647 :   GEN z = cgetr(prec);
     879      839647 :   pari_sp av = avma;
     880      839647 :   affrr(divrs(stor(x, prec), y), z);
     881      839647 :   avma = av; return z;
     882             : }
     883             : 
     884             : INLINE void
     885          14 : rdiviiz(GEN x, GEN y, GEN z)
     886             : {
     887          14 :   pari_sp av = avma;
     888          14 :   long prec = realprec(z);
     889          14 :   affir(x, z);
     890          14 :   if (!is_bigint(y)) {
     891           0 :     affrr(divrs(z, y[2]), z);
     892           0 :     if (signe(y) < 0) togglesign(z);
     893             :   }
     894             :   else
     895          14 :     affrr(divrr(z, itor(y,prec)), z);
     896          14 :   avma = av;
     897          14 : }
     898             : INLINE GEN
     899    11399344 : rdivii(GEN x, GEN y, long prec)
     900             : {
     901    11399344 :   GEN z = cgetr(prec);
     902    11399344 :   pari_sp av = avma;
     903    11399344 :   affir(x, z);
     904    11399344 :   if (lg(y) == 3) {
     905     7223523 :     affrr(divru(z, y[2]), z);
     906     7223523 :     if (signe(y) < 0) togglesign(z);
     907             :   }
     908             :   else
     909     4175821 :     affrr(divrr(z, itor(y,prec)), z);
     910    11399344 :   avma = av; return z;
     911             : }
     912             : INLINE GEN
     913    11322735 : fractor(GEN x, long prec) { return rdivii(gel(x,1), gel(x,2), prec); }
     914             : 
     915             : INLINE int
     916     6056924 : dvdii(GEN x, GEN y)
     917             : {
     918     6056924 :   pari_sp av=avma;
     919     6056924 :   GEN r = remii(x,y);
     920     6069212 :   avma = av; return r == gen_0;
     921             : }
     922             : INLINE int
     923          84 : dvdsi(long x, GEN y)
     924             : {
     925          84 :   if (!signe(y)) return x == 0;
     926          84 :   if (lgefint(y) != 3) return 0;
     927          84 :   return x % y[2] == 0;
     928             : }
     929             : INLINE int
     930         147 : dvdui(ulong x, GEN y)
     931             : {
     932         147 :   if (!signe(y)) return x == 0;
     933         147 :   if (lgefint(y) != 3) return 0;
     934         147 :   return x % y[2] == 0;
     935             : }
     936             : INLINE int
     937        5558 : dvdis(GEN x, long y)
     938        5558 : { return y? smodis(x, y) == 0: signe(x) == 0; }
     939             : INLINE int
     940        2261 : dvdiu(GEN x, ulong y)
     941        2261 : { return y? umodiu(x, y) == 0: signe(x) == 0; }
     942             : 
     943             : INLINE int
     944           0 : dvdisz(GEN x, long y, GEN z)
     945             : {
     946           0 :   const pari_sp av = avma;
     947             :   long r;
     948           0 :   GEN p1 = divis_rem(x,y, &r);
     949           0 :   avma = av; if (r) return 0;
     950           0 :   affii(p1,z); return 1;
     951             : }
     952             : INLINE int
     953           0 : dvdiuz(GEN x, ulong y, GEN z)
     954             : {
     955           0 :   const pari_sp av = avma;
     956             :   ulong r;
     957           0 :   GEN p1 = absdiviu_rem(x,y, &r);
     958           0 :   avma = av; if (r) return 0;
     959           0 :   affii(p1,z); return 1;
     960             : }
     961             : INLINE int
     962        3985 : dvdiiz(GEN x, GEN y, GEN z)
     963             : {
     964        3985 :   const pari_sp av=avma;
     965             :   GEN p2;
     966        3985 :   const GEN p1=dvmdii(x,y,&p2);
     967             : 
     968        3985 :   if (signe(p2)) { avma=av; return 0; }
     969        3282 :   affii(p1,z); avma=av; return 1;
     970             : }
     971             : 
     972             : INLINE ulong
     973     5423013 : remlll_pre(ulong u2, ulong u1, ulong u0, ulong n, ulong ninv)
     974             : {
     975     5423013 :   u1 = remll_pre(u2, u1, n, ninv);
     976     5422919 :   return remll_pre(u1, u0, n, ninv);
     977             : }
     978             : 
     979             : INLINE ulong
     980  1696724927 : Fl_sqr_pre(ulong a, ulong p, ulong pi)
     981             : {
     982             :   register ulong x;
     983             :   LOCAL_HIREMAINDER;
     984  1696724927 :   x = mulll(a,a);
     985  1696724927 :   return remll_pre(hiremainder, x, p, pi);
     986             : }
     987             : 
     988             : INLINE ulong
     989  2564819079 : Fl_mul_pre(ulong a, ulong b, ulong p, ulong pi)
     990             : {
     991             :   register ulong x;
     992             :   LOCAL_HIREMAINDER;
     993  2564819079 :   x = mulll(a,b);
     994  2564819079 :   return remll_pre(hiremainder, x, p, pi);
     995             : }
     996             : 
     997             : INLINE ulong
     998  4803652082 : Fl_addmul_pre(ulong y0, ulong x0, ulong x1, ulong p, ulong pi)
     999             : {
    1000             :   ulong l0, h0;
    1001             :   LOCAL_HIREMAINDER;
    1002  4803652082 :   hiremainder = y0;
    1003  4803652082 :   l0 = addmul(x0, x1); h0 = hiremainder;
    1004  4803652082 :   return remll_pre(h0, l0, p, pi);
    1005             : }
    1006             : 
    1007             : INLINE ulong
    1008    47723145 : Fl_addmulmul_pre(ulong x0, ulong y0, ulong x1, ulong y1, ulong p, ulong pi)
    1009             : {
    1010             :   ulong l0, l1, h0, h1;
    1011             :   LOCAL_OVERFLOW;
    1012             :   LOCAL_HIREMAINDER;
    1013    47723145 :   l0 = mulll(x0, y0); h0 = hiremainder;
    1014    47723145 :   l1 = mulll(x1, y1); h1 = hiremainder;
    1015    47723145 :   l0 = addll(l0, l1); h0 = addllx(h0, h1);
    1016    47723145 :   return overflow ? remlll_pre(1, h0, l0, p, pi): remll_pre(h0, l0, p, pi);
    1017             : }
    1018             : 
    1019             : INLINE ulong
    1020      189157 : Fl_ellj_pre(ulong a4, ulong a6, ulong p, ulong pi)
    1021             : {
    1022             :   /* a43 = 4 a4^3 */
    1023      189157 :   ulong a43 = Fl_double(Fl_double(
    1024             :               Fl_mul_pre(a4, Fl_sqr_pre(a4, p, pi), p, pi), p), p);
    1025             :   /* a62 = 27 a6^2 */
    1026      189160 :   ulong a62 = Fl_mul_pre(Fl_sqr_pre(a6, p, pi), 27 % p, p, pi);
    1027      189162 :   ulong z1 = Fl_mul_pre(a43, 1728 % p, p, pi);
    1028      189161 :   ulong z2 = Fl_add(a43, a62, p);
    1029      189160 :   return Fl_div(z1, z2, p);
    1030             : }
    1031             : 
    1032             : /*******************************************************************/
    1033             : /*                                                                 */
    1034             : /*                        MP (INT OR REAL)                         */
    1035             : /*                                                                 */
    1036             : /*******************************************************************/
    1037             : INLINE GEN
    1038          21 : mptrunc(GEN x) { return typ(x)==t_INT? icopy(x): truncr(x); }
    1039             : INLINE GEN
    1040           0 : mpfloor(GEN x) { return typ(x)==t_INT? icopy(x): floorr(x); }
    1041             : INLINE GEN
    1042           0 : mpceil(GEN x) { return typ(x)==t_INT? icopy(x): ceilr(x); }
    1043             : INLINE GEN
    1044     1300755 : mpround(GEN x) { return typ(x) == t_INT? icopy(x): roundr(x); }
    1045             : 
    1046             : INLINE long
    1047      250269 : mpexpo(GEN x) { return typ(x) == t_INT? expi(x): expo(x); }
    1048             : 
    1049             : INLINE GEN
    1050    52283221 : mpadd(GEN x, GEN y)
    1051             : {
    1052    52283221 :   if (typ(x)==t_INT)
    1053    13607835 :     return (typ(y)==t_INT) ? addii(x,y) : addir(x,y);
    1054    38675386 :   return (typ(y)==t_INT) ? addir(y,x) : addrr(x,y);
    1055             : }
    1056             : INLINE GEN
    1057    20897085 : mpsub(GEN x, GEN y)
    1058             : {
    1059    20897085 :   if (typ(x)==t_INT)
    1060     1363884 :     return (typ(y)==t_INT) ? subii(x,y) : subir(x,y);
    1061    19533201 :   return (typ(y)==t_INT) ? subri(x,y) : subrr(x,y);
    1062             : }
    1063             : INLINE GEN
    1064    65317519 : mpmul(GEN x, GEN y)
    1065             : {
    1066    65317519 :   if (typ(x)==t_INT)
    1067    17837870 :     return (typ(y)==t_INT) ? mulii(x,y) : mulir(x,y);
    1068    47479649 :   return (typ(y)==t_INT) ? mulir(y,x) : mulrr(x,y);
    1069             : }
    1070             : INLINE GEN
    1071    10122902 : mpsqr(GEN x) { return (typ(x)==t_INT) ? sqri(x) : sqrr(x); }
    1072             : INLINE GEN
    1073      152413 : mpdiv(GEN x, GEN y)
    1074             : {
    1075      152413 :   if (typ(x)==t_INT)
    1076       78676 :     return (typ(y)==t_INT) ? divii(x,y) : divir(x,y);
    1077       73737 :   return (typ(y)==t_INT) ? divri(x,y) : divrr(x,y);
    1078             : }
    1079             : 
    1080             : /*******************************************************************/
    1081             : /*                                                                 */
    1082             : /*                          Z/nZ, n ULONG                          */
    1083             : /*                                                                 */
    1084             : /*******************************************************************/
    1085             : INLINE ulong
    1086   385119112 : Fl_double(ulong a, ulong p)
    1087             : {
    1088   385119112 :   ulong res = a << 1;
    1089   385119112 :   return (res >= p || res < a) ? res - p : res;
    1090             : }
    1091             : INLINE ulong
    1092    72397327 : Fl_triple(ulong a, ulong p)
    1093             : {
    1094    72397327 :   ulong res = a << 1;
    1095    72397327 :   if (res >= p || res < a) res -= p;
    1096    72397327 :   res += a;
    1097    72397327 :   return (res >= p || res < a)? res - p: res;
    1098             : }
    1099             : INLINE ulong
    1100    14050932 : Fl_halve(ulong a, ulong p)
    1101             : {
    1102             :   ulong ap, ap2;
    1103    14050932 :   if ((a&1UL)==0) return a>>1;
    1104     7092041 :   ap = a + p; ap2 = ap>>1;
    1105     7092041 :   return ap>=a ? ap2: (ap2|HIGHBIT);
    1106             : }
    1107             : 
    1108             : INLINE ulong
    1109  2464584513 : Fl_add(ulong a, ulong b, ulong p)
    1110             : {
    1111  2464584513 :   ulong res = a + b;
    1112  2464584513 :   return (res >= p || res < a) ? res - p : res;
    1113             : }
    1114             : INLINE ulong
    1115    71218765 : Fl_neg(ulong x, ulong p) { return x ? p - x: 0; }
    1116             : 
    1117             : INLINE ulong
    1118  4470587347 : Fl_sub(ulong a, ulong b, ulong p)
    1119             : {
    1120  4470587347 :   ulong res = a - b;
    1121  4470587347 :   return (res > a) ? res + p: res;
    1122             : }
    1123             : 
    1124             : /* centerlift(u mod p) */
    1125             : INLINE long
    1126    12025835 : Fl_center(ulong u, ulong p, ulong ps2) { return (long) (u > ps2)? u - p: u; }
    1127             : 
    1128             : INLINE ulong
    1129   859236002 : Fl_mul(ulong a, ulong b, ulong p)
    1130             : {
    1131             :   register ulong x;
    1132             :   LOCAL_HIREMAINDER;
    1133   859236002 :   x = mulll(a,b);
    1134   859236002 :   if (!hiremainder) return x % p;
    1135   163566223 :   (void)divll(x,p); return hiremainder;
    1136             : }
    1137             : INLINE ulong
    1138    65637851 : Fl_sqr(ulong a, ulong p)
    1139             : {
    1140             :   register ulong x;
    1141             :   LOCAL_HIREMAINDER;
    1142    65637851 :   x = mulll(a,a);
    1143    65637851 :   if (!hiremainder) return x % p;
    1144    37890237 :   (void)divll(x,p); return hiremainder;
    1145             : }
    1146             : INLINE ulong
    1147     8141414 : Fl_div(ulong a, ulong b, ulong p) { return Fl_mul(a, Fl_inv(b, p), p); }
    1148             : 
    1149             : /*******************************************************************/
    1150             : /*                                                                 */
    1151             : /*        DEFINED FROM EXISTING ONE EXPLOITING COMMUTATIVITY       */
    1152             : /*                                                                 */
    1153             : /*******************************************************************/
    1154             : INLINE GEN
    1155      208358 : addri(GEN x, GEN y) { return addir(y,x); }
    1156             : INLINE GEN
    1157    61140169 : addis(GEN x, long s) { return addsi(s,x); }
    1158             : INLINE GEN
    1159    63685929 : addiu(GEN x, ulong s) { return addui(s,x); }
    1160             : INLINE GEN
    1161     2891994 : addrs(GEN x, long s) { return addsr(s,x); }
    1162             : 
    1163             : INLINE GEN
    1164    29883538 : subiu(GEN x, long y) { GEN z = subui(y, x); togglesign(z); return z; }
    1165             : INLINE GEN
    1166        1653 : subis(GEN x, long y) { return addsi(-y,x); }
    1167             : INLINE GEN
    1168     3213739 : subrs(GEN x, long y) { return addsr(-y,x); }
    1169             : 
    1170             : INLINE GEN
    1171   137174217 : mulis(GEN x, long s) { return mulsi(s,x); }
    1172             : INLINE GEN
    1173   598439504 : muliu(GEN x, ulong s) { return mului(s,x); }
    1174             : INLINE GEN
    1175     4379495 : mulru(GEN x, ulong s) { return mulur(s,x); }
    1176             : INLINE GEN
    1177    15987164 : mulri(GEN x, GEN s) { return mulir(s,x); }
    1178             : INLINE GEN
    1179    10015591 : mulrs(GEN x, long s) { return mulsr(s,x); }
    1180             : 
    1181             : /*******************************************************************/
    1182             : /*                                                                 */
    1183             : /*                  VALUATION, EXPONENT, SHIFTS                    */
    1184             : /*                                                                 */
    1185             : /*******************************************************************/
    1186             : INLINE long
    1187    60158435 : vali(GEN x)
    1188             : {
    1189             :   long i;
    1190             :   GEN xp;
    1191             : 
    1192    60158435 :   if (!signe(x)) return -1;
    1193    60158267 :   xp=int_LSW(x);
    1194    60158267 :   for (i=0; !*xp; i++) xp=int_nextW(xp);
    1195    60158267 :   return vals(*xp) + i * BITS_IN_LONG;
    1196             : }
    1197             : 
    1198             : 
    1199             : /* assume x > 0 */
    1200             : INLINE long
    1201   373639834 : expu(ulong x) { return (BITS_IN_LONG-1) - (long)bfffo(x); }
    1202             : 
    1203             : INLINE long
    1204   599602402 : expi(GEN x)
    1205             : {
    1206   599602402 :   const long lx=lgefint(x);
    1207   599602402 :   return lx==2? -(long)HIGHEXPOBIT: bit_accuracy(lx)-(long)bfffo(*int_MSW(x))-1;
    1208             : }
    1209             : 
    1210             : INLINE GEN
    1211    63210466 : shiftr(GEN x, long n)
    1212             : {
    1213    63210466 :   const long e = evalexpo(expo(x)+n);
    1214    63210466 :   const GEN y = rcopy(x);
    1215             : 
    1216    63210466 :   if (e & ~EXPOBITS) pari_err_OVERFLOW("expo()");
    1217    63210466 :   y[1] = (y[1]&~EXPOBITS) | e; return y;
    1218             : }
    1219             : INLINE GEN
    1220    17086432 : mpshift(GEN x,long s) { return (typ(x)==t_INT)?shifti(x,s):shiftr(x,s); }
    1221             : 
    1222             : /* FIXME: adapt/use mpn_[lr]shift instead */
    1223             : /* z2[imin..imax] := z1[imin..imax].f shifted left sh bits
    1224             :  * (feeding f from the right). Assume sh > 0 */
    1225             : INLINE void
    1226  3103992194 : shift_left(GEN z2, GEN z1, long imin, long imax, ulong f,  ulong sh)
    1227             : {
    1228  3103992194 :   GEN sb = z1 + imin, se = z1 + imax, te = z2 + imax;
    1229  3103992194 :   ulong l, m = BITS_IN_LONG - sh, k = f >> m;
    1230 17939063179 :   while (se > sb) {
    1231 11731078791 :     l     = *se--;
    1232 11731078791 :     *te-- = (l << sh) | k;
    1233 11731078791 :     k     = l >> m;
    1234             :   }
    1235  3103992194 :   *te = (((ulong)*se) << sh) | k;
    1236  3103992194 : }
    1237             : /* z2[imin..imax] := f.z1[imin..imax-1] shifted right sh bits
    1238             :  * (feeding f from the left). Assume sh > 0 */
    1239             : INLINE void
    1240  2616044501 : shift_right(GEN z2, GEN z1, long imin, long imax, ulong f, ulong sh)
    1241             : {
    1242  2616044501 :   GEN sb = z1 + imin, se = z1 + imax, tb = z2 + imin;
    1243  2616044501 :   ulong k, l = *sb++, m = BITS_IN_LONG - sh;
    1244  2616044501 :   *tb++ = (l >> sh) | (f << m);
    1245 14244317317 :   while (sb < se) {
    1246  9012228315 :     k     = l << m;
    1247  9012228315 :     l     = *sb++;
    1248  9012228315 :     *tb++ = (l >> sh) | k;
    1249             :   }
    1250  2616044501 : }
    1251             : 
    1252             : /* Backward compatibility. Inefficient && unused */
    1253             : extern ulong hiremainder;
    1254             : INLINE ulong
    1255           0 : shiftl(ulong x, ulong y)
    1256           0 : { hiremainder = x>>(BITS_IN_LONG-y); return (x<<y); }
    1257             : 
    1258             : INLINE ulong
    1259           0 : shiftlr(ulong x, ulong y)
    1260           0 : { hiremainder = x<<(BITS_IN_LONG-y); return (x>>y); }
    1261             : 
    1262             : INLINE void
    1263    86984015 : shiftr_inplace(GEN z, long d)
    1264             : {
    1265    86984015 :   setexpo(z, expo(z)+d);
    1266    86984015 : }
    1267             : 
    1268             : /*******************************************************************/
    1269             : /*                                                                 */
    1270             : /*                           ASSIGNMENT                            */
    1271             : /*                                                                 */
    1272             : /*******************************************************************/
    1273             : INLINE void
    1274    70141105 : affii(GEN x, GEN y)
    1275             : {
    1276    70141105 :   long lx = lgefint(x);
    1277    70141105 :   if (lg(y)<lx) pari_err_OVERFLOW("t_INT-->t_INT assignment");
    1278    70141115 :   while (--lx) y[lx] = x[lx];
    1279    70141115 : }
    1280             : INLINE void
    1281      432631 : affsi(long s, GEN x)
    1282             : {
    1283      432631 :   if (!s) x[1] = evalsigne(0) | evallgefint(2);
    1284             :   else
    1285             :   {
    1286      410416 :     if (s > 0) { x[1] = evalsigne( 1) | evallgefint(3); x[2] =  s; }
    1287      152808 :     else       { x[1] = evalsigne(-1) | evallgefint(3); x[2] = -s; }
    1288             :   }
    1289      432631 : }
    1290             : INLINE void
    1291     8404740 : affui(ulong u, GEN x)
    1292             : {
    1293     8404740 :   if (!u) x[1] = evalsigne(0) | evallgefint(2);
    1294     8403466 :   else  { x[1] = evalsigne(1) | evallgefint(3); x[2] = u; }
    1295     8404740 : }
    1296             : 
    1297             : INLINE void
    1298   175155934 : affsr(long x, GEN y)
    1299             : {
    1300   175155934 :   long sh, i, ly = lg(y);
    1301             : 
    1302   175155934 :   if (!x)
    1303             :   {
    1304     1366474 :     y[1] = evalexpo(-prec2nbits(ly));
    1305     1366474 :     return;
    1306             :   }
    1307   173789460 :   if (x < 0) {
    1308      160203 :     x = -x; sh = bfffo(x);
    1309      160203 :     y[1] = evalsigne(-1) | _evalexpo((BITS_IN_LONG-1)-sh);
    1310             :   }
    1311             :   else
    1312             :   {
    1313   173629257 :     sh = bfffo(x);
    1314   173629257 :     y[1] = evalsigne(1) | _evalexpo((BITS_IN_LONG-1)-sh);
    1315             :   }
    1316   173789460 :   y[2] = ((ulong)x)<<sh; for (i=3; i<ly; i++) y[i]=0;
    1317             : }
    1318             : 
    1319             : INLINE void
    1320     5940118 : affur(ulong x, GEN y)
    1321             : {
    1322     5940118 :   long sh, i, ly = lg(y);
    1323             : 
    1324     5940118 :   if (!x)
    1325             :   {
    1326         854 :     y[1] = evalexpo(-prec2nbits(ly));
    1327         854 :     return;
    1328             :   }
    1329     5939264 :   sh = bfffo(x);
    1330     5939264 :   y[1] = evalsigne(1) | _evalexpo((BITS_IN_LONG-1)-sh);
    1331     5939264 :   y[2] = x<<sh; for (i=3; i<ly; i++) y[i] = 0;
    1332             : }
    1333             : 
    1334             : INLINE void
    1335      148295 : affiz(GEN x, GEN y) { if (typ(y)==t_INT) affii(x,y); else affir(x,y); }
    1336             : INLINE void
    1337           0 : affsz(long x, GEN y) { if (typ(y)==t_INT) affsi(x,y); else affsr(x,y); }
    1338             : INLINE void
    1339      174478 : mpaff(GEN x, GEN y) { if (typ(x)==t_INT) affiz(x, y); else affrr(x,y); }
    1340             : 
    1341             : /*******************************************************************/
    1342             : /*                                                                 */
    1343             : /*                    OPERATION + ASSIGNMENT                       */
    1344             : /*                                                                 */
    1345             : /*******************************************************************/
    1346             : 
    1347           0 : INLINE void addiiz(GEN x, GEN y, GEN z)
    1348           0 : { pari_sp av = avma; affii(addii(x,y),z); avma = av; }
    1349           0 : INLINE void addirz(GEN x, GEN y, GEN z)
    1350           0 : { pari_sp av = avma; affrr(addir(x,y),z); avma = av; }
    1351           0 : INLINE void addriz(GEN x, GEN y, GEN z)
    1352           0 : { pari_sp av = avma; affrr(addri(x,y),z); avma = av; }
    1353     1396786 : INLINE void addrrz(GEN x, GEN y, GEN z)
    1354     1396786 : { pari_sp av = avma; affrr(addrr(x,y),z); avma = av; }
    1355           0 : INLINE void addsiz(long s, GEN y, GEN z)
    1356           0 : { pari_sp av = avma; affii(addsi(s,y),z); avma = av; }
    1357           0 : INLINE void addsrz(long s, GEN y, GEN z)
    1358           0 : { pari_sp av = avma; affrr(addsr(s,y),z); avma = av; }
    1359           0 : INLINE void addssz(long s, long y, GEN z)
    1360           0 : { pari_sp av = avma; affii(addss(s,y),z); avma = av; }
    1361             : 
    1362          14 : INLINE void diviiz(GEN x, GEN y, GEN z)
    1363          14 : { pari_sp av = avma; affii(divii(x,y),z); avma = av; }
    1364           0 : INLINE void divirz(GEN x, GEN y, GEN z)
    1365           0 : { pari_sp av = avma; mpaff(divir(x,y),z); avma = av; }
    1366           0 : INLINE void divisz(GEN x, long y, GEN z)
    1367           0 : { pari_sp av = avma; affii(divis(x,y),z); avma = av; }
    1368           0 : INLINE void divriz(GEN x, GEN y, GEN z)
    1369           0 : { pari_sp av = avma; affrr(divri(x,y),z); avma = av; }
    1370         390 : INLINE void divrrz(GEN x, GEN y, GEN z)
    1371         390 : { pari_sp av = avma; affrr(divrr(x,y),z); avma = av; }
    1372       90548 : INLINE void divrsz(GEN y, long s, GEN z)
    1373       90548 : { pari_sp av = avma; affrr(divrs(y,s),z); avma = av; }
    1374           0 : INLINE void divsiz(long x, GEN y, GEN z)
    1375           0 : { long junk; affsi(sdivsi_rem(x,y,&junk), z); }
    1376           0 : INLINE void divsrz(long s, GEN y, GEN z)
    1377           0 : { pari_sp av = avma; mpaff(divsr(s,y),z); avma = av; }
    1378           0 : INLINE void divssz(long x, long y, GEN z)
    1379           0 : { affsi(x/y, z); }
    1380             : 
    1381           0 : INLINE void modisz(GEN y, long s, GEN z)
    1382           0 : { affsi(smodis(y,s),z); }
    1383           0 : INLINE void modsiz(long s, GEN y, GEN z)
    1384           0 : { pari_sp av = avma; affii(modsi(s,y),z); avma = av; }
    1385           0 : INLINE void modssz(long s, long y, GEN z)
    1386           0 : { affsi(smodss(s,y),z); }
    1387             : 
    1388           0 : INLINE void mpaddz(GEN x, GEN y, GEN z)
    1389           0 : { pari_sp av = avma; mpaff(mpadd(x,y),z); avma = av; }
    1390           0 : INLINE void mpsubz(GEN x, GEN y, GEN z)
    1391           0 : { pari_sp av = avma; mpaff(mpsub(x,y),z); avma = av; }
    1392           0 : INLINE void mpmulz(GEN x, GEN y, GEN z)
    1393           0 : { pari_sp av = avma; mpaff(mpmul(x,y),z); avma = av; }
    1394             : 
    1395           0 : INLINE void muliiz(GEN x, GEN y, GEN z)
    1396           0 : { pari_sp av = avma; affii(mulii(x,y),z); avma = av; }
    1397           0 : INLINE void mulirz(GEN x, GEN y, GEN z)
    1398           0 : { pari_sp av = avma; mpaff(mulir(x,y),z); avma = av; }
    1399           0 : INLINE void mulriz(GEN x, GEN y, GEN z)
    1400           0 : { pari_sp av = avma; mpaff(mulri(x,y),z); avma = av; }
    1401       56940 : INLINE void mulrrz(GEN x, GEN y, GEN z)
    1402       56940 : { pari_sp av = avma; affrr(mulrr(x,y),z); avma = av; }
    1403           0 : INLINE void mulsiz(long s, GEN y, GEN z)
    1404           0 : { pari_sp av = avma; affii(mulsi(s,y),z); avma = av; }
    1405           0 : INLINE void mulsrz(long s, GEN y, GEN z)
    1406           0 : { pari_sp av = avma; mpaff(mulsr(s,y),z); avma = av; }
    1407           0 : INLINE void mulssz(long s, long y, GEN z)
    1408           0 : { pari_sp av = avma; affii(mulss(s,y),z); avma = av; }
    1409             : 
    1410           0 : INLINE void remiiz(GEN x, GEN y, GEN z)
    1411           0 : { pari_sp av = avma; affii(remii(x,y),z); avma = av; }
    1412           0 : INLINE void remisz(GEN y, long s, GEN z)
    1413           0 : { pari_sp av = avma; affii(remis(y,s),z); avma = av; }
    1414           0 : INLINE void remsiz(long s, GEN y, GEN z)
    1415           0 : { pari_sp av = avma; affii(remsi(s,y),z); avma = av; }
    1416           0 : INLINE void remssz(long s, long y, GEN z)
    1417           0 : { pari_sp av = avma; affii(remss(s,y),z); avma = av; }
    1418             : 
    1419           0 : INLINE void subiiz(GEN x, GEN y, GEN z)
    1420           0 : { pari_sp av = avma; affii(subii(x,y),z); avma = av; }
    1421           0 : INLINE void subirz(GEN x, GEN y, GEN z)
    1422           0 : { pari_sp av = avma; affrr(subir(x,y),z); avma = av; }
    1423           0 : INLINE void subisz(GEN y, long s, GEN z)
    1424           0 : { pari_sp av = avma; affii(addsi(-s,y),z); avma = av; }
    1425           0 : INLINE void subriz(GEN x, GEN y, GEN z)
    1426           0 : { pari_sp av = avma; affrr(subri(x,y),z); avma = av; }
    1427     1295880 : INLINE void subrrz(GEN x, GEN y, GEN z)
    1428     1295880 : { pari_sp av = avma; affrr(subrr(x,y),z); avma = av; }
    1429           0 : INLINE void subrsz(GEN y, long s, GEN z)
    1430           0 : { pari_sp av = avma; affrr(addsr(-s,y),z); avma = av; }
    1431           0 : INLINE void subsiz(long s, GEN y, GEN z)
    1432           0 : { pari_sp av = avma; affii(subsi(s,y),z); avma = av; }
    1433           0 : INLINE void subsrz(long s, GEN y, GEN z)
    1434           0 : { pari_sp av = avma; affrr(subsr(s,y),z); avma = av; }
    1435           0 : INLINE void subssz(long x, long y, GEN z) { addssz(x,-y,z); }
    1436             : 
    1437             : INLINE void
    1438           0 : dvmdssz(long x, long y, GEN z, GEN t) {
    1439           0 :   pari_sp av = avma;
    1440             :   long r;
    1441           0 :   affii(divss_rem(x,y, &r), z); avma = av; affsi(r,t);
    1442           0 : }
    1443             : INLINE void
    1444           0 : dvmdsiz(long x, GEN y, GEN z, GEN t) {
    1445           0 :   pari_sp av = avma;
    1446             :   long r;
    1447           0 :   affii(divsi_rem(x,y, &r), z); avma = av; affsi(r,t);
    1448           0 : }
    1449             : INLINE void
    1450           0 : dvmdisz(GEN x, long y, GEN z, GEN t) {
    1451           0 :   pari_sp av = avma;
    1452             :   long r;
    1453           0 :   affii(divis_rem(x,y, &r),z); avma = av; affsi(r,t);
    1454           0 : }
    1455             : INLINE void
    1456           0 : dvmdiiz(GEN x, GEN y, GEN z, GEN t) {
    1457           0 :   pari_sp av = avma;
    1458             :   GEN r;
    1459           0 :   affii(dvmdii(x,y,&r),z); affii(r,t); avma=av;
    1460           0 : }

Generated by: LCOV version 1.13