xref: /illumos-gate/usr/src/lib/libmp/common/mout.c (revision 981fe1b1)
1 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
2 /*	  All Rights Reserved  	*/
3 
4 
5 /*
6  * Copyright (c) 1980 Regents of the University of California.
7  * All rights reserved.  The Berkeley software License Agreement
8  * specifies the terms and conditions for redistribution.
9  */
10 /* 	Portions Copyright(c) 1988, Sun Microsystems Inc.	*/
11 /*	All Rights Reserved					*/
12 
13 /*
14  * Copyright (c) 1997, by Sun Microsystems, Inc.
15  * All rights reserved.
16  */
17 
18 /*
19  * Copyright (c) 2018, Joyent, Inc.
20  */
21 
22 /* LINTLIBRARY */
23 
24 #include <stdio.h>
25 #include <mp.h>
26 #include <sys/types.h>
27 #include "libmp.h"
28 #include <stdlib.h>
29 
30 static int
m_in(MINT * a,short b,FILE * f)31 m_in(MINT *a, short b, FILE *f)
32 {
33 	MINT x, y, ten;
34 	int sign, c;
35 	short qten, qy;
36 
37 	_mp_xfree(a);
38 	sign = 1;
39 	ten.len = 1;
40 	ten.val = &qten;
41 	qten = b;
42 	x.len = 0;
43 	y.len = 1;
44 	y.val = &qy;
45 	while ((c = getc(f)) != EOF) {
46 		switch (c) {
47 
48 		case '\\':
49 			(void) getc(f);
50 			continue;
51 		case '\t':
52 		case '\n':
53 			a->len *= sign;
54 			_mp_xfree(&x);
55 			return (0);
56 		case ' ':
57 			continue;
58 		case '-':
59 			sign = -sign;
60 			continue;
61 		default:
62 			if (c >= '0' && c <= '9') {
63 				qy = c - '0';
64 				mp_mult(&x, &ten, a);
65 				mp_madd(a, &y, a);
66 				_mp_move(a, &x);
67 				continue;
68 			} else {
69 				(void) ungetc(c, stdin);
70 				a->len *= sign;
71 				return (0);
72 			}
73 		}
74 	}
75 
76 	return (EOF);
77 }
78 
79 static void
m_out(MINT * a,short b,FILE * f)80 m_out(MINT *a, short b, FILE *f)
81 {
82 	int sign, xlen, i;
83 	short r;
84 	MINT x;
85 
86 	char *obuf;
87 	char *bp;
88 
89 	if (a == NULL)
90 		return;
91 	sign = 1;
92 	xlen = a->len;
93 	if (xlen < 0) {
94 		xlen = -xlen;
95 		sign = -1;
96 	}
97 	if (xlen == 0) {
98 		(void) fprintf(f, "0\n");
99 		return;
100 	}
101 	x.len = xlen;
102 	x.val = _mp_xalloc(xlen, "m_out");
103 	for (i = 0; i < xlen; i++)
104 		x.val[i] = a->val[i];
105 	obuf = malloc(7 * (size_t)xlen);
106 	bp = obuf + 7 * xlen - 1;
107 	*bp-- = 0;
108 	while (x.len > 0) {
109 		for (i = 0; i < 10 && x.len > 0; i++) {
110 			mp_sdiv(&x, b, &x, &r);
111 			*bp-- = (char)(r + '0');
112 		}
113 		if (x.len > 0)
114 			*bp-- = ' ';
115 	}
116 	if (sign == -1)
117 		*bp-- = '-';
118 	(void) fprintf(f, "%s\n", bp + 1);
119 	free(obuf);
120 	_mp_xfree(&x);
121 }
122 
123 static void s_div(MINT *, short, MINT *, short *);
124 
125 void
mp_sdiv(MINT * a,short n,MINT * q,short * r)126 mp_sdiv(MINT *a, short n, MINT *q, short *r)
127 {
128 	MINT x, y;
129 	short sign;
130 
131 	sign = 1;
132 	x.len = a->len;
133 	x.val = a->val;
134 	if (n < 0) {
135 		sign = -sign;
136 		n = -n;
137 	}
138 	if (x.len < 0) {
139 		sign = -sign;
140 		x.len = -x.len;
141 	}
142 	s_div(&x, n, &y, r);
143 	_mp_xfree(q);
144 	q->val = y.val;
145 	q->len = sign * y.len;
146 	*r = *r * sign;
147 }
148 
149 static void
s_div(MINT * a,short n,MINT * q,short * r)150 s_div(MINT *a, short n, MINT *q, short *r)
151 {
152 	int qlen;
153 	int i;
154 	int x;
155 	short *qval;
156 	short *aval;
157 
158 	x = 0;
159 	qlen = a->len;
160 	q->val = _mp_xalloc(qlen, "s_div");
161 	aval = a->val + qlen;
162 	qval = q->val + qlen;
163 	for (i = qlen - 1; i >= 0; i--) {
164 		x = x * 0100000 + *--aval;
165 		*--qval = (short)(x / n);
166 		x = x % n;
167 	}
168 	*r = (short)x;
169 	if (qlen && q->val[qlen-1] == 0)
170 		qlen--;
171 	q->len = qlen;
172 	if (qlen == 0)
173 		free(q->val);
174 }
175 
176 int
mp_min(MINT * a)177 mp_min(MINT *a)
178 {
179 	return (m_in(a, 10, stdin));
180 }
181 
182 int
mp_omin(MINT * a)183 mp_omin(MINT *a)
184 {
185 	return (m_in(a, 8, stdin));
186 }
187 
188 void
mp_mout(MINT * a)189 mp_mout(MINT *a)
190 {
191 	m_out(a, 10, stdout);
192 }
193 
194 void
mp_omout(MINT * a)195 mp_omout(MINT *a)
196 {
197 	m_out(a, 8, stdout);
198 }
199 
200 void
mp_fmout(MINT * a,FILE * f)201 mp_fmout(MINT *a, FILE *f)
202 {
203 	m_out(a, 10, f);
204 }
205 
206 int
mp_fmin(MINT * a,FILE * f)207 mp_fmin(MINT *a, FILE *f)
208 {
209 	return (m_in(a, 10, f));
210 }
211