Пример #1
0
unsigned long long int acml_time()
{
  memcpy(x_1,t_x,sizeof(doublecomplex)*N);
  memcpy(y_1,t_y,sizeof(doublecomplex)*N);

  clock_gettime(CLOCK_MONOTONIC,&begin);
  zswap(N,x_1,incx,y_1,incy);
  clock_gettime(CLOCK_MONOTONIC,&end);

  unsigned long long int time = 1000000000L*(end.tv_sec - begin.tv_sec) + end.tv_nsec - begin.tv_nsec;
  printf("%32lld",time);
  return time;
}
Пример #2
0
void zsvdc(dcomplex *x, int ldx, int n, int p, dcomplex *s, dcomplex *e,
           dcomplex *u, int ldu, dcomplex *v, int ldv, dcomplex *work, 
           int job, int *info)
{
/*
      complex*16 x(ldx,1),s(1),e(1),u(ldu,1),v(ldv,1),work(1)
*/
    int i,iter,j,jobu,k,kase,kk,l,ll,lls,lm1,lp1,ls,lu,m,maxit,
             mm,mm1,mp1,nct,nctp1,ncu,nrt,nrtp1;
    dcomplex t,r;
    double  b,c,cs,el,emm1,f,g,scale,shift,sl,sm,sn,
                      smm1,t1,test,ztest;
    int wantu,wantv;

    /*
     * adjust arrays
     */
    s--;
    e--;
    work--;
    
    /*
     *     set the maximum number of iterations.
     */
    maxit = 30;
    /*
     *     determine what is to be computed.
     */
    wantu = FALSE;
    wantv = FALSE;
    jobu = (job % 100)/10;
    ncu = n;
    if (jobu > 1) 
        ncu = min(n,p);
    if (jobu != 0) 
        wantu = TRUE;
    if ((job % 10) != 0) 
        wantv = TRUE;
    /*
     *     reduce x to bidiagonal form, storing the diagonal elements
     *     in s and the super-diagonal elements in e.
     */
    *info = 0;
    nct = min(n-1,p);
    nrt = min(p-2,n);
    nrt = max(0,nrt);
    lu  = max(nct,nrt);
    if (lu >= 1) { 
        for (l = 1;l <= lu;l++) {
            lp1 = l + 1;
            if (l <= nct) { 
                /*
                 *   compute the transformation for the l-th column and
                 *   place the l-th diagonal in s(l).
                 */
                s[l] = Complex_d(dznrm2(n-l+1,&(X(l,l)),1), 0.0);
                if (cabs1(s[l]) != 0.0) { 
                   if (cabs1(X(l,l)) != 0.0) 
                       s[l] = csign(s[l],X(l,l));
                   zscal(n-l+1,zinv(s[l]),&(X(l,l)),1);
                   X(l,l) = Cadd_d(Complex_d(1.0,0.0), X(l,l));
                } 
                s[l] = DCmul_d(-1.0,s[l]);
            } 
            if (p >= lp1) {
                for (j = lp1;j <= p; j++) {
                    if (!((l > nct) || (cabs1(s[l]) == 0.0))) { 
                        /*
                         *  apply the transformation.
                         */
                        t = Cdiv_d(DCmul_d(-1.0,zdotc(n-l+1,&(X(l,l)),1,&(X(l,j)),1)),X(l,l));
                        zaxpy(n-l+1,t,&(X(l,l)),1,&(X(l,j)),1);
                    } 
                    /*
                     *       place the l-th row of x into  e for the
                     *       subsequent calculation of the row transformation.
                     */
                    e[j] = Conjg_d(X(l,j));
                }
            } 
            if (wantu && l <= nct) { 
                /*
                 *   place the transformation in u for subsequent back
                 *   multiplication.
                 */
                for (i = l;i <= n;i++)
                    U(i,l) = X(i,l);

            } 
            if (l <= nrt) { 
                /*
                 *   compute the l-th row transformation and place the
                 *   l-th super-diagonal in e(l).
                 */
                e[l] = Complex_d(dznrm2(p-l,&(e[lp1]),1),0.0);
                if (cabs1(e[l]) != 0.0) {
                    if (cabs1(e[lp1]) != 0.0) 
                        e[l] = csign(e[l],e[lp1]);
                    zscal(p-l,zinv(e[l]),&(e[lp1]),1);
                    e[lp1] = Cadd_d(Complex_d(1.0,0.0), e[lp1]);
                } 
                e[l] = DCmul_d(-1.0,Conjg_d(e[l]));
                if (lp1 <= n && cabs1(e[l]) != 0.0) { 
                    /*
                     *   apply the transformation.
                     */
                    for (i = lp1;i<= n;i++)
                        work[i] = Complex_d(0.0,0.0);
                    for (j = lp1;j<= p;j++)
                        zaxpy(n-l,e[j],&(X(lp1,j)),1,&(work[lp1]),1);
                    for (j = lp1;j<= p;j++)
                        zaxpy(n-l,Conjg_d(Cdiv_d(DCmul_d(-1.0,e[j]),e[lp1])),
                              &(work[lp1]),1,&(X(lp1,j)),1);
                } 
                if (wantv) 
                    /*
                     *   place the transformation in v for subsequent
                     *   back multiplication.
                     */
                    for (i = lp1;i<= p;i++)
                        V(i,l) = e[i];
            }
        }
    }
    /*
     *     set up the final bidiagonal matrix or order m.
     */
    m = min(p,n+1);
    nctp1 = nct + 1;
    nrtp1 = nrt + 1;
    if (nct < p) 
        s[nctp1] = X(nctp1,nctp1);
    if (n < m) 
        s[m] = Complex_d(0.0,0.0);
    if (nrtp1 < m) 
        e[nrtp1] = X(nrtp1,m);
    e[m] = Complex_d(0.0,0.0);
    /*
     *     if required, generate u.
     */
    if (wantu) {
        if (ncu >= nctp1) { 
            for (j = nctp1;j<= ncu;j++) {
                for (i = 1;i<= n;i++)
                    U(i,j) = Complex_d(0.0,0.0);
                U(j,j) = Complex_d(1.0,0.0);
            }
        } 
        if (nct >= 1) {
            for (ll = 1;ll<= nct;ll++) {
                l = nct - ll + 1;
                if (cabs1(s[l]) == 0.0) {
                    for (i = 1;i<= n;i++)
                        U(i,l) = Complex_d(0.0,0.0);
                    U(l,l) = Complex_d(1.0,0.0);
                }
                else {
                    lp1 = l + 1;
                    if (ncu >= lp1) {
                        for (j = lp1;j<=ncu;j++) {
                            t = DCmul_d(-1.0,Cdiv_d(zdotc(n-l+1,&(U(l,l)),1,&(U(l,j)),1),U(l,l)));
                            zaxpy(n-l+1,t,&(U(l,l)),1,&(U(l,j)),1);
                        }
                    } 
                    zscal(n-l+1,Complex_d(-1.0,0.0),&(U(l,l)),1);
                    U(l,l) = Cadd_d(Complex_d(1.0,0.0), U(l,l));
                    lm1 = l - 1;
                    if (lm1 >= 1) 
                        for (i = 1;i<= lm1;i++)
                            U(i,l) = Complex_d(0.0,0.0);
                }
            }
        }
    }
    /*  
     *     if it is required, generate v.
     */
    if (wantv) {
        for (ll = 1;ll<= p;ll++) {
            l = p - ll + 1;
            lp1 = l + 1;
            if ((l <= nrt) && (cabs1(e[l]) != 0.0)) {
                for (j = lp1;j<= p;j++) {
                    dcomplex dc,dd;
                    dc = zdotc(p-l,&(V(lp1,l)),1,&(V(lp1,j)),1);
                    dd = V(lp1,l);
                    t = Cdiv_d(DCmul_d(-1.0,dc),dd);
                    zaxpy(p-l,t,&(V(lp1,l)),1,&(V(lp1,j)),1);
                }
            }
            for (i = 1;i<= p;i++)
                V(i,l) = Complex_d(0.0,0.0);
            V(l,l) = Complex_d(1.0,0.0);
        }
    }
    /*
     *     transform s and e so that they are double precision.
     */
    for (i = 1;i<= m;i++) {
        if (cabs1(s[i]) != 0.0) { 
            t = Complex_d(Cabs_d(s[i]),0.0);
            r = Cdiv_d(s[i],t);
            s[i] = t;
            if (i < m) 
                e[i] = Cdiv_d(e[i],r);
            if (wantu) 
                zscal(n,r,&(U(1,i)),1);
        } 
        /*
         *     ...exit
         */
        if (i == m) 
            break; 
        if (cabs1(e[i]) != 0.0) {
            t = Complex_d(Cabs_d(e[i]),0.0);
            r = Cdiv_d(t,e[i]);
            e[i] = t;
            s[i+1] = Cmul_d(s[i+1],r);
            if (wantv) 
                zscal(p,r,&(V(1,i+1)),1);
        }
    } 
    /*
     *     main iteration loop for the singular values.
     */
    mm = m;
    iter = 0;
    while (1) { 
        /*
         *        quit if all the singular values have been found.
         *
         *     ...exit
         */
        if (m == 0) {
            break; 
        }
        /*
         *        if too many iterations have been performed, set
         *        flag and return.
         */
        if (iter >= maxit) {
            *info = m;
            /*
             *     ......exit
             */
            break; 
        } 
        /*
         *    this section of the program inspects for
         *    negligible elements in the s and e arrays.  on
         *    completion the variables kase and l are set as follows.
         *
         *       kase = 1     if s[m] and e(l-1) are negligible and l<m
         *       kase = 2     if s(l) is negligible and l<m
         *       kase = 3     if e(l-1) is negligible, l<m, and
         *                    s(l), ..., s[m] are not negligible (qr step).
         *       kase = 4     if e(m-1) is negligible (convergence).
         */
        for (ll = 1;ll<= m;ll++) {
            l = m - ll;
            if (l == 0) 
                break; 
            test = Cabs_d(s[l]) + Cabs_d(s[l+1]);
            ztest = test + Cabs_d(e[l]);
            if (ztest == test) { 
                e[l] = Complex_d(0.0,0.0);
                break;
            }
        }
        if (l == m - 1) {
            kase = 4;
        }
        else {
            lp1 = l + 1;
            mp1 = m + 1;
            for (lls = lp1;lls<= mp1;lls++) {
                ls = m - lls + lp1;
                if (ls == l) 
                    break;
                test = 0.0;
                if (ls != m) 
                    test += Cabs_d(e[ls]);
                if (ls != l + 1) 
                    test += Cabs_d(e[ls-1]);
                ztest = test + Cabs_d(s[ls]);
                if (ztest == test) { 
                    s[ls] = Complex_d(0.0,0.0);
                    break;
                } 
            } 
            if (ls == l) { 
                kase = 3;
            }
            else {
                if (ls == m) { 
                    kase = 1;
                }
                else {
                    kase = 2;
                    l = ls;
                }
            }  
        } 
        l++;
        /*
         *        perform the task indicated by kase.
         */
        switch (kase) {
        /*
         *        deflate negligible s[m].
         */
        case 1 :   
            mm1 = m - 1;
            f = e[m-1].r;
            e[m-1] = Complex_d(0.0,0.0);
            for (kk = l;kk<= mm1;kk++) {
                k = mm1 - kk + l;
                t1 = s[k].r;
                drotg(&t1,&f,&cs,&sn);
                s[k] = Complex_d(t1,0.0);
                if (k != l) {
                    f = -sn * e[k-1].r;
                    e[k-1] = DCmul_d(cs, e[k-1]);
                }
                if (wantv) 
                    zdrot(p,&(V(1,k)),1,&(V(1,m)),1,cs,sn);
            }
            break; 
            /*
             *        split at negligible s(l).
             */
        case 2 :   
            f = e[l-1].r;
            e[l-1] = Complex_d(0.0,0.0);
            for (k = l;k<= m;k++) {
                t1 = s[k].r;
                drotg(&t1,&f,&cs,&sn);
                s[k] = Complex_d(t1,0.0);
                f = -sn*e[k].r;
                e[k] = DCmul_d(cs,e[k]);
                if (wantu) 
                    zdrot(n,&(U(1,k)),1,&(U(1,l-1)),1,cs,sn);
            }
            break; 
            /*
             *        perform one qr step.
             */
        case 3 :   
            /*
             *        calculate the shift.
             */
            scale = dmax1(Cabs_d(s[m]),Cabs_d(s[m-1]),Cabs_d(e[m-1]),
                          Cabs_d(s[l]),Cabs_d(e[l]));
            sm    = s[m].r/scale;
            smm1  = s[m-1].r/scale;
            emm1  = e[m-1].r/scale;
            sl    = s[l].r/scale;
            el    = e[l].r/scale;
            b     = ((smm1 + sm)*(smm1 - sm) + emm1*emm1)/2.0;
            c     = pow(sm*emm1,2);
            shift = 0.0;
            if (b != 0.0 || c != 0.0) { 
                shift = sqrt(b*b+c);
                if (b < 0.0) 
                    shift = -shift;
                shift = c/(b + shift);
            } 
            f = (sl + sm)*(sl - sm) + shift;
            g = sl*el;
            /*
             *           chase zeros.
             */
            mm1 = m - 1;
            for (k = l;k<= mm1;k++) {
                drotg(&f,&g,&cs,&sn);
                if (k != l) 
                    e[k-1] = Complex_d(f,0.0);
                f = cs * s[k].r + sn * e[k].r;
                e[k] = Csub_d(DCmul_d(cs,e[k]), DCmul_d(sn,s[k]));
                g = sn * s[k+1].r;
                s[k+1] = DCmul_d(cs,s[k+1]);
                if (wantv) 
                    zdrot(p,&(V(1,k)),1,&(V(1,k+1)),1,cs,sn);
                drotg(&f,&g,&cs,&sn);
                s[k] = Complex_d(f,0.0);
                f = cs * e[k].r + sn * s[k+1].r;
                s[k+1] = Cadd_d(DCmul_d(-sn,e[k]), DCmul_d(cs,s[k+1]));
                g = sn * e[k+1].r;
                e[k+1] = DCmul_d(cs,e[k+1]);
                if (wantu && k < n)
                    zdrot(n,&(U(1,k)),1,&(U(1,k+1)),1,cs,sn);
            }
            e[m-1] = Complex_d(f,0.0);
            iter++;
            break; 
            /*
             *        convergence.
             */
        case 4 :    
            /*
             *           make the singular value  positive
             */
            if (s[l].r < 0.0) {
               s[l] = DCmul_d(-1.0,s[l]);
               if (wantv) 
                   zscal(p,Complex_d(-1.0,0.0),&(V(1,l)),1);
            }
            /*
             *           order the singular value.
             */
            while (l != mm) {
               if (s[l].r >= s[l+1].r) 
                   break;  
               t = s[l];
               s[l] = s[l+1];
               s[l+1] = t;
               if (wantv && l < p)
                   zswap(p,&(V(1,l)),1,&(V(1,l+1)),1);
               if (wantu && l < n)
                   zswap(n,&(U(1,l)),1,&(U(1,l+1)),1);
               l++;
            } 
            iter = 0;
            m--;
        } 
    }     
}
Пример #3
0
int
main(void)
{
	/* static because otherwise it would have to be volatile yeilding a lot of stupid
	 * warnings. auto variables are not guaranteed to be readable after a long jump. */
	static z_t a, b, c, d, _0, _1, _2, _3;
	static char buf[2000];
	static int ret = 0;
	static jmp_buf env, env2;
	static size_t n;

#define BUF_N (sizeof(buf) - 1)

	if (setjmp(env)) {
		zperror(0);
		ret = 2;
		goto done;
	}

	zsetup(env);
	zinit(a), zinit(b), zinit(c), zinit(d), zinit(_0), zinit(_1), zinit(_2), zinit(_3);

	zsetu(_0, 0);
	zsetu(_1, 1);
	zsetu(_2, 2);
	zsetu(_3, 3);

	assert(zeven(_0), == 1);
	assert(zodd(_0), == 0);
	assert(zzero(_0), == 1);
	assert(zsignum(_0), == 0);
	assert(zeven(_1), == 0);
	assert(zodd(_1), == 1);
	assert(zzero(_1), == 0);
	assert(zsignum(_1), == 1);
	assert(zeven(_2), == 1);
	assert(zodd(_2), == 0);
	assert(zzero(_2), == 0);
	assert(zsignum(_2), == 1);

	zswap(_1, _2);
	assert(zeven(_2), == 0);
	assert(zodd(_2), == 1);
	assert(zzero(_2), == 0);
	assert(zsignum(_2), == 1);
	assert(zeven(_1), == 1);
	assert(zodd(_1), == 0);
	assert(zzero(_1), == 0);
	assert(zsignum(_1), == 1);
	zswap(_2, _1);
	assert(zeven(_1), == 0);
	assert(zodd(_1), == 1);
	assert(zzero(_1), == 0);
	assert(zsignum(_1), == 1);
	assert(zeven(_2), == 1);
	assert(zodd(_2), == 0);
	assert(zzero(_2), == 0);
	assert(zsignum(_2), == 1);

	assert((zneg(_2, _2), zsignum(_2)), == -1); zneg(_2, _2);
	assert(zsignum(_2), == 1);

	assert(zcmp(_0, _0), == 0);
	assert(zcmp(_1, _1), == 0);
	assert(zcmp(_0, _1), < 0);
	assert(zcmp(_1, _0), > 0);
	assert(zcmp(_1, _2), < 0);
	assert(zcmp(_2, _1), > 0);
	assert(zcmp(_0, _2), < 0);
	assert(zcmp(_2, _0), > 0);

	zbset(a, _0, 0, 1);
	assert(zcmp(a, _1), == 0);
	zbset(a, a, 1, 1);
	assert(zcmp(a, _3), == 0);
	zbset(a, a, 0, 0);
	assert(zcmp(a, _2), == 0);
	zbset(a, a, 0, 0);
	assert(zcmp(a, _2), == 0);
	zbset(a, a, 0, -1);
	assert(zcmp(a, _3), == 0);
	zbset(a, a, 0, -1);
	assert(zcmp(a, _2), == 0);

	zadd(a, _0, _1);
	assert(zsignum(a), == 1);
	assert(zcmp(a, _1), == 0);
	assert(zcmpi(a, 1), == 0);
	assert(zcmpu(a, 1), == 0);
	zneg(a, a);
	assert(zsignum(a), == -1);
	assert(zcmp(a, _1), < 0);
	assert(zcmpi(a, 1), < 0);
	assert(zcmpu(a, 1), < 0);
	zadd(a, _2, _0);
	assert(zsignum(a), == 1);
	assert(zcmp(a, _2), == 0);
	assert(zcmpi(a, 2), == 0);
	assert(zcmpu(a, 2), == 0);
	zneg(a, a);
	assert(zsignum(a), == -1);
	assert(zcmp(a, _2), < 0);
	assert(zcmpi(a, 2), < 0);
	assert(zcmpu(a, 2), < 0);
	assert(zsignum(_1), == 1);
	zadd(a, _1, _1);
	assert(zsignum(a), == 1);
	assert(zcmp(a, _2), == 0);
	assert(zcmpi(a, 2), == 0);
	assert(zcmpu(a, 2), == 0);
	zset(b, _1);
	zadd(a, b, _1);
	assert(zsignum(a), == 1);
	assert(zcmp(a, _2), == 0);
	assert(zcmpi(a, 2), == 0);
	assert(zcmpu(a, 2), == 0);
	zneg(a, a);
	zset(b, _2);
	zneg(b, b);
	assert(zsignum(a), == -1);
	assert(zcmp(a, b), == 0);
	assert(zcmp(a, _2), < 0);
	assert(zcmpmag(a, b), == 0);
	assert(zcmpmag(a, _2), == 0);
	assert(zcmpi(a, 2), < 0);
	assert(zcmpu(a, 2), < 0);
	assert(zcmpi(a, -2), == 0);
	assert((zneg(_2, _2), zcmp(a, _2)), == 0); zneg(_2, _2);
	zadd(a, _1, _2);
	assert(zsignum(a), == 1);
	assert(zcmp(a, _2), > 0);
	assert(zcmpi(a, 2), > 0);
	assert(zcmpu(a, 2), > 0);
	zneg(a, a);
	zset(b, _2);
	zneg(b, b);
	assert(zsignum(a), == -1);
	assert(zcmpmag(a, _2), > 0);
	assert(zcmpmag(a, b), > 0);
	assert(zcmp(a, b), < 0);
	assert(zcmp(a, _2), < 0);
	assert(zcmpi(a, 2), < 0);
	assert(zcmpu(a, 2), < 0);
	assert(zcmpi(a, -2), < 0);
	assert((zneg(_2, _2), zcmp(a, _2)), < 0); zneg(_2, _2);
	zneg(b, _3);
	assert(zcmp(a, b), == 0);

	zunsetup();
	zsetup(env);

	zsub(a, _2, _1);
	assert(zcmpmag(_2, _1), > 0);
	assert(zcmpmag(_2, _0), > 0);
	assert(zcmpmag(_1, _0), > 0);
	zsub(b, _1, _2);
	assert(zcmpmag(_2, _0), > 0);
	assert(zcmpmag(_1, _0), > 0);
	assert(zcmpmag(_2, _1), > 0);
	assert(zcmpmag(a, b), == 0);
	assert(zcmpmag(a, _1), == 0);
	assert(zcmp(a, b), > 0);
	assert(zcmp(a, _1), == 0);
	assert(zcmp(b, _1), < 0);
	zsub(a, _1, _1);
	assert(zcmp(a, _0), == 0);
	zseti(b, 0);
	zsetu(c, 0);
	zsub(a, b, c);
	assert(zcmp(a, _0), == 0);
	assert(zcmpmag(_2, _1), > 0);
	assert(zcmp(_2, _1), > 0);
	zsub(a, _2, _1);
	assert(zsignum(a), == 1);
	assert(zcmpmag(a, _1), == 0);
	assert(zcmp(a, _1), == 0);
	zsub(a, a, _1);
	assert(zcmp(a, _0), == 0);
	zsub(a, a, _0);
	assert(zcmp(a, _0), == 0);
	zsub(a, _1, _2);
	assert(zcmp(a, _1), < 0);
	assert(zcmpmag(a, _1), == 0);
	zabs(a, a);
	assert(zcmp(a, _1), == 0);
	zabs(a, a);
	assert(zcmp(a, _1), == 0);
	zabs(a, _1);
	assert(zcmp(a, _1), == 0);
	zabs(a, _0);
	assert(zcmp(a, _0), == 0);

	zseti(b, -1);
	zseti(c, -2);
	zadd(a, _0, b);
	assert(zcmp(a, _0), < 0);
	assert(zcmpi(a, -1), == 0);
	assert(zcmpmag(a, _1), == 0);
	assert(zcmp(a, _1), < 0);
	zadd(a, b, _0);
	assert(zcmp(a, _0), < 0);
	assert(zcmpi(a, -1), == 0);
	assert(zcmpmag(a, _1), == 0);
	assert(zcmp(a, _1), < 0);
	zadd(a, b, c);
	assert(zcmp(a, c), < 0);
	assert(zcmpmag(a, _2), > 0);
	zadd(a, c, b);
	assert(zcmp(a, c), < 0);
	assert(zcmpmag(a, _2), > 0);
	zadd(a, b, _1);
	assert(zcmp(a, _0), == 0);
	assert(zcmpmag(a, _0), == 0);
	zadd(a, _1, b);
	assert(zcmp(a, _0), == 0);
	assert(zcmpmag(a, _0), == 0);

	zneg(b, _1);
	zneg(c, _2);
	zsub(a, _0, b);
	assert(zcmp(a, _1), == 0);
	zsub(a, b, _0);
	assert(zcmpmag(a, _1), == 0);
	assert(zcmp(a, _1), < 0);
	zsub(a, b, c);
	assert(zcmpmag(a, _1), == 0);
	assert(zcmp(a, _1), == 0);
	zsub(a, c, b);
	assert(zcmpmag(a, _1), == 0);
	assert(zcmp(a, _1), < 0);
	zsub(a, b, _1);
	assert(zcmpmag(a, _2), == 0);
	assert(zcmp(a, _2), < 0);
	assert(zcmp(a, c), == 0);
	zsub(a, _1, b);
	assert(zcmp(b, _1), < 0);
	assert(zcmpmag(b, _1), == 0);
	assert(zcmp(a, _2), == 0);

	zsetu(a, 1000);
	zsetu(b, 0);
	assert(zcmp(a, b), != 0);
	n = zsave(a, buf);
	assert(n > 0, > 0);
	assert_zu(zload(b, buf), n);
	assert(zcmp(a, b), == 0);

	zneg(b, _1);
	zneg(c, _2);

	assert((zadd_unsigned(a, _1, _2), zcmp(a, _3)), == 0);
	assert((zadd_unsigned(a, b, c), zcmp(a, _3)), == 0);
	assert((zadd_unsigned(a, b, _2), zcmp(a, _3)), == 0);
	assert((zadd_unsigned(a, _1, c), zcmp(a, _3)), == 0);

	assert((zadd_unsigned(a, _0, _0), zcmp(a, _0)), == 0);
	assert((zadd_unsigned(a, _0, _1), zcmp(a, _1)), == 0);
	assert((zadd_unsigned(a, _1, _1), zcmp(a, _2)), == 0);
	assert((zadd_unsigned(a, _1, _0), zcmp(a, _1)), == 0);
	zneg(_1, _1);
	assert((zadd_unsigned(a, _0, _0), zcmp(a, _0)), == 0);
	assert((zadd_unsigned(a, _0, _1), zcmp(a, _1)), != 0);
	assert((zadd_unsigned(a, _0, _1), zcmpmag(a, _1)), == 0);
	assert((zadd_unsigned(a, _1, _1), zcmp(a, _2)), == 0);
	assert((zadd_unsigned(a, _1, _0), zcmp(a, _1)), != 0);
	assert((zadd_unsigned(a, _1, _0), zcmpmag(a, _1)), == 0);
	zneg(_1, _1);

	assert((zsub_unsigned(a, _2, _1), zcmp(a, _1)), == 0);
	assert((zsub_unsigned(a, _2, b), zcmp(a, _1)), == 0);
	assert((zsub_unsigned(a, c, _1), zcmp(a, _1)), == 0);
	assert((zsub_unsigned(a, c, b), zcmp(a, _1)), == 0);

	assert((zsub_unsigned(a, _1, _2), zcmp(a, b)), == 0);
	assert((zsub_unsigned(a, b, _2), zcmp(a, b)), == 0);
	assert((zsub_unsigned(a, _1, c), zcmp(a, b)), == 0);
	assert((zsub_unsigned(a, b, c), zcmp(a, b)), == 0);

	assert_zu(zbits(_0), 1);
	assert_zu(zbits(_1), 1);
	assert_zu(zbits(_2), 2);
	assert_zu(zbits(_3), 2);

	assert_zu(zlsb(_0), SIZE_MAX);
	assert_zu(zlsb(_1), 0);
	assert_zu(zlsb(_2), 1);
	assert_zu(zlsb(_3), 0);

	assert((zand(a, _0, _0), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zand(a, _0, _1), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zand(a, _0, _2), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zand(a, _0, _3), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zand(a, _1, _1), zcmp(a, _1)), == 0);
	assert((zand(a, _1, _2), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zand(a, _1, _3), zcmp(a, _1)), == 0);
	assert((zand(a, _2, _2), zcmp(a, _2)), == 0);
	assert((zand(a, _2, _3), zcmp(a, _2)), == 0);
	assert((zand(a, _3, _3), zcmp(a, _3)), == 0);

	assert((zor(a, _0, _0), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zor(a, _0, _1), zcmp(a, _1)), == 0);
	assert((zor(a, _0, _2), zcmp(a, _2)), == 0);
	assert((zor(a, _0, _3), zcmp(a, _3)), == 0);
	assert((zor(a, _1, _1), zcmp(a, _1)), == 0);
	assert((zor(a, _1, _2), zcmp(a, _3)), == 0);
	assert((zor(a, _1, _3), zcmp(a, _3)), == 0);
	assert((zor(a, _2, _2), zcmp(a, _2)), == 0);
	assert((zor(a, _2, _3), zcmp(a, _3)), == 0);
	assert((zor(a, _3, _3), zcmp(a, _3)), == 0);

	assert((zxor(a, _0, _0), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zxor(a, _0, _1), zcmp(a, _1)), == 0);
	assert((zxor(a, _0, _2), zcmp(a, _2)), == 0);
	assert((zxor(a, _0, _3), zcmp(a, _3)), == 0);
	assert((zxor(a, _1, _1), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zxor(a, _1, _2), zcmp(a, _3)), == 0);
	assert((zxor(a, _1, _3), zcmp(a, _2)), == 0);
	assert((zxor(a, _2, _2), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zxor(a, _2, _3), zcmp(a, _1)), == 0);
	assert((zxor(a, _3, _3), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);

	zneg(b, _1);
	zneg(c, _3);
	zneg(_1, _1);
	zand(a, b, c);
	assert(zcmpmag(a, _1), == 0);
	assert(zcmp(a, _1), == 0);
	zneg(_1, _1);
	assert((zand(a, b, _3), zcmp(a, _1)), == 0);
	assert((zand(a, _1, c), zcmp(a, _1)), == 0);
	assert((zand(a, _0, c), zcmp(a, _0)), == 0);
	assert((zand(a, b, _0), zcmp(a, _0)), == 0);

	zneg(b, _1);
	zneg(c, _2);
	zneg(_3, _3);
	zor(a, b, c);
	assert(zcmpmag(a, _3), == 0);
	assert(zcmp(a, _3), == 0);
	zor(a, b, _2);
	assert(zcmpmag(a, _3), == 0);
	assert(zcmp(a, _3), == 0);
	zor(a, _1, c);
	assert((zcmpmag(a, _3)), == 0);
	assert((zcmp(a, _3)), == 0);
	assert((zor(a, _0, c), zcmp(a, c)), == 0);
	assert((zor(a, b, _0), zcmp(a, b)), == 0);
	zneg(_3, _3);

	zneg(b, _1);
	zneg(c, _2);
	zxor(a, b, c);
	assert(zcmpmag(a, _3), == 0);
	assert(zcmp(a, _3), == 0);
	zneg(_3, _3);
	zxor(a, b, _2);
	assert(zcmpmag(a, _3), == 0);
	assert(zcmp(a, _3), == 0);
	zxor(a, _1, c);
	assert(zcmpmag(a, _3), == 0);
	assert(zcmp(a, _3), == 0);
	zxor(a, b, _0);
	assert(zcmpmag(a, b), == 0);
	assert(zcmp(a, b), == 0);
	zxor(a, _0, c);
	assert(zcmpmag(a, c), == 0);
	assert(zcmp(a, c), == 0);
	zneg(_3, _3);

	assert((zlsh(a, _0, 0), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zlsh(a, _0, 1), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zlsh(a, _1, 0), zcmp(a, _1)), == 0);
	assert((zlsh(a, _1, 1), zcmp(a, _2)), == 0);
	assert((zlsh(a, _1, 2), zcmp(a, _2)), > 0);
	assert((zlsh(a, _2, 0), zcmp(a, _2)), == 0);
	assert((zlsh(a, _2, 1), zcmp(a, _2)), > 0);

	zset(a, _0);
	assert((zlsh(a, a, 0), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zlsh(a, a, 1), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	zset(a, _1);
	assert((zlsh(a, a, 0), zcmp(a, _1)), == 0);
	assert((zlsh(a, a, 1), zcmp(a, _2)), == 0);
	assert((zlsh(a, a, 2), zcmp(a, _2)), > 0);
	zset(a, _2);
	assert((zlsh(a, a, 0), zcmp(a, _2)), == 0);
	assert((zlsh(a, a, 1), zcmp(a, _2)), > 0);

	assert((zrsh(a, _0, 0), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zrsh(a, _0, 1), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zrsh(a, _1, 0), zcmp(a, _1)), == 0);
	assert((zrsh(a, _1, 1), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zrsh(a, _1, 2), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zrsh(a, _2, 0), zcmp(a, _2)), == 0);
	assert((zrsh(a, _2, 1), zcmp(a, _1)), == 0);
	assert((zrsh(a, _2, 2), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);

	zset(a, _0);
	assert((zrsh(a, a, 0), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zrsh(a, a, 1), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	zset(a, _1);
	assert((zrsh(a, a, 0), zcmp(a, _1)), == 0);
	assert((zrsh(a, a, 1), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	assert((zrsh(a, a, 2), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);
	zset(a, _2);
	assert((zrsh(a, a, 0), zcmp(a, _2)), == 0);
	assert((zrsh(a, a, 1), zcmp(a, _1)), == 0);
	assert((zrsh(a, a, 2), zcmp(a, _0)), == 0);
	assert(zzero(a), == 1);

	assert(zbtest(_0, 0), == 0);
	assert(zbtest(_1, 0), == 1);
	assert(zbtest(_2, 0), == 0);
	assert(zbtest(_3, 0), == 1);
	assert(zbtest(_0, 1), == 0);
	assert(zbtest(_1, 1), == 0);
	assert(zbtest(_2, 1), == 1);
	assert(zbtest(_3, 1), == 1);
	assert(zbtest(_0, 2), == 0);
	assert(zbtest(_1, 2), == 0);
	assert(zbtest(_2, 2), == 0);
	assert(zbtest(_3, 2), == 0);

	znot(a, _2);
	assert(zcmpmag(a, _1), == 0);
	assert(zcmp(a, _1), != 0);
	znot(a, a);
	assert(zcmp(a, _0), == 0);

	zsetu(a, 0x1234);
	zsetu(c, 0x234);
	ztrunc(a, a, 12);
	assert(zcmp(a, c), == 0);

	zsetu(a, 0xEEFF);
	zsetu(c, 0xEE);
	zsetu(d, 0xFF);
	zsplit(a, b, a, 8);
	assert(zcmpmag(a, c), == 0);
	assert(zcmpmag(b, d), == 0);
	zsetu(a, 0xEEFF);
	zsplit(b, a, a, 8);
	assert(zcmpmag(b, c), == 0);
	assert(zcmpmag(a, d), == 0);

	zmul(a, _2, _3);
	assert(zcmpi(a, 6), == 0);
	zneg(_3, _3);
	zmul(a, _2, _3);
	assert(zcmpi(a, -6), == 0);
	zneg(_3, _3);
	zneg(_2, _2);
	zmul(a, _2, _3);
	assert(zcmpi(a, -6), == 0);
	zneg(_3, _3);
	zmul(a, _2, _3);
	assert(zcmpi(a, 6), == 0);
	zneg(_3, _3);
	zneg(_2, _2);

	zmul(a, _3, _3);
	assert(zcmpi(a, 9), == 0);
	zsqr(a, _3);
	assert(zcmpi(a, 9), == 0);
	zneg(_3, _3);
	zmul(a, _3, _3);
	assert(zcmpi(a, 9), == 0);
	zsqr(a, _3);
	assert(zcmpi(a, 9), == 0);
	zneg(_3, _3);

	zseti(a, 8);
	zseti(b, 2);
	zdiv(c, a, b);
	assert(zcmpi(c, 4), == 0);
	zseti(b, -2);
	zdiv(c, a, b);
	assert(zcmpi(c, -4), == 0);
	zseti(a, -8);
	zseti(b, 2);
	zdiv(c, a, b);
	assert(zcmpi(c, -4), == 0);
	zseti(b, -2);
	zdiv(c, a, b);
	assert(zcmpi(c, 4), == 0);

	zseti(a, 1000);
	zseti(b, 10);
	zdiv(c, a, b);
	assert(zcmpi(c, 100), == 0);
	zseti(b, -10);
	zdiv(c, a, b);
	assert(zcmpi(c, -100), == 0);
	zseti(a, -1000);
	zseti(b, 10);
	zdiv(c, a, b);
	assert(zcmpi(c, -100), == 0);
	zseti(b, -10);
	zdiv(c, a, b);
	assert(zcmpi(c, 100), == 0);

	zseti(a, 7);
	zseti(b, 3);
	zmod(c, a, b);
	assert(zcmpi(c, 1), == 0);
	zseti(b, -3);
	zmod(c, a, b);
	assert(zcmpi(c, 1), == 0);
	zseti(a, -7);
	zseti(b, 3);
	zmod(c, a, b);
	assert(zcmpi(c, -1), == 0);
	zseti(b, -3);
	zmod(c, a, b);
	assert(zcmpi(c, -1), == 0);

	zseti(a, 7);
	zseti(b, 3);
	zdivmod(d, c, a, b);
	assert(zcmpi(d, 2), == 0);
	assert(zcmpi(c, 1), == 0);
	zseti(b, -3);
	zdivmod(d, c, a, b);
	assert(zcmpi(d, -2), == 0);
	assert(zcmpi(c, 1), == 0);
	zseti(a, -7);
	zseti(b, 3);
	zdivmod(d, c, a, b);
	assert(zcmpi(d, -2), == 0);
	assert(zcmpi(c, -1), == 0);
	zseti(b, -3);
	zdivmod(d, c, a, b);
	assert(zcmpi(d, 2), == 0);
	assert(zcmpi(c, -1), == 0);

	zseti(a, 10);
	zseti(b, -1);
	zpow(a, a, b);
	assert(zcmp(a, _0), == 0);

	zseti(a, 10);
	zseti(b, -1);
	zseti(a, 20);
	zmodpow(a, a, b, c);
	assert(zcmp(a, _0), == 0);

	zseti(a, 10);
	zseti(c, 100000L);
	zpowu(a, a, 5);
	assert(zcmpmag(a, c), == 0);
	assert(zcmp(a, c), == 0);

	zseti(a, -10);
	zseti(c, -100000L);
	zpowu(a, a, 5);
	assert(zcmpmag(a, c), == 0);
	assert(zcmp(a, c), == 0);

	zseti(a, -10);
	zseti(c, 10000L);
	zpowu(a, a, 4);
	assert(zcmpmag(a, c), == 0);
	assert(zcmp(a, c), == 0);

	zseti(a, 10);
	zseti(c, 3);
	zmodpowu(a, a, 5, c);
	assert(zcmpmag(a, _1), == 0);
	assert(zcmp(a, _1), == 0);

	zseti(a, 10);
	zseti(b, 5);
	zseti(c, 100000L);
	zpow(a, a, b);
	assert(zcmpmag(a, c), == 0);
	assert(zcmp(a, c), == 0);

	zseti(a, -10);
	zseti(b, 5);
	zseti(c, -100000L);
	zpow(a, a, b);
	assert(zcmpmag(a, c), == 0);
	assert(zcmp(a, c), == 0);

	zseti(a, -10);
	zseti(b, 4);
	zseti(c, 10000L);
	zpow(a, a, b);
	assert(zcmpmag(a, c), == 0);
	assert(zcmp(a, c), == 0);

	zseti(a, 10);
	zseti(b, 5);
	zseti(c, 3);
	zmodpow(a, a, b, c);
	assert(zcmpmag(a, _1), == 0);
	assert(zcmp(a, _1), == 0);

	zseti(a, 102);
	zseti(b, 501);
	zseti(c, 5);
	zmodmul(a, a, b, c);
	assert(zcmp(a, _2), == 0);

	zseti(b, 2 * 3 * 3 * 7);
	zseti(c, 3 * 7 * 11);
	zseti(d, 3 * 7);
	assert((zgcd(a, _0, _0), zcmp(a, _0)), == 0);
	assert((zgcd(a, b, _0), zcmp(a, b)), == 0);
	assert((zgcd(a, _0, c), zcmp(a, c)), == 0);
	assert((zgcd(a, b, b), zcmp(a, b)), == 0);
	assert((zgcd(a, b, _2), zcmp(a, _2)), == 0);
	assert((zgcd(a, _2, b), zcmp(a, _2)), == 0);
	assert((zgcd(a, _2, _2), zcmp(a, _2)), == 0);
	assert((zgcd(a, c, _2), zcmp(a, _1)), == 0);
	assert((zgcd(a, _2, c), zcmp(a, _1)), == 0);
	assert((zgcd(a, b, _1), zcmp(a, _1)), == 0);
	assert((zgcd(a, _1, c), zcmp(a, _1)), == 0);
	assert((zgcd(a, _1, _1), zcmp(a, _1)), == 0);
	assert((zgcd(a, b, c), zcmp(a, d)), == 0);
	assert((zgcd(a, c, b), zcmp(a, d)), == 0);

	zsets(a, "1234");
	assert(zcmpi(a, 1234), == 0);
	zsets(b, "+1234");
	assert(zcmp(a, b), == 0);
	assert_zu(zstr_length(_0, 10), 1);
	assert_zu(zstr_length(_1, 10), 1);
	assert_zu(zstr_length(_2, 10), 1);
	assert_zu(zstr_length(_3, 10), 1);
	zneg(_2, _2);
	assert_zu(zstr_length(_2, 10), 2);
	zneg(_2, _2);
	assert_zu(zstr_length(a, 10), 4);
	zstr(a, buf, 0);
	assert_s(buf, "1234");
	zsets(a, "-1234");
	zseti(b, -1234);
	zseti(c, 1234);
	assert(zcmp(a, _0), < 0);
	assert(zcmp(a, b), == 0);
	assert(zcmpmag(a, c), == 0);
	assert(zcmp(a, c), < 0);
	zstr(a, buf, 0);
	assert_s(buf, "-1234");
	assert_s(zstr(a, buf, 0), "-1234");

	zsetu(d, 100000UL);
	zrand(a, FAST_RANDOM, UNIFORM, d);
	assert(zcmp(a, _0), >= 0);
	assert(zcmp(a, d), <= 0);
	zrand(b, SECURE_RANDOM, UNIFORM, d);
	assert(zcmp(b, _0), >= 0);
	assert(zcmp(b, d), <= 0);
	zrand(c, FASTEST_RANDOM, UNIFORM, d);
	assert(zcmp(c, _0), >= 0);
	assert(zcmp(c, d), <= 0);
	assert(zcmp(a, b), != 0);
	assert(zcmp(a, c), != 0);
	assert(zcmp(b, c), != 0);

	zsetu(d, 100000UL);
	zrand(a, DEFAULT_RANDOM, QUASIUNIFORM, d);
	assert(zcmp(a, _0), >= 0);
	assert(zcmp(a, d), <= 0);
	zrand(b, DEFAULT_RANDOM, QUASIUNIFORM, d);
	assert(zcmp(b, _0), >= 0);
	assert(zcmp(b, d), <= 0);
	zrand(c, DEFAULT_RANDOM, QUASIUNIFORM, d);
	assert(zcmp(c, _0), >= 0);
	assert(zcmp(c, d), <= 0);
	assert(zcmp(a, b), != 0);
	assert(zcmp(a, c), != 0);
	assert(zcmp(b, c), != 0);

	zsetu(d, 100000UL);
	zrand(a, DEFAULT_RANDOM, MODUNIFORM, d);
	assert(zcmp(a, _0), >= 0);
	assert(zcmp(a, d), <= 0);
	zrand(b, DEFAULT_RANDOM, MODUNIFORM, d);
	assert(zcmp(b, _0), >= 0);
	assert(zcmp(b, d), <= 0);
	zrand(c, DEFAULT_RANDOM, MODUNIFORM, d);
	assert(zcmp(c, _0), >= 0);
	assert(zcmp(c, d), <= 0);
	assert(zcmp(a, b), != 0);
	assert(zcmp(a, c), != 0);
	assert(zcmp(b, c), != 0);

	assert((zseti(a, -5), zptest(0, a, 100)), == NONPRIME);
	assert((zseti(a, -4), zptest(0, a, 100)), == NONPRIME);
	assert((zseti(a, -3), zptest(0, a, 100)), == NONPRIME);
	assert((zseti(a, -2), zptest(0, a, 100)), == NONPRIME);
	assert((zseti(a, -1), zptest(0, a, 100)), == NONPRIME);
	assert((zseti(a, 0), zptest(0, a, 100)), == NONPRIME);
	assert((zseti(a, 1), zptest(0, a, 100)), == NONPRIME);
	assert((zseti(a, 2), zptest(0, a, 100)), == PRIME);
	assert((zseti(a, 3), zptest(0, a, 100)), == PRIME);
	assert((zseti(a, 4), zptest(0, a, 100)), == NONPRIME);
	assert((zseti(a, 5), zptest(0, a, 100)), != NONPRIME);
	assert((zseti(a, 6), zptest(0, a, 100)), == NONPRIME);
	assert((zseti(a, 7), zptest(0, a, 100)), != NONPRIME);
	assert((zseti(a, 8), zptest(0, a, 100)), == NONPRIME);
	assert((zseti(a, 9), zptest(0, a, 100)), == NONPRIME);
	assert((zseti(a, 10), zptest(0, a, 100)), == NONPRIME);
	assert((zseti(a, 11), zptest(0, a, 100)), != NONPRIME);
	assert((zseti(a, 101), zptest(0, a, 100)), != NONPRIME);

#if defined(ZAHL_UNSAFE)
	(void) env2;
#else
	assert_nr(zdivmod(a, b, _0, _0));
	assert_nr(zdivmod(a, b, _1, _0));
	zdivmod(a, b, _0, _1);
	zdivmod(a, b, _1, _1);
	assert_nr(zdiv(a, _0, _0));
	assert_nr(zdiv(a, _1, _0));
	zdiv(a, _0, _1);
	zdiv(a, _1, _1);
	assert_nr(zmod(a, _0, _0));
	assert_nr(zmod(a, _1, _0));
	zmod(a, _0, _1);
	zmod(a, _1, _1);
	assert_nr(zpow(a, _0, _0));
	assert_nr((zneg(_1, _1), zpow(a, _0, _1))); zneg(_1, _1);
	zpow(a, _0, _1);
	zpow(a, _1, _0);
	zneg(_1, _1), zpow(a, _1, _0), zneg(_1, _1);
	assert_nr(zmodmul(a, _1, _1, _0));
	assert_nr(zmodpow(a, _0, _0, _1));
	assert_nr((zneg(_1, _1), zmodpow(a, _0, _1, _1))); zneg(_1, _1);
	zmodpow(a, _0, _1, _1);
	zmodpow(a, _1, _0, _1);
	zneg(_1, _1), zmodpow(a, _1, _0, _1), zneg(_1, _1);
	assert_nr(zmodpow(a, _0, _0, _0));
	assert_nr((zneg(_1, _1), zmodpow(a, _0, _1, _0))); zneg(_1, _1);
	assert_nr(zmodpow(a, _0, _1, _0));
	assert_nr(zmodpow(a, _1, _0, _0));
	assert_nr((zneg(_1, _1), zmodpow(a, _1, _0, _0))); zneg(_1, _1);
	assert_nr(zpowu(a, _0, 0));
	zpowu(a, _0, 1);
	zpowu(a, _1, 0);
	zneg(_1, _1), zpowu(a, _1, 0), zneg(_1, _1);
	assert_nr(zmodpowu(a, _0, 0, _1));
	zmodpowu(a, _0, 1, _1);
	zmodpowu(a, _1, 0, _1);
	zneg(_1, _1), zmodpowu(a, _1, 0, _1), zneg(_1, _1);
	assert_nr(zmodpowu(a, _0, 0, _0));
	assert_nr((zneg(_1, _1), zmodpowu(a, _0, 1, _0))); zneg(_1, _1);
	assert_nr(zmodpowu(a, _0, 1, _0));
	assert_nr(zmodpowu(a, _1, 0, _0));
	assert_nr((zneg(_1, _1), zmodpowu(a, _1, 0, _0))); zneg(_1, _1);
	assert_nr(zstr_length(a, 0));
	assert_nr(zstr_length(a, 1));
	zstr_length(a, 2);
	zstr_length(a, 3);
#endif

	zsetu(a, 1LL);
	assert_s(zstr(a, buf, 1), "1");
	zsetu(a, 10LL);
	assert_s(zstr(a, buf, 2), "10");
	zsetu(a, 100LL);
	assert_s(zstr(a, buf, 3), "100");
	zsetu(a, 1000LL);
	assert_s(zstr(a, buf, 4), "1000");
	zsetu(a, 10000LL);
	assert_s(zstr(a, buf, BUF_N), "10000");
	zsetu(a, 100000LL);
	assert_s(zstr(a, buf, BUF_N), "100000");
	zsetu(a, 1000000LL);
	assert_s(zstr(a, buf, BUF_N), "1000000");
	zsetu(a, 10000000LL);
	assert_s(zstr(a, buf, BUF_N), "10000000");
	zsetu(a, 100000000LL);
	assert_s(zstr(a, buf, BUF_N), "100000000");
	zsetu(a, 999999999LL);
	assert_s(zstr(a, buf, BUF_N), "999999999");
	zsetu(a, 1000000000LL);
	assert_s(zstr(a, buf, BUF_N), "1000000000");
	zsetu(a, 1000000001LL);
	assert_s(zstr(a, buf, BUF_N), "1000000001");
	zsetu(a, 2000000000LL);
	assert_s(zstr(a, buf, BUF_N), "2000000000");
	zsetu(a, 2050000000LL);
	assert_s(zstr(a, buf, BUF_N), "2050000000");
	zsetu(a, 2100000000LL);
	assert_s(zstr(a, buf, BUF_N), "2100000000");
	zsetu(a, 2140000000LL);
	assert_s(zstr(a, buf, BUF_N), "2140000000");
	zsetu(a, 2147000000LL);
	assert_s(zstr(a, buf, BUF_N), "2147000000");
	zsetu(a, 2147483000LL);
	assert_s(zstr(a, buf, BUF_N), "2147483000");
	zsetu(a, 2147483640LL);
	assert_s(zstr(a, buf, BUF_N), "2147483640");
	zsetu(a, 2147483646LL);
	assert_s(zstr(a, buf, BUF_N), "2147483646");

	zseti(a, 2147483647LL);
	assert_s(zstr(a, buf, BUF_N), "2147483647");
	zseti(a, -2147483647LL);
	assert_s(zstr(a, buf, BUF_N), "-2147483647");
	zseti(a, -2147483647LL - 1LL);
	assert_s(zstr(a, buf, BUF_N), "-2147483648");

	zsetu(a, 2147483647ULL);
	assert_s(zstr(a, buf, BUF_N), "2147483647");
	zsetu(a, 2147483648ULL);
	assert_s(zstr(a, buf, BUF_N), "2147483648");
	zsetu(a, 2147483649ULL);
	assert_s(zstr(a, buf, BUF_N), "2147483649");

	zsetu(a, 3000000000ULL);
	assert_s(zstr(a, buf, BUF_N), "3000000000");
	zsetu(a, 3100000000ULL);
	assert_s(zstr(a, buf, BUF_N), "3100000000");
	zsetu(a, 3200000000ULL);
	assert_s(zstr(a, buf, BUF_N), "3200000000");
	zsetu(a, 3300000000ULL);
	assert_s(zstr(a, buf, BUF_N), "3300000000");
	zsetu(a, 3400000000ULL);
	assert_s(zstr(a, buf, BUF_N), "3400000000");
	zsetu(a, 3500000000ULL);
	assert_s(zstr(a, buf, BUF_N), "3500000000");
	zsetu(a, 3600000000ULL);
	assert_s(zstr(a, buf, BUF_N), "3600000000");
	zsetu(a, 3700000000ULL);
	assert_s(zstr(a, buf, BUF_N), "3700000000");
	zsetu(a, 3800000000ULL);
	assert_s(zstr(a, buf, BUF_N), "3800000000");
	zsetu(a, 3900000000ULL);
	assert_s(zstr(a, buf, BUF_N), "3900000000");
	zsetu(a, 3999999999ULL);
	assert_s(zstr(a, buf, BUF_N), "3999999999");
	zsetu(a, 4000000000ULL);
	assert_s(zstr(a, buf, BUF_N), "4000000000");
	zsetu(a, 4000000001ULL);
	assert_zu(zstr_length(a, 10), 10);
	assert_s(zstr(a, buf, BUF_N), "4000000001");

	zsetu(a, 4000000000ULL);
	zsetu(b, 4000000000ULL);
	zadd(c, a, a);
	zsets(d, "8000000000");
	assert(zcmp(c, d), == 0);
	zadd(c, a, b);
	assert(zcmp(c, d), == 0);
	zadd(c, c, a);
	zsets(d, "12000000000");
	assert(zcmp(c, d), == 0);
	zsub(c, c, a);
	zsets(d, "8000000000");
	assert(zcmp(c, d), == 0);
	zsub(c, c, a);
	zsets(d, "4000000000");
	assert(zcmp(c, d), == 0);
	zsets(d, "8000000000");
	zrsh(d, d, 1);
	assert(zcmp(c, d), == 0);
	zsets(a, "6234216714");
	zsets(b, "9424614147");
	zsets(d, "830476546");
	zand(c, a, b);
	assert(zcmp(c, d), == 0);
	zsets(a, "234216714");
	zsets(b, "9424614147");
	zsets(d, "9629466379");
	zor(c, a, b);
	assert(zcmp(c, d), == 0);
	zsets(a, "6234216714");
	zsets(b, "9424614147");
	zsets(d, "13997877769");
	zxor(c, a, b);
	assert(zcmp(c, d), == 0);
	zsets(a, "34216714");
	zsets(b, "9424614147");
	zsets(d, "9458821129");
	zxor(c, a, b);
	assert(zcmp(c, d), == 0);
	zsetu(a, 1000000000ULL);
	zsets(d, "1000000000000000000");
	zmul(c, a, a);
	assert(zcmp(c, d), == 0);
	zdiv(c, c, a);
	assert(zcmp(c, a), == 0);
	zsetu(a, 1000000000ULL);
	zsets(d, "1000000000000000000");
	zsqr(c, a);
	assert(zcmp(c, d), == 0);
	zsetu(a, 1000000000ULL);
	zmodpowu(c, a, 5, _3);
	assert(zcmpu(c, 1), == 0);
	zsetu(a, 1000000000ULL);
	zsets(d, "1");
	zpowu(c, a, 0);
	assert(zcmp(c, d), == 0);
	zsetu(a, 1000000000ULL);
	zsets(d, "1000000000");
	zpowu(c, a, 1);
	assert(zcmp(c, d), == 0);
	zsetu(a, 1000000000ULL);
	zsets(d, "1000000000000000000");
	zpowu(c, a, 2);
	assert(zcmp(c, d), == 0);
	zsetu(a, 1000000000ULL);
	zsets(b, "1000000000000000000");
	zsets(d, "1000000000000000000000000000");
	zmul(c, a, b);
	assert(zcmp(c, d), == 0);
	zsetu(a, 1000000000ULL);
	zsets(d, "1000000000000000000000000000");
	zmul(b, a, a);
	zmul(b, b, a);
	assert(zcmp(c, d), == 0);
	zsetu(a, 1000000000ULL);
	zsets(d, "1000000000000000000000000000");
	zpowu(c, a, 3);
	assert(zcmp(c, d), == 0);
	zsetu(a, 1000000000ULL);
	zsets(d, "1000000000000000000000000000000000000");
	zpowu(c, a, 4);
	assert(zcmp(c, d), == 0);
	zsetu(a, 1000000000ULL);
	zsets(d, "1000000000000000000000000000000000000000000000");
	zpowu(c, a, 5);
	assert(zcmp(c, d), == 0);

	zsetu(a, 4294967294ULL);
	assert_s(zstr(a, buf, BUF_N), "4294967294");
	zsetu(a, 4294967295ULL);
	assert_s(zstr(a, buf, BUF_N), "4294967295");
	zsetu(a, 4294967296ULL);
	assert_s(zstr(a, buf, BUF_N), "4294967296");
	zsetu(a, 4294967297ULL);
	assert_s(zstr(a, buf, BUF_N), "4294967297");

	zseti(a, 9223372036854775807LL);
	assert_s(zstr(a, buf, BUF_N), "9223372036854775807");
	zseti(a, -9223372036854775807LL);
	assert_s(zstr(a, buf, BUF_N), "-9223372036854775807");
	zseti(a, -9223372036854775807LL - 1LL);
	assert_s(zstr(a, buf, BUF_N), "-9223372036854775808");

	zsetu(a, 18446744073709551614ULL);
	assert_s(zstr(a, buf, BUF_N), "18446744073709551614");
	zsetu(a, 18446744073709551615ULL);
	assert_s(zstr(a, buf, BUF_N), "18446744073709551615");
	zadd(a, a, _1);
	assert_s(zstr(a, buf, BUF_N), "18446744073709551616");
	zadd(a, a, _1);
	assert_s(zstr(a, buf, BUF_N), "18446744073709551617");

	zsets(a, "1000000000000000000000000000000");
	assert_s(zstr(a, buf, BUF_N), "1000000000000000000000000000000");
	zsets(a, "+1000000000000000000000000000000");
	assert_s(zstr(a, buf, BUF_N), "1000000000000000000000000000000");
	zsets(a, "-1000000000000000000000000000000");
	assert_s(zstr(a, buf, BUF_N), "-1000000000000000000000000000000");

	zsetu(a, 1000000000000000ULL);
	zsqr(a, a);
	assert_s(zstr(a, buf, BUF_N), "1000000000000000000000000000000");

#include "test-random.c"

done:
	zfree(a), zfree(b), zfree(c), zfree(d), zfree(_0), zfree(_1), zfree(_2), zfree(_3);
	zunsetup();
	return ret;
}