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

📄 mpdiv.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include "os.h"#include <mp.h>#include "dat.h"// division ala knuth, seminumerical algorithms, pp 237-238// the numbers are stored backwards to what knuth expects so j// counts down rather than up.voidmpdiv(mpint *dividend, mpint *divisor, mpint *quotient, mpint *remainder){	int j, s, vn, sign;	mpdigit qd, *up, *vp, *qp;	mpint *u, *v, *t;	// divide bv zero	if(divisor->top == 0)		abort();	// quick check	if(mpmagcmp(dividend, divisor) < 0){		if(remainder != nil)			mpassign(dividend, remainder);		if(quotient != nil)			mpassign(mpzero, quotient);		return;	}	// D1: shift until divisor, v, has hi bit set (needed to make trial	//     divisor accurate)	qd = divisor->p[divisor->top-1];	for(s = 0; (qd & mpdighi) == 0; s++)		qd <<= 1;	u = mpnew((dividend->top+2)*Dbits + s);	if(s == 0 && divisor != quotient && divisor != remainder) {		mpassign(dividend, u);		v = divisor;	} else {		mpleft(dividend, s, u);		v = mpnew(divisor->top*Dbits);		mpleft(divisor, s, v);	}	up = u->p+u->top-1;	vp = v->p+v->top-1;	vn = v->top;	// D1a: make sure high digit of dividend is less than high digit of divisor	if(*up >= *vp){		*++up = 0;		u->top++;	}	// storage for multiplies	t = mpnew(4*Dbits);	qp = nil;	if(quotient != nil){		mpbits(quotient, (u->top - v->top)*Dbits);		quotient->top = u->top - v->top;		qp = quotient->p+quotient->top-1;	}	// D2, D7: loop on length of dividend	for(j = u->top; j > vn; j--){		// D3: calculate trial divisor		mpdigdiv(up-1, *vp, &qd);		// D3a: rule out trial divisors 2 greater than real divisor		if(vn > 1) for(;;){			memset(t->p, 0, 3*Dbytes);	// mpvecdigmuladd adds to what's there			mpvecdigmuladd(vp-1, 2, qd, t->p);			if(mpveccmp(t->p, 3, up-2, 3) > 0)				qd--;			else				break;		}		// D4: u -= v*qd << j*Dbits		sign = mpvecdigmulsub(v->p, vn, qd, up-vn);		if(sign < 0){			// D6: trial divisor was too high, add back borrowed			//     value and decrease divisor			mpvecadd(up-vn, vn+1, v->p, vn, up-vn);			qd--;		}		// D5: save quotient digit		if(qp != nil)			*qp-- = qd;		// push top of u down one		u->top--;		*up-- = 0;	}	if(qp != nil){		mpnorm(quotient);		if(dividend->sign != divisor->sign)			quotient->sign = -1;	}	if(remainder != nil){		mpright(u, s, remainder);	// u is the remainder shifted		remainder->sign = dividend->sign;	}	mpfree(t);	mpfree(u);	if(v != divisor)		mpfree(v);}

⌨️ 快捷键说明

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