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