xref: /csrg-svn/usr.bin/f77/libI77/fmtlib.c (revision 4745)
12493Sdlw /*
2*4745Sdlw char id_fmtlib[] = "@(#)fmtlib.c	1.3";
32493Sdlw  *
42493Sdlw  * integer to ascii conversion
5*4745Sdlw  *
6*4745Sdlw  * This code has been rearranged to produce optimized runtime code.
72493Sdlw  */
82493Sdlw 
92493Sdlw #include "fio.h"
102493Sdlw 
11*4745Sdlw static char	_digit[] = "0123456789abcdefghijklmnopqrstuvwxyz";
12*4745Sdlw static char	_icv_buf[MAXINTLENGTH+1];
13*4745Sdlw #define		_mask	0x7fffffff
142493Sdlw 
15*4745Sdlw char *
16*4745Sdlw icvt(value, ndigit, sign)
17*4745Sdlw long	value;
18*4745Sdlw int	*ndigit;
19*4745Sdlw int	*sign;
202493Sdlw {
21*4745Sdlw 	register long	val = value;
22*4745Sdlw 	register long	rad = radix;
23*4745Sdlw 	register char	*b = &_icv_buf[MAXINTLENGTH];
24*4745Sdlw 	register char	*d = _digit;
25*4745Sdlw 	register long	tmp1;
26*4745Sdlw 	register int	tmp2;
27*4745Sdlw 	long	rem;
28*4745Sdlw 	long	kludge;
292493Sdlw 
30*4745Sdlw 	if (val == 0)
31*4745Sdlw 	{
32*4745Sdlw 		*--b = '0';
33*4745Sdlw 		*sign = 0;
34*4745Sdlw 		*ndigit = 1;
35*4745Sdlw 		return(b);
362493Sdlw 	}
37*4745Sdlw 
38*4745Sdlw 	if (signit && (*sign = (val < 0)))	/* signed conversion */
392493Sdlw 	{
40*4745Sdlw 		/*
41*4745Sdlw 		 * It is necessary to do the first divide
42*4745Sdlw 		 * before the absolute value, for the case -2^31
43*4745Sdlw 		 *
44*4745Sdlw 		 * This is actually what is being done...
45*4745Sdlw 		 * tmp1 = (int)(val % rad);
46*4745Sdlw 		 * val /= rad;
47*4745Sdlw 		 * val = -val
48*4745Sdlw 		 * *--b = d[-tmp1];
49*4745Sdlw 		 */
50*4745Sdlw 		tmp1 = val / rad;
51*4745Sdlw 		*--b = d[(tmp1 * rad) - val];
52*4745Sdlw 		val = -tmp1;
532493Sdlw 	}
54*4745Sdlw 	else				/* unsigned conversion */
55*4745Sdlw 	{
56*4745Sdlw 		*sign = 0;
57*4745Sdlw 		if (val < 0)
58*4745Sdlw 		{	/* ALL THIS IS TO SIMULATE UNSIGNED LONG MOD & DIV */
59*4745Sdlw 			kludge = _mask - (rad - 1);
60*4745Sdlw 			val &= _mask;
61*4745Sdlw 			/*
62*4745Sdlw 			 * This is really what's being done...
63*4745Sdlw 			 * rem = (kludge % rad) + (val % rad);
64*4745Sdlw 			 * val = (kludge / rad) + (val / rad) + (rem / rad) + 1;
65*4745Sdlw 			 * *--b = d[rem % rad];
66*4745Sdlw 			 */
67*4745Sdlw 			tmp1 = kludge / rad;
68*4745Sdlw 			tmp2 = val / rad;
69*4745Sdlw 			rem = (kludge - (tmp1 * rad)) + (val - (tmp2 * rad));
70*4745Sdlw 			val = ++tmp1 + tmp2;
71*4745Sdlw 			tmp1 = rem / rad;
72*4745Sdlw 			val += tmp1;
73*4745Sdlw 			*--b = d[rem - (tmp1 * rad)];
742493Sdlw 		}
752493Sdlw 	}
76*4745Sdlw 
77*4745Sdlw 	while (val)
782493Sdlw 	{
79*4745Sdlw 		/*
80*4745Sdlw 		 * This is really what's being done ...
81*4745Sdlw 		 * *--b = d[val % rad];
82*4745Sdlw 		 * val /= rad;
83*4745Sdlw 		 */
84*4745Sdlw 		tmp1 = val / rad;
85*4745Sdlw 		*--b = d[val - (tmp1 * rad)];
86*4745Sdlw 		val = tmp1;
872493Sdlw 	}
88*4745Sdlw 
89*4745Sdlw 	*ndigit = (&_icv_buf[MAXINTLENGTH] - b);
90*4745Sdlw 	return(b);
912493Sdlw }
92