xref: /csrg-svn/usr.bin/f77/libI77/fmtlib.c (revision 23076)
12493Sdlw /*
2*23076Skre  * Copyright (c) 1980 Regents of the University of California.
3*23076Skre  * All rights reserved.  The Berkeley software License Agreement
4*23076Skre  * specifies the terms and conditions for redistribution.
52493Sdlw  *
6*23076Skre  *	@(#)fmtlib.c	5.1	06/07/85
7*23076Skre  */
8*23076Skre 
9*23076Skre /*
102493Sdlw  * integer to ascii conversion
114745Sdlw  *
124745Sdlw  * This code has been rearranged to produce optimized runtime code.
132493Sdlw  */
142493Sdlw 
152493Sdlw #include "fio.h"
162493Sdlw 
174745Sdlw static char	_digit[] = "0123456789abcdefghijklmnopqrstuvwxyz";
184745Sdlw static char	_icv_buf[MAXINTLENGTH+1];
194745Sdlw #define		_mask	0x7fffffff
202493Sdlw 
214745Sdlw char *
224745Sdlw icvt(value, ndigit, sign)
234745Sdlw long	value;
244745Sdlw int	*ndigit;
254745Sdlw int	*sign;
262493Sdlw {
274745Sdlw 	register long	val = value;
284745Sdlw 	register long	rad = radix;
294745Sdlw 	register char	*b = &_icv_buf[MAXINTLENGTH];
304745Sdlw 	register char	*d = _digit;
314745Sdlw 	register long	tmp1;
324745Sdlw 	register int	tmp2;
334745Sdlw 	long	rem;
344745Sdlw 	long	kludge;
352493Sdlw 
364745Sdlw 	if (val == 0)
374745Sdlw 	{
384745Sdlw 		*--b = '0';
394745Sdlw 		*sign = 0;
404745Sdlw 		*ndigit = 1;
414745Sdlw 		return(b);
422493Sdlw 	}
434745Sdlw 
444745Sdlw 	if (signit && (*sign = (val < 0)))	/* signed conversion */
452493Sdlw 	{
464745Sdlw 		/*
474745Sdlw 		 * It is necessary to do the first divide
484745Sdlw 		 * before the absolute value, for the case -2^31
494745Sdlw 		 *
504745Sdlw 		 * This is actually what is being done...
514745Sdlw 		 * tmp1 = (int)(val % rad);
524745Sdlw 		 * val /= rad;
534745Sdlw 		 * val = -val
544745Sdlw 		 * *--b = d[-tmp1];
554745Sdlw 		 */
564745Sdlw 		tmp1 = val / rad;
574745Sdlw 		*--b = d[(tmp1 * rad) - val];
584745Sdlw 		val = -tmp1;
592493Sdlw 	}
604745Sdlw 	else				/* unsigned conversion */
614745Sdlw 	{
624745Sdlw 		*sign = 0;
634745Sdlw 		if (val < 0)
644745Sdlw 		{	/* ALL THIS IS TO SIMULATE UNSIGNED LONG MOD & DIV */
654745Sdlw 			kludge = _mask - (rad - 1);
664745Sdlw 			val &= _mask;
674745Sdlw 			/*
684745Sdlw 			 * This is really what's being done...
694745Sdlw 			 * rem = (kludge % rad) + (val % rad);
704745Sdlw 			 * val = (kludge / rad) + (val / rad) + (rem / rad) + 1;
714745Sdlw 			 * *--b = d[rem % rad];
724745Sdlw 			 */
734745Sdlw 			tmp1 = kludge / rad;
744745Sdlw 			tmp2 = val / rad;
754745Sdlw 			rem = (kludge - (tmp1 * rad)) + (val - (tmp2 * rad));
764745Sdlw 			val = ++tmp1 + tmp2;
774745Sdlw 			tmp1 = rem / rad;
784745Sdlw 			val += tmp1;
794745Sdlw 			*--b = d[rem - (tmp1 * rad)];
802493Sdlw 		}
812493Sdlw 	}
824745Sdlw 
834745Sdlw 	while (val)
842493Sdlw 	{
854745Sdlw 		/*
864745Sdlw 		 * This is really what's being done ...
874745Sdlw 		 * *--b = d[val % rad];
884745Sdlw 		 * val /= rad;
894745Sdlw 		 */
904745Sdlw 		tmp1 = val / rad;
914745Sdlw 		*--b = d[val - (tmp1 * rad)];
924745Sdlw 		val = tmp1;
932493Sdlw 	}
944745Sdlw 
954745Sdlw 	*ndigit = (&_icv_buf[MAXINTLENGTH] - b);
964745Sdlw 	return(b);
972493Sdlw }
98