⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 idigitvec.c

📁 Arithmetic for integers of almost unlimited size for C and C++. Developed and copyrighted by Ra
💻 C
字号:
/* Corrected DigitVecSri, TP, 27.01.95 *//* DigitVecAddCarry and DigitVecSubCarry removed, RD, 14.7.93 *//* Integer Version 2.1, DigitVecMultSub changed, RD, 30.4.93	*//* Integer Version 2.0, RD, 18.1.93	idigitvec.c	*//*	Sparc Version 8, RD, 11.2.93	*//* DigitVecSri: try to avoid memory access delay, RD, 15.2.93 */#include <iint.h>#include <idigit.h>/*******************************	First the standard DigitVec operations *********************************/DigitType  DigitVecAdd (sum, a, b, l)	DigitType *sum, *a, *b;	int l;     /*	sum[0..l-1] = a[0..l-1] + b[0..l-1]; return CARRY;   */     /* This notation means:	Add the integers represented by the vectors a and b,	write the lowest l digits of the result into the vector sum	and return the carry of this operation.     */{	DigitType accu, carry, tmp;	carry=0;	for ( ; l>0; l-- ) {		accu = *a++ + carry;		carry = (accu < carry);		tmp = *b++;		accu += tmp;		carry += (accu < tmp);		*sum++ = accu;	}	return carry;}		/* DigitVecAdd */DigitType  DigitVecSub (diff, a, b, l)	DigitType *diff, *a, *b;	int l;     /*	diff[0..l-1] = a[0..l-1] - b[0..l-1]; return CARRY;   */{	DigitType accu, carry, tmp;	carry=0;	for ( ; l>0; l-- ) {		tmp = *a++;		accu = tmp - carry;		carry = (accu > tmp);		tmp = accu - *b++;		carry += (tmp > accu);		*diff++ = tmp;	}	return carry;}		/* DigitVecSub */#define DDH (BitsPerDigit/2)#ifdef USE_C_DIGITVECMULTDigitType  DigitVecMult (res, a, m, l)	DigitType *res, *a, m;	int l;     /*	res[0..l-1] = a[0..l-1]*m; return CARRY;   */{       DigitType carry;        DigitType aa, low1, low2, tmp1, tmp2, tmp3;        DigitType ml, mh, al, ah;        ml = (m << DDH) >> DDH;        mh = m >> DDH;	carry=0;        for ( ; l>0; l--) {            aa = *a++;            al = (aa << DDH) >> DDH;            ah = aa >> DDH;            tmp1 = ml * al;            low2 = carry + tmp1;            carry = (low2 < carry);            tmp2 = ml * ah;            low1 = low2 + (tmp2 << DDH);            carry += (low1 < low2) + (tmp2 >> DDH);            tmp3 = mh * al;            low2 = low1 + (tmp3 << DDH);            carry += (low2 < low1) + (tmp3 >> DDH);            *res++ = low2;            carry += mh * ah;        }        return carry;}               /* DigitVecMult */#endif#ifdef USE_C_DIGITVECMULTADDDigitType  DigitVecMultAdd (res, a, m, l)	DigitType *res, *a, m;	int l;     /*	res[0..l-1] += a[0..l-1]*m; return CARRY;   */     /* Special function for multiple digit multiplication */{       DigitType carry;        DigitType aa, low1, low2, tmp1, tmp2, tmp3;        DigitType ml, mh, al, ah;        ml = (m << DDH) >> DDH;        mh = m >> DDH;	carry=0;        for ( ; l>0; l--) {            aa = *a++;            al = (aa << DDH) >> DDH;            ah = aa >> DDH;            low1  = carry + *res;            carry = (low1 < carry);            tmp1 = ml * al;            low2 = low1 + tmp1;            carry += (low2 < low1);            tmp2 = ml * ah;            low1 = low2 + (tmp2 << DDH);            carry += (low1 < low2) + (tmp2 >> DDH);            tmp3 = mh * al;            low2 = low1 + (tmp3 << DDH);            carry += (low2 < low1) + (tmp3 >> DDH);            *res++ = low2;            carry += mh * ah;        }        return carry;}               /* DigitVecMultAdd */#endif#ifdef USE_C_DIGITVECMULTSUBDigitType  DigitVecMultSub (res, a, m, l)	DigitType *res, *a, m;	int l;     /*	res[0..l-1] -= a[0..l-1]*m; return CARRY;   */     /* Special function for multiple digit division */{       DigitType carry;        DigitType aa, low1, low2, tmp1, tmp2, tmp3;        DigitType ml, mh, al, ah;        ml = (m << DDH) >> DDH;        mh = m >> DDH;	carry=0;        for ( ; l>0; l--) {            aa = *a++;            al = (aa << DDH) >> DDH;            ah = aa >> DDH;            tmp1 = ml * al;            low2 = carry + tmp1;            carry = (low2 < carry);            tmp2 = ml * ah;            low1 = low2 + (tmp2 << DDH);            carry += (low1 < low2) + (tmp2 >> DDH);            tmp3 = mh * al;            low2 = low1 + (tmp3 << DDH);            carry += (low2 < low1) + (tmp3 >> DDH);	    tmp1 = *res;	    low1 = tmp1 - low2;	    carry += (low1 > tmp1);            *res++ = low1;            carry += mh * ah;        }        return carry;}               /* DigitVecMultSub */#endifDigitType  DigitVecDiv (quot, a, d, l)	DigitType *quot, *a, d;	int l;     /*	quot[0..l-1] = a[0..l-1]/m; 	return a[0..l-1]%m;     */{       DigitType carry=0;        for (quot+=l, a+=l; l>0; l--)		carry=DigitDiv(--quot, carry, *--a, d);        return carry;}		/* DigitVec_div *//*******************************	Now some special DigitVec operations *********************************/void DigitVecCsubto (a, b, l)	DigitType *a, *b;	int l;        /* a[]-=b[l]; */{	DigitType carry, x, y;	carry=0;        for ( ; l>0; l--) {		x = *a;		y = x - carry;		carry = (y > x);		x = y - *b++;		carry += (x > y);		*a++ = x;	}        while (carry) {		x = *a;		y = x - carry;		carry = (y > x);		*a++ = y;	}}		/* DigitVecCsubto */int DigitVecCadd (sum, a, b, la, lb)	DigitType *sum, *a, *b;	int la, lb;	/* sum[]=a[la]+b[lb]; return sum->length */{       DigitType carry=0, accu, tmp;	int countmax;	if (la>lb) {		countmax=la;		la-=lb;	        for ( ; lb>0; lb--) {			accu = *a++ + carry;			carry = (accu < carry);			tmp = *b++;			accu += tmp;			carry += (accu < tmp);			*sum++ = accu;		}	        for ( ; la>0; la--) {			accu = *a++ + carry;			carry = (accu < carry);			*sum++ = accu;		}	} else {		countmax=lb;		lb-=la;	        for ( ; la>0; la--) {			accu = *a++ + carry;			carry = (accu < carry);			tmp = *b++;			accu += tmp;			carry += (accu < tmp);			*sum++ = accu;		}	        for ( ; lb>0; lb--) {			accu = *b++ + carry;			carry = (accu < carry);			*sum++ = accu;    	}	}	*sum = carry;	if (carry)		return countmax+1;	else		return countmax;}	/* DigitVecCadd */int DigitVecCsub (diff, a, b, la, lb)	DigitType *diff, *a, *b;	int la, lb;	/* diff[]=a[la]-b[lb]; return diff->length */{       DigitType carry=0, x, y;	int l=la-lb;	for ( ; lb>0; lb--) {		x = *a++;		y = x - carry;		carry = (y > x);		x = y - *b++;		carry += (x > y);		*diff++ = x;	}	while (carry) {		x = *a++;		y = x - carry;		carry = (y > x);		*diff++ = y;		l--;	}	for ( ; l>0; l--) {		*diff++=*a++;	}	diff--;	while ((la>0)&&(! *diff)) {		diff--;		la--;	}	return la;}	/* DigitVecCsub */BOOLEAN DigitVecSr1 (u, l) 	DigitType *u;	int l;	/* b=u[l]%2; u[l]/=2; return b; */{	DigitType b, bold, c;	u=u + l;	b=bold=0;	while(l) {		b=*--u;		c=b>>1;		c|=(bold<<(BitsPerDigit-1));		bold=b;		*u=c;		l--;	}	b&=1;	return (BOOLEAN) b;}		/* DigitVecSr1 */#ifdef USE_OLD_VECSRIvoid DigitVecSri (u, l, i)	DigitType *u;	int l, i;	/* b=u[l]%2^i; u[l]/=2^i; 	0<i<BitsPerDigit  */{	DigitType b, bold, c;	u=u + l;	bold=0;	while(l) {		b=*--u;		c=b>>i;		c|=(bold<<(BitsPerDigit-i));		bold=b;		*u=c;		l--;	}}		/* DigitVecSri */#elsevoid DigitVecSri (u, l, i)	DigitType *u;	int l, i;	/* b=u[l]%2^i; u[l]/=2^i; 	0<i<BitsPerDigit  */{	DigitType b, bold, c;	if ((!l) || (!i))		return;	u = u + l - 1;	b = *u;	bold=0;	l--;	while(l) {		c=b>>i;		c|=(bold<<(BitsPerDigit-i));		*u=c;		bold=b;		b=*--u;		l--;	}	c=b>>i;	c|=(bold<<(BitsPerDigit-i));	bold=b;	*u=c;}		/* DigitVecSri */#endif/*******************************	Now some general non-critical DigitVec operations *********************************/BOOLEAN DigitVecEq (a, b, l)	DigitType *a, *b;	int l;        /* return a[l]==b[l]; */{       for ( ; l>0; l--)                if (*a++ != *b++)                        return FALSE;        return TRUE;}BOOLEAN DigitVecGt (a, b, l)	DigitType *a, *b;	int l;        /* return a[l]>b[l] lexikographisch */{       for (a+=l, b+=l; l>0; l--) {		DigitType aa, bb;		aa=*--a;		bb=*--b;                if (aa > bb)                        return TRUE;                else if (aa < bb)                        return FALSE;	}        return FALSE;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -