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