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

📄 bignum1.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
字号:
/* *	Copyright (c) 1982 Regents of the University of California */#ifndef lintstatic char sccsid[] = "@(#)bignum1.c 4.4 6/30/83";#endif not lint#include <errno.h>#include <stdio.h>#include "as.h"/* *	Construct a floating point number */Bignum as_atof(numbuf, radix, ovfp)	char	*numbuf;	int	radix;	Ovf	*ovfp;{	Bignum	number;	extern	int	errno;	double	atof();	number = Znumber;	errno = 0;	switch(radix){	case TYPF:	case TYPD:		number.num_tag = TYPD;		*ovfp = 0;		number.num_num.numFd_float.Fd_value = atof(numbuf);		break;	case TYPG:	case TYPH:		number = bigatof(numbuf, radix);		break;	}	if (errno == ERANGE && passno == 2){		yywarning("Floating conversion over/underflowed\n");	}	return(number);}/* *	Construct an integer. */Bignum as_atoi(ccp, radix, ovfp)	reg	char	*ccp;		/* character cp */		int	radix;		Ovf	*ovfp;{	reg	chptr	bcp;		chptr	tcp;	reg	int	i;		int	val;		Bignum	n_n;		Bignum	t_n;		int	sign;		Ovf	ovf;	ovf = 0;	sign = 0;	for (; *ccp; ccp++){		switch(*ccp){		case '0':		case '+':	continue;		case '-':	sign ^= 1;				continue;		}		break;	}	n_n = Znumber;	t_n = Znumber;	bcp = CH_FIELD(n_n); (void)numclear(bcp);	tcp = CH_FIELD(t_n); (void)numclear(tcp);	for (; *ccp; ccp++){		switch(*ccp){		case '8': case '9':			if (radix < 10)				goto done;			/*FALLTHROUGH*/		case '0': case '1': case '2': case '3': case '4':		case '5': case '6': case '7':			val = *ccp - '0';			break;		case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':			if (radix < 16)				goto done;			val = *ccp - 'A' + 10;			break;		case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':			if (radix < 16)				goto done;			val = *ccp - 'a' + 10;			break;		default:			goto done;		}		switch(radix){		case 8:			ovf |= numshift(3, bcp, bcp);			break;		case 16:			ovf |= numshift(4, bcp, bcp);			break;		case 10:			ovf |= numshift(1, tcp, bcp);			ovf |= numshift(3, bcp, bcp);			ovf |= numaddv(bcp, tcp, bcp);			break;		}		ovf |= numaddd(bcp, bcp, val);	}  done: ;	ovf |= posovf(bcp);	if (sign){		if (ovf & OVF_MAXINT) {			ovf &= ~(OVF_MAXINT | OVF_POSOVF);		} else {			ovf |= numnegate(bcp, bcp);		}	}	/*	 *	find the highest set unit of the number	 */	val = sign ? -1 : 0;	for (i = 0; i < CH_N; i++){		if (bcp[i] == val)			break;	}	{		static u_char tagtab[4][16] = {		{	TYPB,			TYPW,			TYPL, TYPL,			TYPQ, TYPQ, TYPQ, TYPQ,			TYPO, TYPO, TYPO, TYPO, TYPO, TYPO, TYPO, TYPO},		{	TYPW,			TYPL,			TYPQ, TYPQ,			TYPO, TYPO, TYPO, TYPO},		{   0   },		{	TYPL,			TYPQ,			TYPO, TYPO }		};		/*		 *	i indexes to the null chunk; make it point to the		 *	last non null chunk		 */		i -= 1;		if (i < 0)			i = 0;		n_n.num_tag = tagtab[HOC][i];		assert(n_n.num_tag != 0, "Botch width computation");	}	*ovfp = ovf;	return(n_n);}Ovf posovf(src)	reg	chptr	src;{	reg	int	i;	Ovf	overflow = 0;	if (src[HOC] & SIGNBIT)		overflow = OVF_POSOVF;	if (src[HOC] == SIGNBIT){		for (i = HOC - 1; i >= 0; --i){			if (src[i] != 0)				return(overflow);		}		overflow |= OVF_MAXINT;	}	return(overflow);}/* *	check if the number is clear */int isclear(dst)	reg	chptr	dst;{	return(!isunequal(dst, CH_FIELD(Znumber)));}int isunequal(src1, src2)	reg	chptr	src1, src2;{	reg	int	i;	i = CH_N;	do{		if (*src1++ != *src2++)			return(i);	}while(--i);	return(0);}Ovf numclear(dst)	reg	chptr	dst;{	reg	int	i;	i = CH_N;	do{		*dst++ = 0;	}while(--i);	return(0);}Ovf numshift(n, dst, src)		int	n;	reg	chptr	dst, src;{	reg	int	i;	reg	u_int	carryi, carryo;	reg	u_int	mask;	reg	u_int	value;	i = CH_N;	if (n == 0){		do{			*dst++ = *src++;		} while(--i);		return(0);	}	carryi = 0;	mask = ONES(n);	if (n > 0){		do{			value = *src++;			carryo = (value >> (CH_BITS - n)) & mask; 			value <<= n;			value &= ~mask;			*dst++ = value | carryi;			carryi = carryo;		} while (--i);		return(carryi ? OVF_LSHIFT : 0);	} else {		n = -n;		src += CH_N;		dst += CH_N;		do{			value = *--src;			carryo = value & mask; 			value >>= n;			value &= ONES(CH_BITS - n);			*--dst = value | carryi;			carryi = carryo << (CH_BITS - n);		} while (--i);		return(carryi ? OVF_LSHIFT : 0);	}}Ovf numaddd(dst, src1, val)	chptr	dst, src1;	int	val;{	static	Bignum	work;	work.num_uchar[0] = val;	return (numaddv(dst, src1, CH_FIELD(work)));}Ovf numaddv(dst, src1, src2)	reg	chptr	dst, src1, src2;{	reg	int	i;	reg	int	carry;	reg	u_int	A,B,value;	carry = 0;	i = CH_N;	do{		A = *src1++;		B = *src2++;		value = A + B + carry;		*dst++ = value;		carry = 0;		if (value < A || value < B)			carry = 1;	} while (--i);	return(carry ? OVF_ADDV : 0);}Ovf numnegate(dst, src)	chptr	dst, src;{	Ovf	ovf;	ovf = num1comp(dst, src) ;	ovf |= numaddd(dst, dst, 1);	return(ovf);}Ovf num1comp(dst, src)	reg	chptr	dst, src;{	reg	int	i;	i = CH_N;	do{		*dst++ = ~ *src++;	}while (--i);	return(0);}/* *	Determine if floating point numbers are *	capable of being represented as a one byte immediate literal constant *	If it is, then stuff the value into *valuep. *	argtype is how the instruction will interpret the number. */int slitflt(number, argtype, valuep)	Bignum	number;		/* number presented */	int	argtype;	/* what the instruction expects */	int	*valuep;{#define	EXPPREC 3#define	MANTPREC 3		int	mask;	reg	int	i;		Bignum	unpacked;		Ovf	ovf;	*valuep = 0;	if (!ty_float[argtype])		return(0);	unpacked = bignumunpack(number, &ovf);	assert(ovf == 0, "overflow in unpacking floating #!?");	if (unpacked.num_sign)		return(0);	if (unpacked.num_exponent < 0)		return(0);	if (unpacked.num_exponent > ONES(EXPPREC))		return(0);	for (i = 0; i < HOC; i++){		if (CH_FIELD(unpacked)[i])			return(0);	}	if ((CH_FIELD(unpacked)[HOC]) & ONES(CH_BITS - MANTPREC))		return(0);	*valuep = (unpacked.num_exponent & ONES(EXPPREC)) << MANTPREC;	mask = (CH_FIELD(unpacked)[HOC]) >> (CH_BITS - MANTPREC);	mask &= ONES(MANTPREC);	*valuep |= mask;	*valuep &= ONES(MANTPREC + EXPPREC);	return(1);}#ifndef STANDALONE/* *	Output a big number to txtfil *	Called only when passno == 2 * *	The conversion specifies the width of the number to be written out. *	The width is supplied from either an initialized data directive *	(for example .float, .double), or from the operand size *	defined by an operator. *	If the number is of type quad or octal, *	we just write it out; this allows one to specify bit *	patterns for floating point numbers. *	If the number is one of the floating types and the conversion *	is not the same type, then we complain, but do the conversion anyway. *	The conversion is strict. */bignumwrite(number, toconv)	Bignum	number;	int	toconv;		/* one of TYP[QO FDGH] */{	reg	u_int	*bp;	if (passno != 2)		return;	bp = &number.num_uint[0];	switch(number.num_tag){	case TYPB:	case TYPW:	case TYPL:	case TYPQ:	case TYPO:		number = intconvert(number, toconv);		break;	default:		number = floatconvert(number, toconv);		break;	}	bwrite((char *)bp, ty_nbyte[toconv], txtfil);}#endif STANDALONE

⌨️ 快捷键说明

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