xref: /csrg-svn/usr.bin/f77/libI77/fmtlib.c (revision 47943)
1*47943Sbostic /*-
2*47943Sbostic  * Copyright (c) 1980 The Regents of the University of California.
3*47943Sbostic  * All rights reserved.
42493Sdlw  *
5*47943Sbostic  * %sccs.include.proprietary.c%
623076Skre  */
723076Skre 
8*47943Sbostic #ifndef lint
9*47943Sbostic static char sccsid[] = "@(#)fmtlib.c	5.2 (Berkeley) 04/12/91";
10*47943Sbostic #endif /* not lint */
11*47943Sbostic 
1223076Skre /*
132493Sdlw  * integer to ascii conversion
144745Sdlw  *
154745Sdlw  * This code has been rearranged to produce optimized runtime code.
162493Sdlw  */
172493Sdlw 
182493Sdlw #include "fio.h"
192493Sdlw 
204745Sdlw static char	_digit[] = "0123456789abcdefghijklmnopqrstuvwxyz";
214745Sdlw static char	_icv_buf[MAXINTLENGTH+1];
224745Sdlw #define		_mask	0x7fffffff
232493Sdlw 
244745Sdlw char *
icvt(value,ndigit,sign)254745Sdlw icvt(value, ndigit, sign)
264745Sdlw long	value;
274745Sdlw int	*ndigit;
284745Sdlw int	*sign;
292493Sdlw {
304745Sdlw 	register long	val = value;
314745Sdlw 	register long	rad = radix;
324745Sdlw 	register char	*b = &_icv_buf[MAXINTLENGTH];
334745Sdlw 	register char	*d = _digit;
344745Sdlw 	register long	tmp1;
354745Sdlw 	register int	tmp2;
364745Sdlw 	long	rem;
374745Sdlw 	long	kludge;
382493Sdlw 
394745Sdlw 	if (val == 0)
404745Sdlw 	{
414745Sdlw 		*--b = '0';
424745Sdlw 		*sign = 0;
434745Sdlw 		*ndigit = 1;
444745Sdlw 		return(b);
452493Sdlw 	}
464745Sdlw 
474745Sdlw 	if (signit && (*sign = (val < 0)))	/* signed conversion */
482493Sdlw 	{
494745Sdlw 		/*
504745Sdlw 		 * It is necessary to do the first divide
514745Sdlw 		 * before the absolute value, for the case -2^31
524745Sdlw 		 *
534745Sdlw 		 * This is actually what is being done...
544745Sdlw 		 * tmp1 = (int)(val % rad);
554745Sdlw 		 * val /= rad;
564745Sdlw 		 * val = -val
574745Sdlw 		 * *--b = d[-tmp1];
584745Sdlw 		 */
594745Sdlw 		tmp1 = val / rad;
604745Sdlw 		*--b = d[(tmp1 * rad) - val];
614745Sdlw 		val = -tmp1;
622493Sdlw 	}
634745Sdlw 	else				/* unsigned conversion */
644745Sdlw 	{
654745Sdlw 		*sign = 0;
664745Sdlw 		if (val < 0)
674745Sdlw 		{	/* ALL THIS IS TO SIMULATE UNSIGNED LONG MOD & DIV */
684745Sdlw 			kludge = _mask - (rad - 1);
694745Sdlw 			val &= _mask;
704745Sdlw 			/*
714745Sdlw 			 * This is really what's being done...
724745Sdlw 			 * rem = (kludge % rad) + (val % rad);
734745Sdlw 			 * val = (kludge / rad) + (val / rad) + (rem / rad) + 1;
744745Sdlw 			 * *--b = d[rem % rad];
754745Sdlw 			 */
764745Sdlw 			tmp1 = kludge / rad;
774745Sdlw 			tmp2 = val / rad;
784745Sdlw 			rem = (kludge - (tmp1 * rad)) + (val - (tmp2 * rad));
794745Sdlw 			val = ++tmp1 + tmp2;
804745Sdlw 			tmp1 = rem / rad;
814745Sdlw 			val += tmp1;
824745Sdlw 			*--b = d[rem - (tmp1 * rad)];
832493Sdlw 		}
842493Sdlw 	}
854745Sdlw 
864745Sdlw 	while (val)
872493Sdlw 	{
884745Sdlw 		/*
894745Sdlw 		 * This is really what's being done ...
904745Sdlw 		 * *--b = d[val % rad];
914745Sdlw 		 * val /= rad;
924745Sdlw 		 */
934745Sdlw 		tmp1 = val / rad;
944745Sdlw 		*--b = d[val - (tmp1 * rad)];
954745Sdlw 		val = tmp1;
962493Sdlw 	}
974745Sdlw 
984745Sdlw 	*ndigit = (&_icv_buf[MAXINTLENGTH] - b);
994745Sdlw 	return(b);
1002493Sdlw }
101