Testing latest pari + WASM + node.js... and it works?! Wow.
License: GPL3
ubuntu2004
#line 2 "../src/kernel/none/add.c"1/* Copyright (C) 2002-2003 The PARI group.23This file is part of the PARI/GP package.45PARI/GP is free software; you can redistribute it and/or modify it under the6terms of the GNU General Public License as published by the Free Software7Foundation; either version 2 of the License, or (at your option) any later8version. It is distributed in the hope that it will be useful, but WITHOUT9ANY WARRANTY WHATSOEVER.1011Check the License for details. You should have received a copy of it, along12with the package; see the file 'COPYING'. If not, write to the Free Software13Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */1415INLINE GEN16icopy_sign(GEN x, long sx)17{18GEN y=icopy(x);19setsigne(y,sx);20return y;21}2223GEN24addsi_sign(long x, GEN y, long sy)25{26long sx,ly;27GEN z;2829if (!x) return icopy_sign(y, sy);30if (!sy) return stoi(x);31if (x<0) { sx=-1; x=-x; } else sx=1;32if (sx==sy)33{34z = adduispec(x,y+2, lgefint(y)-2);35setsigne(z,sy); return z;36}37ly=lgefint(y);38if (ly==3)39{40const long d = (long)(uel(y,2) - (ulong)x);41if (!d) return gen_0;42z=cgeti(3);43if (y[2] < 0 || d > 0) {44z[1] = evalsigne(sy) | evallgefint(3);45z[2] = d;46}47else {48z[1] = evalsigne(-sy) | evallgefint(3);49z[2] =-d;50}51return z;52}53z = subiuspec(y+2,x, ly-2);54setsigne(z,sy); return z;55}56GEN57addui_sign(ulong x, GEN y, long sy)58{59long ly;60GEN z;6162if (!x) return icopy_sign(y, sy);63if (!sy) return utoipos(x);64if (sy == 1) return adduispec(x,y+2, lgefint(y)-2);65ly=lgefint(y);66if (ly==3)67{68const ulong t = y[2];69if (x == t) return gen_0;70z=cgeti(3);71if (x < t) {72z[1] = evalsigne(-1) | evallgefint(3);73z[2] = t - x;74}75else {76z[1] = evalsigne(1) | evallgefint(3);77z[2] = x - t;78}79return z;80}81z = subiuspec(y+2,x, ly-2);82setsigne(z,-1); return z;83}8485/* return gen_0 when the sign is 0 */86GEN87addii_sign(GEN x, long sx, GEN y, long sy)88{89long lx,ly;90GEN z;9192if (!sx) return sy? icopy_sign(y, sy): gen_0;93if (!sy) return icopy_sign(x, sx);94lx = lgefint(x);95ly = lgefint(y);96if (sx==sy)97z = addiispec(x+2,y+2,lx-2,ly-2);98else99{ /* sx != sy */100long i = cmpiispec(x+2,y+2,lx-2,ly-2);101if (!i) return gen_0;102/* we must ensure |x| > |y| for subiispec */103if (i < 0) {104sx = sy;105z = subiispec(y+2,x+2,ly-2,lx-2);106}107else108z = subiispec(x+2,y+2,lx-2,ly-2);109}110setsigne(z,sx); return z;111}112113INLINE GEN114rcopy_sign(GEN x, long sx) { GEN y = rcopy(x); setsigne(y,sx); return y; }115116GEN117addir_sign(GEN x, long sx, GEN y, long sy)118{119long e, l, ly;120GEN z;121122if (!sx) return rcopy_sign(y, sy);123e = expo(y) - expi(x);124if (!sy)125{126if (e >= 0) return rcopy_sign(y, sy);127z = itor(x, nbits2prec(-e));128setsigne(z, sx); return z;129}130131ly = lg(y);132if (e > 0)133{134l = ly - divsBIL(e);135if (l < 3) return rcopy_sign(y, sy);136}137else l = ly + nbits2extraprec(-e);138z = (GEN)avma;139y = addrr_sign(itor(x,l), sx, y, sy);140ly = lg(y); while (ly--) *--z = y[ly];141set_avma((pari_sp)z); return z;142}143144static GEN145addsr_sign(long x, GEN y, long sy)146{147long e, l, ly, sx;148GEN z;149150if (!x) return rcopy_sign(y, sy);151if (x < 0) { sx = -1; x = -x; } else sx = 1;152e = expo(y) - expu(x);153if (!sy)154{155if (e >= 0) return rcopy_sign(y, sy);156if (sx == -1) x = -x;157return stor(x, nbits2prec(-e));158}159160ly = lg(y);161if (e > 0)162{163l = ly - divsBIL(e);164if (l < 3) return rcopy_sign(y, sy);165}166else l = ly + nbits2extraprec(-e);167z = (GEN)avma;168y = addrr_sign(stor(x,l), sx, y, sy);169ly = lg(y); while (ly--) *--z = y[ly];170set_avma((pari_sp)z); return z;171}172173GEN174addsr(long x, GEN y) { return addsr_sign(x, y, signe(y)); }175176GEN177subsr(long x, GEN y) { return addsr_sign(x, y, -signe(y)); }178179GEN180addrr_sign(GEN x, long sx, GEN y, long sy)181{182long lx, ex = expo(x);183long ly, ey = expo(y), e = ey - ex;184long i, j, lz, ez, m;185int extend, f2;186GEN z;187LOCAL_OVERFLOW;188189if (!sy)190{191if (!sx)192{193if (e > 0) ex = ey;194return real_0_bit(ex);195}196if (e >= 0) return real_0_bit(ey);197lz = nbits2prec(-e);198lx = lg(x); if (lz > lx) lz = lx;199z = cgetr(lz); while(--lz) z[lz] = x[lz];200setsigne(z,sx); return z;201}202if (!sx)203{204if (e <= 0) return real_0_bit(ex);205lz = nbits2prec(e);206ly = lg(y); if (lz > ly) lz = ly;207z = cgetr(lz); while (--lz) z[lz] = y[lz];208setsigne(z,sy); return z;209}210211if (e < 0) { swap(x,y); lswap(sx,sy); ey=ex; e=-e; }212/* now ey >= ex */213lx = lg(x);214ly = lg(y);215/* If exponents differ, need to shift one argument, here x. If216* extend = 1: extension of x,z by m < BIL bits (round to 1 word) */217/* in this case, lz = lx + d + 1, otherwise lx + d */218extend = 0;219if (e)220{221long d = dvmdsBIL(e, &m), l = ly-d;222if (l <= 2) return rcopy_sign(y, sy);223if (l > lx) { lz = lx + d + 1; extend = 1; }224else { lz = ly; lx = l; }225if (m)226{ /* shift x right m bits */227const pari_sp av = avma;228const ulong sh = BITS_IN_LONG-m;229GEN p1 = x; x = new_chunk(lx + lz + 1);230shift_right(x,p1,2,lx, 0,m);231if (extend) uel(x,lx) = uel(p1,lx-1) << sh;232set_avma(av); /* HACK: cgetr(lz) will not overwrite x */233}234}235else236{ /* d = 0 */237m = 0;238if (lx > ly) lx = ly;239lz = lx;240}241242if (sx == sy)243{ /* addition */244i = lz-1;245j = lx-1;246if (extend) {247ulong garde = addll(x[lx], y[i]);248if (m < 4) /* don't extend for few correct bits */249z = cgetr(--lz);250else251{252z = cgetr(lz);253z[i] = garde;254}255}256else257{258z = cgetr(lz);259z[i] = addll(x[j], y[i]); j--;260}261i--;262for (; j>=2; i--,j--) z[i] = addllx(x[j],y[i]);263if (overflow)264{265z[1] = 1; /* stops since z[1] != 0 */266for (;;) { z[i] = uel(y,i)+1; if (z[i--]) break; }267if (i <= 0)268{269shift_right(z,z, 2,lz, 1,1);270z[1] = evalsigne(sx) | evalexpo(ey+1); return z;271}272}273for (; i>=2; i--) z[i] = y[i];274z[1] = evalsigne(sx) | evalexpo(ey); return z;275}276277/* subtraction */278if (e) f2 = 1;279else280{281i = 2; while (i < lx && x[i] == y[i]) i++;282if (i==lx) return real_0_bit(ey+1 - prec2nbits(lx));283f2 = (uel(y,i) > uel(x,i));284}285/* result is nonzero. f2 = (y > x) */286i = lz-1; z = cgetr(lz);287if (f2)288{289j = lx-1;290if (extend) z[i] = subll(y[i], x[lx]);291else z[i] = subll(y[i], x[j--]);292for (i--; j>=2; i--) z[i] = subllx(y[i], x[j--]);293if (overflow) /* stops since y[1] != 0 */294for (;;) { z[i] = uel(y,i)-1; if (y[i--]) break; }295for (; i>=2; i--) z[i] = y[i];296sx = sy;297}298else299{300if (extend) z[i] = subll(x[lx], y[i]);301else z[i] = subll(x[i], y[i]);302for (i--; i>=2; i--) z[i] = subllx(x[i], y[i]);303}304305x = z+2; i = 0; while (!x[i]) i++;306lz -= i; z += i;307j = bfffo(z[2]); /* need to shift left by j bits to normalize mantissa */308ez = ey - (j | (i * BITS_IN_LONG));309if (extend)310{ /* z was extended by d+1 words [should be e bits = d words + m bits] */311/* not worth keeping extra word if less than 5 significant bits in there */312if (m - j < 5 && lz > 3)313{ /* shorten z */314ulong last = (ulong)z[--lz]; /* cancelled word */315316/* if we need to shift anyway, shorten from left317* If not, shorten from right, neutralizing last word of z */318if (j == 0)319/* stackdummy((pari_sp)(z + lz+1), (pari_sp)(z + lz)); */320z[lz] = evaltyp(t_VECSMALL) | _evallg(1);321else322{323GEN t = z;324z++; shift_left(z,t,2,lz-1, last,j);325}326if ((last<<j) & HIGHBIT)327{ /* round up */328i = lz-1;329while (++((ulong*)z)[i] == 0 && i > 1) i--;330if (i == 1) { ez++; z[2] = (long)HIGHBIT; }331}332}333else if (j) shift_left(z,z,2,lz-1, 0,j);334}335else if (j) shift_left(z,z,2,lz-1, 0,j);336z[1] = evalsigne(sx) | evalexpo(ez);337z[0] = evaltyp(t_REAL) | evallg(lz);338set_avma((pari_sp)z); return z;339}340341342