1 /*
2  * Copyright (c) 2002 by The XFree86 Project, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20  * SOFTWARE.
21  *
22  * Except as contained in this notice, the name of the XFree86 Project shall
23  * not be used in advertising or otherwise to promote the sale, use or other
24  * dealings in this Software without prior written authorization from the
25  * XFree86 Project.
26  *
27  * Author: Paulo César Pereira de Andrade
28  */
29 
30 /* $XFree86: xc/programs/xedit/lisp/mp/mp.h,v 1.5tsi Exp $ */
31 
32 #include <stdio.h>
33 #include <math.h>
34 #ifdef sun
35 #include <ieeefp.h>
36 #endif
37 #include <float.h>
38 #include <stdlib.h>
39 #include <limits.h>
40 #include <ctype.h>
41 #include <string.h>
42 
43 #ifndef __mp_h_
44 #define __mp_h_
45 
46 #ifdef __GNUC__
47 #define INLINE __inline__
48 #else
49 #define INLINE /**/
50 #endif
51 
52 /* this normally is better for multiplication and also
53  * simplify addition loops putting the larger value first */
54 #define MP_SWAP(op1, op2, len1, len2) {	\
55     BNS *top = op1;			\
56     BNI tlen = len1;			\
57 					\
58     op1 = op2;				\
59     len1 = len2;			\
60     op2 = top;				\
61     len2 = tlen;			\
62 }
63 
64 /*
65  * At least this length to use Karatsuba multiplication method
66  */
67 #define KARATSUBA		32
68 
69 /*
70  * At least this length to use Toom multiplication method
71  */
72 #define TOOM			128
73 
74 #if ULONG_MAX > 4294967295UL
75   /* sizeof(long) == 8 and sizeof(int) == 4 */
76 # define BNI		unsigned long
77 # define BNS		unsigned int
78 # define MINSLONG	0x8000000000000000UL
79 # define MAXSLONG	0x7fffffffffffffffUL
80 # define CARRY		0x100000000
81 # define LMASK		0xffffffff00000000UL
82 # define SMASK		0x00000000ffffffffUL
83 # define BNIBITS	64
84 # define BNSBITS	32
85 # ifndef LONG64
86 #  define LONG64
87 # endif
88 #else
89   /* sizeof(long) == 4 and sizeof(short) == 2 */
90 # define BNI		unsigned long
91 # define BNS		unsigned short
92 # define MINSLONG	0x80000000UL
93 # define MAXSLONG	0x7fffffffUL
94 # define CARRY		0x10000
95 # define LMASK		0xffff0000UL
96 # define SMASK		0x0000ffffUL
97 # define BNIBITS	32
98 # define BNSBITS	16
99 #endif
100 
101 #ifdef MAX
102 #undef MAX
103 #endif
104 #define MAX(a, b)	((a) > (b) ? (a) : (b))
105 
106 #ifdef MIN
107 #undef MIN
108 #endif
109 #define MIN(a, b)	((a) < (b) ? (a) : (b))
110 
111 /*
112  * Types
113  */
114 typedef struct _mpi {
115     unsigned int size : 31;
116     unsigned int sign : 1;
117     BNI alloc;
118     BNS *digs;		/* LSF format */
119 } mpi;
120 
121 typedef struct _mpr {
122     mpi num;
123     mpi den;
124 } mpr;
125 
126 typedef void *(*mp_malloc_fun)(size_t);
127 typedef void *(*mp_calloc_fun)(size_t, size_t);
128 typedef void *(*mp_realloc_fun)(void*, size_t);
129 typedef void (*mp_free_fun)(void*);
130 
131 /*
132  * Prototypes
133  */
134 /* GENERIC FUNCTIONS */
135 	/* memory allocation wrappers */
136 void *mp_malloc(size_t size);
137 void *mp_calloc(size_t nmemb, size_t size);
138 void *mp_realloc(void *pointer, size_t size);
139 void mp_free(void *pointer);
140 mp_malloc_fun mp_set_malloc(mp_malloc_fun);
141 mp_calloc_fun mp_set_calloc(mp_calloc_fun);
142 mp_realloc_fun mp_set_realloc(mp_realloc_fun);
143 mp_free_fun mp_set_free(mp_free_fun);
144 
145 	/* adds op1 and op2, stores result in rop
146 	 * rop must pointer to at least len1 + len2 + 1 elements
147 	 * rop can be either op1 or op2 */
148 long mp_add(BNS *rop, BNS *op1, BNS *op2, BNI len1, BNI len2);
149 
150 	/* subtracts op2 from op1, stores result in rop
151 	 * rop must pointer to at least len1 + len2 elements
152 	 * op1 must be >= op2
153 	 * rop can be either op1 or op2 */
154 long mp_sub(BNS *rop, BNS *op1, BNS *op2, BNI len1, BNI len2);
155 
156 	/* shift op to the left shift bits
157 	 * rop must have enough storage for result
158 	 * rop can be op */
159 long mp_lshift(BNS *rop, BNS *op, BNI len, long shift);
160 
161 	/* shift op to the right shift bits
162 	 * shift must be positive
163 	 * rop can be op */
164 long mp_rshift(BNS *rop, BNS *op, BNI len, long shift);
165 
166 	/* use simple generic multiplication method
167 	 * rop cannot be the same as op1 or op2
168 	 * rop must be zeroed
169 	 * op1 can be op2 */
170 long mp_base_mul(BNS *rop, BNS *op1, BNS *op2, BNI len1, BNI len2);
171 
172 	/* use Karatsuba method
173 	 * MIN(len1, len2) must be larger than (MAX(len1, len2) + 1) >> 1
174 	 * MAX(len1, len2) should be at least 2
175 	 * rop cannot be the same as op1 or op2
176 	 * rop must be zeroed
177 	 * op1 can be op2 */
178 long mp_karatsuba_mul(BNS *rop, BNS *op1, BNS *op2, BNI len1, BNI len2);
179 
180 	/* use Toom method
181 	 * len1 / 3 should be equal to len2 / 3
182 	 * len1 / 3 should be at least 1
183 	 * rop cannot be the same as op1 or op2
184 	 * rop must be zeroed
185 	 * op1 can be op2 */
186 long mp_toom_mul(BNS *rop, BNS *op1, BNS *op2, BNI len1, BNI len2);
187 
188 	/* chooses the available multiplication methods based on it's input
189 	 * rop must be a pointer to len1 + len2 elements
190 	 * rop cannot be the same as op1 or op2
191 	 * rop must be zeroed
192 	 * op1 can be op2 */
193 long mp_mul(BNS *rop, BNS *op1, BNS *op2, BNI len1, BNI len2);
194 
195 /* INTEGER FUNCTIONS */
196 	/* initialize op and set it to 0 */
197 void mpi_init(mpi *op);
198 
199 	/* clear memory associated to op */
200 void mpi_clear(mpi *op);
201 
202 	/* set rop to the value of op */
203 void mpi_set(mpi *rop, mpi *op);
204 
205 	/* set rop to the value of si */
206 void mpi_seti(mpi *rop, long si);
207 
208 	/* set rop to the floor(fabs(d)) */
209 void mpi_setd(mpi *rop, double d);
210 
211 	/* initialize rop to number representation in str in the given base.
212 	 * leading zeros are skipped.
213 	 * if sign present, it is processed.
214 	 * base must be in the range 2 to 36. */
215 void mpi_setstr(mpi *rop, char *str, int base);
216 
217 	/* adds two mp integers */
218 void mpi_add(mpi *rop, mpi *op1, mpi *op2);
219 
220 	/* adds op1 and op2 */
221 void mpi_addi(mpi *rop, mpi *op1, long op2);
222 
223 	/* subtracts two mp integers */
224 void mpi_sub(mpi *rop, mpi *op1, mpi *op2);
225 
226 	/* subtracts op2 from op1 */
227 void mpi_subi(mpi *rop, mpi *op1, long op2);
228 
229 	/* multiply two mp integers */
230 void mpi_mul(mpi *rop, mpi *op1, mpi *op2);
231 
232 	/* multiply op1 by op2 */
233 void mpi_muli(mpi *rop, mpi *op1, long op2);
234 
235 	/* divides num by den and sets rop to result */
236 void mpi_div(mpi *rop, mpi *num, mpi *den);
237 
238 	/* divides num by den and sets rop to the remainder */
239 void mpi_rem(mpi *rop, mpi *num, mpi *den);
240 
241 	/* divides num by den, sets quotient to qrop and remainder to rrop
242 	 * qrop is truncated towards zero.
243 	 * qrop and rrop are optional
244 	 * qrop and rrop cannot be the same variable */
245 void mpi_divqr(mpi *qrop, mpi *rrop, mpi *num, mpi *den);
246 
247 	/* divides num by then and stores result in rop */
248 void mpi_divi(mpi *rop, mpi *num, long den);
249 
250 	/* divides num by den and returns remainder */
251 long mpi_remi(mpi *num, long den);
252 
253 	/* divides num by den
254 	 * stores quotient in qrop and returns remainder */
255 long mpi_divqri(mpi *qrop, mpi *num, long den);
256 
257 	/* sets rop to num modulo den */
258 void mpi_mod(mpi *rop, mpi *num, mpi *den);
259 
260 	/* returns num modulo den */
261 long mpi_modi(mpi *num, long den);
262 
263 	/* sets rop to the greatest common divisor of num and den
264 	 * result is always positive */
265 void mpi_gcd(mpi *rop, mpi *num, mpi *den);
266 
267 	/* sets rop to the least common multiple of num and den
268 	 * result is always positive */
269 void mpi_lcm(mpi *rop, mpi *num, mpi *den);
270 
271 	/* sets rop to op raised to exp */
272 void mpi_pow(mpi *rop, mpi *op, unsigned long exp);
273 
274 	/* sets rop to the integer part of the nth root of op.
275 	 * returns 1 if result is exact, 0 otherwise */
276 int mpi_root(mpi *rop, mpi *op, unsigned long nth);
277 
278 	/* sets rop to the integer part of the square root of op.
279 	 * returns 1 if result is exact, 0 otherwise */
280 int mpi_sqrt(mpi *rop, mpi *op);
281 
282 	/* bit shift, left if shift positive, right if negative
283 	 * a fast way to multiply and divide by powers of two */
284 void mpi_ash(mpi *rop, mpi *op, long shift);
285 
286 	/* sets rop to op1 logand op2 */
287 void mpi_and(mpi *rop, mpi *op1, mpi *op2);
288 
289 	/* sets rop to op1 logior op2 */
290 void mpi_ior(mpi *rop, mpi *op1, mpi *op2);
291 
292 	/* sets rop to op1 logxor op2 */
293 void mpi_xor(mpi *rop, mpi *op1, mpi *op2);
294 
295 	/* sets rop to one's complement of op */
296 void mpi_com(mpi *rop, mpi *op);
297 
298 	/* sets rop to -op */
299 void mpi_neg(mpi *rop, mpi *op);
300 
301 	/* sets rop to the absolute value of op */
302 void mpi_abs(mpi *rop, mpi *op);
303 
304 	/* compares op1 and op2
305 	 * returns >0 if op1 > op2, 0 if op1 = op2, and  <0 if op1 < op2 */
306 int mpi_cmp(mpi *op1, mpi *op2);
307 
308 	/* mpi_cmp with a long integer operand */
309 int mpi_cmpi(mpi *op1, long op2);
310 
311 	/* compares absolute value of op1 and op2
312 	 * returns >0 if abs(op1) > abs(op2), 0 if abs(op1) = abs(op2),
313 	 * and  <0 if abs(op1) < abs(op2) */
314 int mpi_cmpabs(mpi *op1, mpi *op2);
315 
316 	/* mpi_cmpabs with a long integer operand */
317 int mpi_cmpabsi(mpi *op1, long op2);
318 
319 	/* returns 1 if op1 > 0, 0 if op1 = 0, and  -1 if op1 < 0 */
320 int mpi_sgn(mpi *op);
321 
322 	/* fastly swaps contents of op1 and op2 */
323 void mpi_swap(mpi *op1, mpi *op2);
324 
325 	/* returns 1 if op fits in a signed long int, 0 otherwise */
326 int mpi_fiti(mpi *op);
327 
328 	/* converts mp integer to long int
329 	 * to know if the value will fit, call mpi_fiti */
330 long mpi_geti(mpi *op);
331 
332 	/* convert mp integer to double */
333 double mpi_getd(mpi *op);
334 
335 	/* returns exact number of characters to represent mp integer
336 	 * in given base, excluding sign and ending null character.
337 	 * base must be in the range 2 to 36 */
338 unsigned long mpi_getsize(mpi *op, int base);
339 
340 	/* returns pointer to string with representation of mp integer
341 	 * if str is not NULL, it must have enough space to store integer
342 	 * representation, if NULL a newly allocated string is returned.
343 	 * base must be in the range 2 to 36 */
344 char *mpi_getstr(char *str, mpi *op, int base);
345 
346 /* RATIO FUNCTIONS */
347 #define mpr_num(op)	(&((op)->num))
348 #define mpr_den(op)	(&((op)->den))
349 
350 	/* initialize op and set it to 0/1 */
351 void mpr_init(mpr *op);
352 
353 	/* clear memory associated to op */
354 void mpr_clear(mpr *op);
355 
356 	/* set rop to the value of op */
357 void mpr_set(mpr *rop, mpr *op);
358 
359 	/* set rop to num/den */
360 void mpr_seti(mpr *rop, long num, long den);
361 
362 	/* set rop to the value of d */
363 void mpr_setd(mpr *rop, double d);
364 
365 	/* initialize rop to number representation in str in the given base.
366 	 * leading zeros are skipped.
367 	 * if sign present, it is processed.
368 	 * base must be in the range 2 to 36. */
369 void mpr_setstr(mpr *rop, char *str, int base);
370 
371 	/* remove common factors of op */
372 void mpr_canonicalize(mpr *op);
373 
374 	/* adds two mp rationals */
375 void mpr_add(mpr *rop, mpr *op1, mpr *op2);
376 
377 	/* adds op1 and op2 */
378 void mpr_addi(mpr *rop, mpr *op1, long op2);
379 
380 	/* subtracts two mp rationals */
381 void mpr_sub(mpr *rop, mpr *op1, mpr *op2);
382 
383 	/* subtracts op2 from op1 */
384 void mpr_subi(mpr *rop, mpr *op1, long op2);
385 
386 	/* multiply two mp rationals */
387 void mpr_mul(mpr *rop, mpr *op1, mpr *op2);
388 
389 	/* multiply op1 by op2 */
390 void mpr_muli(mpr *rop, mpr *op1, long op2);
391 
392 	/* divide two mp rationals */
393 void mpr_div(mpr *rop, mpr *op1, mpr *op2);
394 
395 	/* divides op1 by op2 */
396 void mpr_divi(mpr *rop, mpr *op1, long op2);
397 
398 	/* sets rop to 1/op */
399 void mpr_inv(mpr *rop, mpr *op);
400 
401 	/* sets rop to -op */
402 void mpr_neg(mpr *rop, mpr *op);
403 
404 	/* sets rop to the absolute value of op */
405 void mpr_abs(mpr *rop, mpr *op);
406 
407 	/* compares op1 and op2
408 	 * returns >0 if op1 > op2, 0 if op1 = op2, and  <0 if op1 < op2 */
409 int mpr_cmp(mpr *op1, mpr *op2);
410 
411 	/* mpr_cmp with a long integer operand */
412 int mpr_cmpi(mpr *op1, long op2);
413 
414 	/* compares absolute value of op1 and op2
415 	 * returns >0 if abs(op1) > abs(op2), 0 if abs(op1) = abs(op2),
416 	 * and  <0 if abs(op1) < abs(op2) */
417 int mpr_cmpabs(mpr *op1, mpr *op2);
418 
419 	/* mpr_cmpabs with a long integer operand */
420 int mpr_cmpabsi(mpr *op1, long op2);
421 
422 	/* fastly swaps contents of op1 and op2 */
423 void mpr_swap(mpr *op1, mpr *op2);
424 
425 	/* returns 1 if op fits in a signed long int, 0 otherwise */
426 int mpr_fiti(mpr *op);
427 
428 	/* convert mp rational to double */
429 double mpr_getd(mpr *op);
430 
431 	/* returns pointer to string with representation of mp rational
432 	 * if str is not NULL, it must have enough space to store rational
433 	 * representation, if NULL a newly allocated string is returned.
434 	 * base must be in the range 2 to 36 */
435 char *mpr_getstr(char *str, mpr *op, int base);
436 
437 #endif /* __mp_h_ */
438