xref: /original-bsd/usr.bin/f77/libI77/fmtlib.c (revision 27f6e8d8)
1 /*-
2  * Copyright (c) 1980 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.proprietary.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)fmtlib.c	5.2 (Berkeley) 04/12/91";
10 #endif /* not lint */
11 
12 /*
13  * integer to ascii conversion
14  *
15  * This code has been rearranged to produce optimized runtime code.
16  */
17 
18 #include "fio.h"
19 
20 static char	_digit[] = "0123456789abcdefghijklmnopqrstuvwxyz";
21 static char	_icv_buf[MAXINTLENGTH+1];
22 #define		_mask	0x7fffffff
23 
24 char *
25 icvt(value, ndigit, sign)
26 long	value;
27 int	*ndigit;
28 int	*sign;
29 {
30 	register long	val = value;
31 	register long	rad = radix;
32 	register char	*b = &_icv_buf[MAXINTLENGTH];
33 	register char	*d = _digit;
34 	register long	tmp1;
35 	register int	tmp2;
36 	long	rem;
37 	long	kludge;
38 
39 	if (val == 0)
40 	{
41 		*--b = '0';
42 		*sign = 0;
43 		*ndigit = 1;
44 		return(b);
45 	}
46 
47 	if (signit && (*sign = (val < 0)))	/* signed conversion */
48 	{
49 		/*
50 		 * It is necessary to do the first divide
51 		 * before the absolute value, for the case -2^31
52 		 *
53 		 * This is actually what is being done...
54 		 * tmp1 = (int)(val % rad);
55 		 * val /= rad;
56 		 * val = -val
57 		 * *--b = d[-tmp1];
58 		 */
59 		tmp1 = val / rad;
60 		*--b = d[(tmp1 * rad) - val];
61 		val = -tmp1;
62 	}
63 	else				/* unsigned conversion */
64 	{
65 		*sign = 0;
66 		if (val < 0)
67 		{	/* ALL THIS IS TO SIMULATE UNSIGNED LONG MOD & DIV */
68 			kludge = _mask - (rad - 1);
69 			val &= _mask;
70 			/*
71 			 * This is really what's being done...
72 			 * rem = (kludge % rad) + (val % rad);
73 			 * val = (kludge / rad) + (val / rad) + (rem / rad) + 1;
74 			 * *--b = d[rem % rad];
75 			 */
76 			tmp1 = kludge / rad;
77 			tmp2 = val / rad;
78 			rem = (kludge - (tmp1 * rad)) + (val - (tmp2 * rad));
79 			val = ++tmp1 + tmp2;
80 			tmp1 = rem / rad;
81 			val += tmp1;
82 			*--b = d[rem - (tmp1 * rad)];
83 		}
84 	}
85 
86 	while (val)
87 	{
88 		/*
89 		 * This is really what's being done ...
90 		 * *--b = d[val % rad];
91 		 * val /= rad;
92 		 */
93 		tmp1 = val / rad;
94 		*--b = d[val - (tmp1 * rad)];
95 		val = tmp1;
96 	}
97 
98 	*ndigit = (&_icv_buf[MAXINTLENGTH] - b);
99 	return(b);
100 }
101