mp.h revision 31de2854
15dfecf96Smrg/*
25dfecf96Smrg * Copyright (c) 2002 by The XFree86 Project, Inc.
35dfecf96Smrg *
45dfecf96Smrg * Permission is hereby granted, free of charge, to any person obtaining a
55dfecf96Smrg * copy of this software and associated documentation files (the "Software"),
65dfecf96Smrg * to deal in the Software without restriction, including without limitation
75dfecf96Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
85dfecf96Smrg * and/or sell copies of the Software, and to permit persons to whom the
95dfecf96Smrg * Software is furnished to do so, subject to the following conditions:
105dfecf96Smrg *
115dfecf96Smrg * The above copyright notice and this permission notice shall be included in
125dfecf96Smrg * all copies or substantial portions of the Software.
135dfecf96Smrg *
145dfecf96Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
155dfecf96Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
165dfecf96Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
175dfecf96Smrg * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
185dfecf96Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
195dfecf96Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
205dfecf96Smrg * SOFTWARE.
215dfecf96Smrg *
225dfecf96Smrg * Except as contained in this notice, the name of the XFree86 Project shall
235dfecf96Smrg * not be used in advertising or otherwise to promote the sale, use or other
245dfecf96Smrg * dealings in this Software without prior written authorization from the
255dfecf96Smrg * XFree86 Project.
265dfecf96Smrg *
275dfecf96Smrg * Author: Paulo César Pereira de Andrade
285dfecf96Smrg */
295dfecf96Smrg
305dfecf96Smrg/* $XFree86: xc/programs/xedit/lisp/mp/mp.h,v 1.5tsi Exp $ */
315dfecf96Smrg
325dfecf96Smrg#include <stdio.h>
335dfecf96Smrg#include <math.h>
345dfecf96Smrg#ifdef sun
355dfecf96Smrg#include <ieeefp.h>
365dfecf96Smrg#endif
375dfecf96Smrg#include <float.h>
385dfecf96Smrg#include <stdlib.h>
395dfecf96Smrg#include <limits.h>
405dfecf96Smrg#include <ctype.h>
415dfecf96Smrg#include <string.h>
425dfecf96Smrg
435dfecf96Smrg#ifndef __mp_h_
445dfecf96Smrg#define __mp_h_
455dfecf96Smrg
465dfecf96Smrg#ifdef __GNUC__
475dfecf96Smrg#define INLINE __inline__
485dfecf96Smrg#else
495dfecf96Smrg#define INLINE /**/
505dfecf96Smrg#endif
515dfecf96Smrg
525dfecf96Smrg/* this normally is better for multiplication and also
535dfecf96Smrg * simplify addition loops putting the larger value first */
545dfecf96Smrg#define MP_SWAP(op1, op2, len1, len2) {	\
555dfecf96Smrg    BNS *top = op1;			\
565dfecf96Smrg    BNI tlen = len1;			\
575dfecf96Smrg					\
585dfecf96Smrg    op1 = op2;				\
595dfecf96Smrg    len1 = len2;			\
605dfecf96Smrg    op2 = top;				\
615dfecf96Smrg    len2 = tlen;			\
625dfecf96Smrg}
635dfecf96Smrg
645dfecf96Smrg/*
655dfecf96Smrg * At least this length to use Karatsuba multiplication method
665dfecf96Smrg */
675dfecf96Smrg#define KARATSUBA		32
685dfecf96Smrg
695dfecf96Smrg/*
705dfecf96Smrg * At least this length to use Toom multiplication method
715dfecf96Smrg */
725dfecf96Smrg#define TOOM			128
735dfecf96Smrg
745dfecf96Smrg#if ULONG_MAX > 4294967295UL
755dfecf96Smrg  /* sizeof(long) == 8 and sizeof(int) == 4 */
765dfecf96Smrg# define BNI		unsigned long
775dfecf96Smrg# define BNS		unsigned int
785dfecf96Smrg# define MINSLONG	0x8000000000000000UL
7931de2854Smrg# define MAXSLONG	0x7fffffffffffffffUL
805dfecf96Smrg# define CARRY		0x100000000
815dfecf96Smrg# define LMASK		0xffffffff00000000UL
825dfecf96Smrg# define SMASK		0x00000000ffffffffUL
835dfecf96Smrg# define BNIBITS	64
845dfecf96Smrg# define BNSBITS	32
855dfecf96Smrg# ifndef LONG64
865dfecf96Smrg#  define LONG64
875dfecf96Smrg# endif
885dfecf96Smrg#else
895dfecf96Smrg  /* sizeof(long) == 4 and sizeof(short) == 2 */
905dfecf96Smrg# define BNI		unsigned long
915dfecf96Smrg# define BNS		unsigned short
925dfecf96Smrg# define MINSLONG	0x80000000UL
9331de2854Smrg# define MAXSLONG	0x7fffffffUL
945dfecf96Smrg# define CARRY		0x10000
955dfecf96Smrg# define LMASK		0xffff0000UL
965dfecf96Smrg# define SMASK		0x0000ffffUL
975dfecf96Smrg# define BNIBITS	32
985dfecf96Smrg# define BNSBITS	16
995dfecf96Smrg#endif
1005dfecf96Smrg
1015dfecf96Smrg#ifdef MAX
1025dfecf96Smrg#undef MAX
1035dfecf96Smrg#endif
1045dfecf96Smrg#define MAX(a, b)	((a) > (b) ? (a) : (b))
1055dfecf96Smrg
1065dfecf96Smrg#ifdef MIN
1075dfecf96Smrg#undef MIN
1085dfecf96Smrg#endif
1095dfecf96Smrg#define MIN(a, b)	((a) < (b) ? (a) : (b))
1105dfecf96Smrg
1115dfecf96Smrg/*
1125dfecf96Smrg * Types
1135dfecf96Smrg */
1145dfecf96Smrgtypedef struct _mpi {
1155dfecf96Smrg    unsigned int size : 31;
1165dfecf96Smrg    unsigned int sign : 1;
1175dfecf96Smrg    BNI alloc;
1185dfecf96Smrg    BNS *digs;		/* LSF format */
1195dfecf96Smrg} mpi;
1205dfecf96Smrg
1215dfecf96Smrgtypedef struct _mpr {
1225dfecf96Smrg    mpi num;
1235dfecf96Smrg    mpi den;
1245dfecf96Smrg} mpr;
1255dfecf96Smrg
1265dfecf96Smrgtypedef void *(*mp_malloc_fun)(size_t);
1275dfecf96Smrgtypedef void *(*mp_calloc_fun)(size_t, size_t);
1285dfecf96Smrgtypedef void *(*mp_realloc_fun)(void*, size_t);
1295dfecf96Smrgtypedef void (*mp_free_fun)(void*);
1305dfecf96Smrg
1315dfecf96Smrg/*
1325dfecf96Smrg * Prototypes
1335dfecf96Smrg */
1345dfecf96Smrg/* GENERIC FUNCTIONS */
1355dfecf96Smrg	/* memory allocation wrappers */
1365dfecf96Smrgvoid *mp_malloc(size_t size);
1375dfecf96Smrgvoid *mp_calloc(size_t nmemb, size_t size);
1385dfecf96Smrgvoid *mp_realloc(void *pointer, size_t size);
1395dfecf96Smrgvoid mp_free(void *pointer);
1405dfecf96Smrgmp_malloc_fun mp_set_malloc(mp_malloc_fun);
1415dfecf96Smrgmp_calloc_fun mp_set_calloc(mp_calloc_fun);
1425dfecf96Smrgmp_realloc_fun mp_set_realloc(mp_realloc_fun);
1435dfecf96Smrgmp_free_fun mp_set_free(mp_free_fun);
1445dfecf96Smrg
1455dfecf96Smrg	/* adds op1 and op2, stores result in rop
1465dfecf96Smrg	 * rop must pointer to at least len1 + len2 + 1 elements
1475dfecf96Smrg	 * rop can be either op1 or op2 */
1485dfecf96Smrglong mp_add(BNS *rop, BNS *op1, BNS *op2, BNI len1, BNI len2);
1495dfecf96Smrg
1505dfecf96Smrg	/* subtracts op2 from op1, stores result in rop
1515dfecf96Smrg	 * rop must pointer to at least len1 + len2 elements
1525dfecf96Smrg	 * op1 must be >= op2
1535dfecf96Smrg	 * rop can be either op1 or op2 */
1545dfecf96Smrglong mp_sub(BNS *rop, BNS *op1, BNS *op2, BNI len1, BNI len2);
1555dfecf96Smrg
1565dfecf96Smrg	/* shift op to the left shift bits
1575dfecf96Smrg	 * rop must have enough storage for result
1585dfecf96Smrg	 * rop can be op */
1595dfecf96Smrglong mp_lshift(BNS *rop, BNS *op, BNI len, long shift);
1605dfecf96Smrg
1615dfecf96Smrg	/* shift op to the right shift bits
1625dfecf96Smrg	 * shift must be positive
1635dfecf96Smrg	 * rop can be op */
1645dfecf96Smrglong mp_rshift(BNS *rop, BNS *op, BNI len, long shift);
1655dfecf96Smrg
1665dfecf96Smrg	/* use simple generic multiplication method
1675dfecf96Smrg	 * rop cannot be the same as op1 or op2
1685dfecf96Smrg	 * rop must be zeroed
1695dfecf96Smrg	 * op1 can be op2 */
1705dfecf96Smrglong mp_base_mul(BNS *rop, BNS *op1, BNS *op2, BNI len1, BNI len2);
1715dfecf96Smrg
1725dfecf96Smrg	/* use Karatsuba method
1735dfecf96Smrg	 * MIN(len1, len2) must be larger than (MAX(len1, len2) + 1) >> 1
1745dfecf96Smrg	 * MAX(len1, len2) should be at least 2
1755dfecf96Smrg	 * rop cannot be the same as op1 or op2
1765dfecf96Smrg	 * rop must be zeroed
1775dfecf96Smrg	 * op1 can be op2 */
1785dfecf96Smrglong mp_karatsuba_mul(BNS *rop, BNS *op1, BNS *op2, BNI len1, BNI len2);
1795dfecf96Smrg
1805dfecf96Smrg	/* use Toom method
1815dfecf96Smrg	 * len1 / 3 should be equal to len2 / 3
1825dfecf96Smrg	 * len1 / 3 should be at least 1
1835dfecf96Smrg	 * rop cannot be the same as op1 or op2
1845dfecf96Smrg	 * rop must be zeroed
1855dfecf96Smrg	 * op1 can be op2 */
1865dfecf96Smrglong mp_toom_mul(BNS *rop, BNS *op1, BNS *op2, BNI len1, BNI len2);
1875dfecf96Smrg
1885dfecf96Smrg	/* chooses the available multiplication methods based on it's input
1895dfecf96Smrg	 * rop must be a pointer to len1 + len2 elements
1905dfecf96Smrg	 * rop cannot be the same as op1 or op2
1915dfecf96Smrg	 * rop must be zeroed
1925dfecf96Smrg	 * op1 can be op2 */
1935dfecf96Smrglong mp_mul(BNS *rop, BNS *op1, BNS *op2, BNI len1, BNI len2);
1945dfecf96Smrg
1955dfecf96Smrg/* INTEGER FUNCTIONS */
1965dfecf96Smrg	/* initialize op and set it to 0 */
1975dfecf96Smrgvoid mpi_init(mpi *op);
1985dfecf96Smrg
1995dfecf96Smrg	/* clear memory associated to op */
2005dfecf96Smrgvoid mpi_clear(mpi *op);
2015dfecf96Smrg
2025dfecf96Smrg	/* set rop to the value of op */
2035dfecf96Smrgvoid mpi_set(mpi *rop, mpi *op);
2045dfecf96Smrg
2055dfecf96Smrg	/* set rop to the value of si */
2065dfecf96Smrgvoid mpi_seti(mpi *rop, long si);
2075dfecf96Smrg
2085dfecf96Smrg	/* set rop to the floor(fabs(d)) */
2095dfecf96Smrgvoid mpi_setd(mpi *rop, double d);
2105dfecf96Smrg
2115dfecf96Smrg	/* initialize rop to number representation in str in the given base.
2125dfecf96Smrg	 * leading zeros are skipped.
2135dfecf96Smrg	 * if sign present, it is processed.
2145dfecf96Smrg	 * base must be in the range 2 to 36. */
2155dfecf96Smrgvoid mpi_setstr(mpi *rop, char *str, int base);
2165dfecf96Smrg
2175dfecf96Smrg	/* adds two mp integers */
2185dfecf96Smrgvoid mpi_add(mpi *rop, mpi *op1, mpi *op2);
2195dfecf96Smrg
2205dfecf96Smrg	/* adds op1 and op2 */
2215dfecf96Smrgvoid mpi_addi(mpi *rop, mpi *op1, long op2);
2225dfecf96Smrg
2235dfecf96Smrg	/* subtracts two mp integers */
2245dfecf96Smrgvoid mpi_sub(mpi *rop, mpi *op1, mpi *op2);
2255dfecf96Smrg
2265dfecf96Smrg	/* subtracts op2 from op1 */
2275dfecf96Smrgvoid mpi_subi(mpi *rop, mpi *op1, long op2);
2285dfecf96Smrg
2295dfecf96Smrg	/* multiply two mp integers */
2305dfecf96Smrgvoid mpi_mul(mpi *rop, mpi *op1, mpi *op2);
2315dfecf96Smrg
2325dfecf96Smrg	/* multiply op1 by op2 */
2335dfecf96Smrgvoid mpi_muli(mpi *rop, mpi *op1, long op2);
2345dfecf96Smrg
2355dfecf96Smrg	/* divides num by den and sets rop to result */
2365dfecf96Smrgvoid mpi_div(mpi *rop, mpi *num, mpi *den);
2375dfecf96Smrg
2385dfecf96Smrg	/* divides num by den and sets rop to the remainder */
2395dfecf96Smrgvoid mpi_rem(mpi *rop, mpi *num, mpi *den);
2405dfecf96Smrg
2415dfecf96Smrg	/* divides num by den, sets quotient to qrop and remainder to rrop
2425dfecf96Smrg	 * qrop is truncated towards zero.
2435dfecf96Smrg	 * qrop and rrop are optional
2445dfecf96Smrg	 * qrop and rrop cannot be the same variable */
2455dfecf96Smrgvoid mpi_divqr(mpi *qrop, mpi *rrop, mpi *num, mpi *den);
2465dfecf96Smrg
2475dfecf96Smrg	/* divides num by then and stores result in rop */
2485dfecf96Smrgvoid mpi_divi(mpi *rop, mpi *num, long den);
2495dfecf96Smrg
2505dfecf96Smrg	/* divides num by den and returns remainder */
2515dfecf96Smrglong mpi_remi(mpi *num, long den);
2525dfecf96Smrg
2535dfecf96Smrg	/* divides num by den
2545dfecf96Smrg	 * stores quotient in qrop and returns remainder */
2555dfecf96Smrglong mpi_divqri(mpi *qrop, mpi *num, long den);
2565dfecf96Smrg
2575dfecf96Smrg	/* sets rop to num modulo den */
2585dfecf96Smrgvoid mpi_mod(mpi *rop, mpi *num, mpi *den);
2595dfecf96Smrg
2605dfecf96Smrg	/* returns num modulo den */
2615dfecf96Smrglong mpi_modi(mpi *num, long den);
2625dfecf96Smrg
2635dfecf96Smrg	/* sets rop to the greatest common divisor of num and den
2645dfecf96Smrg	 * result is always positive */
2655dfecf96Smrgvoid mpi_gcd(mpi *rop, mpi *num, mpi *den);
2665dfecf96Smrg
2675dfecf96Smrg	/* sets rop to the least common multiple of num and den
2685dfecf96Smrg	 * result is always positive */
2695dfecf96Smrgvoid mpi_lcm(mpi *rop, mpi *num, mpi *den);
2705dfecf96Smrg
2715dfecf96Smrg	/* sets rop to op raised to exp */
2725dfecf96Smrgvoid mpi_pow(mpi *rop, mpi *op, unsigned long exp);
2735dfecf96Smrg
2745dfecf96Smrg	/* sets rop to the integer part of the nth root of op.
2755dfecf96Smrg	 * returns 1 if result is exact, 0 otherwise */
2765dfecf96Smrgint mpi_root(mpi *rop, mpi *op, unsigned long nth);
2775dfecf96Smrg
2785dfecf96Smrg	/* sets rop to the integer part of the square root of op.
2795dfecf96Smrg	 * returns 1 if result is exact, 0 otherwise */
2805dfecf96Smrgint mpi_sqrt(mpi *rop, mpi *op);
2815dfecf96Smrg
2825dfecf96Smrg	/* bit shift, left if shift positive, right if negative
2835dfecf96Smrg	 * a fast way to multiply and divide by powers of two */
2845dfecf96Smrgvoid mpi_ash(mpi *rop, mpi *op, long shift);
2855dfecf96Smrg
2865dfecf96Smrg	/* sets rop to op1 logand op2 */
2875dfecf96Smrgvoid mpi_and(mpi *rop, mpi *op1, mpi *op2);
2885dfecf96Smrg
2895dfecf96Smrg	/* sets rop to op1 logior op2 */
2905dfecf96Smrgvoid mpi_ior(mpi *rop, mpi *op1, mpi *op2);
2915dfecf96Smrg
2925dfecf96Smrg	/* sets rop to op1 logxor op2 */
2935dfecf96Smrgvoid mpi_xor(mpi *rop, mpi *op1, mpi *op2);
2945dfecf96Smrg
2955dfecf96Smrg	/* sets rop to one's complement of op */
2965dfecf96Smrgvoid mpi_com(mpi *rop, mpi *op);
2975dfecf96Smrg
2985dfecf96Smrg	/* sets rop to -op */
2995dfecf96Smrgvoid mpi_neg(mpi *rop, mpi *op);
3005dfecf96Smrg
3015dfecf96Smrg	/* sets rop to the absolute value of op */
3025dfecf96Smrgvoid mpi_abs(mpi *rop, mpi *op);
3035dfecf96Smrg
3045dfecf96Smrg	/* compares op1 and op2
3055dfecf96Smrg	 * returns >0 if op1 > op2, 0 if op1 = op2, and  <0 if op1 < op2 */
3065dfecf96Smrgint mpi_cmp(mpi *op1, mpi *op2);
3075dfecf96Smrg
3085dfecf96Smrg	/* mpi_cmp with a long integer operand */
3095dfecf96Smrgint mpi_cmpi(mpi *op1, long op2);
3105dfecf96Smrg
3115dfecf96Smrg	/* compares absolute value of op1 and op2
3125dfecf96Smrg	 * returns >0 if abs(op1) > abs(op2), 0 if abs(op1) = abs(op2),
3135dfecf96Smrg	 * and  <0 if abs(op1) < abs(op2) */
3145dfecf96Smrgint mpi_cmpabs(mpi *op1, mpi *op2);
3155dfecf96Smrg
3165dfecf96Smrg	/* mpi_cmpabs with a long integer operand */
3175dfecf96Smrgint mpi_cmpabsi(mpi *op1, long op2);
3185dfecf96Smrg
3195dfecf96Smrg	/* returns 1 if op1 > 0, 0 if op1 = 0, and  -1 if op1 < 0 */
3205dfecf96Smrgint mpi_sgn(mpi *op);
3215dfecf96Smrg
3225dfecf96Smrg	/* fastly swaps contents of op1 and op2 */
3235dfecf96Smrgvoid mpi_swap(mpi *op1, mpi *op2);
3245dfecf96Smrg
3255dfecf96Smrg	/* returns 1 if op fits in a signed long int, 0 otherwise */
3265dfecf96Smrgint mpi_fiti(mpi *op);
3275dfecf96Smrg
3285dfecf96Smrg	/* converts mp integer to long int
3295dfecf96Smrg	 * to know if the value will fit, call mpi_fiti */
3305dfecf96Smrglong mpi_geti(mpi *op);
3315dfecf96Smrg
3325dfecf96Smrg	/* convert mp integer to double */
3335dfecf96Smrgdouble mpi_getd(mpi *op);
3345dfecf96Smrg
3355dfecf96Smrg	/* returns exact number of characters to represent mp integer
3365dfecf96Smrg	 * in given base, excluding sign and ending null character.
3375dfecf96Smrg	 * base must be in the range 2 to 36 */
3385dfecf96Smrgunsigned long mpi_getsize(mpi *op, int base);
3395dfecf96Smrg
3405dfecf96Smrg	/* returns pointer to string with representation of mp integer
3415dfecf96Smrg	 * if str is not NULL, it must have enough space to store integer
3425dfecf96Smrg	 * representation, if NULL a newly allocated string is returned.
3435dfecf96Smrg	 * base must be in the range 2 to 36 */
3445dfecf96Smrgchar *mpi_getstr(char *str, mpi *op, int base);
3455dfecf96Smrg
3465dfecf96Smrg/* RATIO FUNCTIONS */
3475dfecf96Smrg#define mpr_num(op)	(&((op)->num))
3485dfecf96Smrg#define mpr_den(op)	(&((op)->den))
3495dfecf96Smrg
3505dfecf96Smrg	/* initialize op and set it to 0/1 */
3515dfecf96Smrgvoid mpr_init(mpr *op);
3525dfecf96Smrg
3535dfecf96Smrg	/* clear memory associated to op */
3545dfecf96Smrgvoid mpr_clear(mpr *op);
3555dfecf96Smrg
3565dfecf96Smrg	/* set rop to the value of op */
3575dfecf96Smrgvoid mpr_set(mpr *rop, mpr *op);
3585dfecf96Smrg
3595dfecf96Smrg	/* set rop to num/den */
3605dfecf96Smrgvoid mpr_seti(mpr *rop, long num, long den);
3615dfecf96Smrg
3625dfecf96Smrg	/* set rop to the value of d */
3635dfecf96Smrgvoid mpr_setd(mpr *rop, double d);
3645dfecf96Smrg
3655dfecf96Smrg	/* initialize rop to number representation in str in the given base.
3665dfecf96Smrg	 * leading zeros are skipped.
3675dfecf96Smrg	 * if sign present, it is processed.
3685dfecf96Smrg	 * base must be in the range 2 to 36. */
3695dfecf96Smrgvoid mpr_setstr(mpr *rop, char *str, int base);
3705dfecf96Smrg
3715dfecf96Smrg	/* remove common factors of op */
3725dfecf96Smrgvoid mpr_canonicalize(mpr *op);
3735dfecf96Smrg
3745dfecf96Smrg	/* adds two mp rationals */
3755dfecf96Smrgvoid mpr_add(mpr *rop, mpr *op1, mpr *op2);
3765dfecf96Smrg
3775dfecf96Smrg	/* adds op1 and op2 */
3785dfecf96Smrgvoid mpr_addi(mpr *rop, mpr *op1, long op2);
3795dfecf96Smrg
3805dfecf96Smrg	/* subtracts two mp rationals */
3815dfecf96Smrgvoid mpr_sub(mpr *rop, mpr *op1, mpr *op2);
3825dfecf96Smrg
3835dfecf96Smrg	/* subtracts op2 from op1 */
3845dfecf96Smrgvoid mpr_subi(mpr *rop, mpr *op1, long op2);
3855dfecf96Smrg
3865dfecf96Smrg	/* multiply two mp rationals */
3875dfecf96Smrgvoid mpr_mul(mpr *rop, mpr *op1, mpr *op2);
3885dfecf96Smrg
3895dfecf96Smrg	/* multiply op1 by op2 */
3905dfecf96Smrgvoid mpr_muli(mpr *rop, mpr *op1, long op2);
3915dfecf96Smrg
3925dfecf96Smrg	/* divide two mp rationals */
3935dfecf96Smrgvoid mpr_div(mpr *rop, mpr *op1, mpr *op2);
3945dfecf96Smrg
3955dfecf96Smrg	/* divides op1 by op2 */
3965dfecf96Smrgvoid mpr_divi(mpr *rop, mpr *op1, long op2);
3975dfecf96Smrg
3985dfecf96Smrg	/* sets rop to 1/op */
3995dfecf96Smrgvoid mpr_inv(mpr *rop, mpr *op);
4005dfecf96Smrg
4015dfecf96Smrg	/* sets rop to -op */
4025dfecf96Smrgvoid mpr_neg(mpr *rop, mpr *op);
4035dfecf96Smrg
4045dfecf96Smrg	/* sets rop to the absolute value of op */
4055dfecf96Smrgvoid mpr_abs(mpr *rop, mpr *op);
4065dfecf96Smrg
4075dfecf96Smrg	/* compares op1 and op2
4085dfecf96Smrg	 * returns >0 if op1 > op2, 0 if op1 = op2, and  <0 if op1 < op2 */
4095dfecf96Smrgint mpr_cmp(mpr *op1, mpr *op2);
4105dfecf96Smrg
4115dfecf96Smrg	/* mpr_cmp with a long integer operand */
4125dfecf96Smrgint mpr_cmpi(mpr *op1, long op2);
4135dfecf96Smrg
4145dfecf96Smrg	/* compares absolute value of op1 and op2
4155dfecf96Smrg	 * returns >0 if abs(op1) > abs(op2), 0 if abs(op1) = abs(op2),
4165dfecf96Smrg	 * and  <0 if abs(op1) < abs(op2) */
4175dfecf96Smrgint mpr_cmpabs(mpr *op1, mpr *op2);
4185dfecf96Smrg
4195dfecf96Smrg	/* mpr_cmpabs with a long integer operand */
4205dfecf96Smrgint mpr_cmpabsi(mpr *op1, long op2);
4215dfecf96Smrg
4225dfecf96Smrg	/* fastly swaps contents of op1 and op2 */
4235dfecf96Smrgvoid mpr_swap(mpr *op1, mpr *op2);
4245dfecf96Smrg
4255dfecf96Smrg	/* returns 1 if op fits in a signed long int, 0 otherwise */
4265dfecf96Smrgint mpr_fiti(mpr *op);
4275dfecf96Smrg
4285dfecf96Smrg	/* convert mp rational to double */
4295dfecf96Smrgdouble mpr_getd(mpr *op);
4305dfecf96Smrg
4315dfecf96Smrg	/* returns pointer to string with representation of mp rational
4325dfecf96Smrg	 * if str is not NULL, it must have enough space to store rational
4335dfecf96Smrg	 * representation, if NULL a newly allocated string is returned.
4345dfecf96Smrg	 * base must be in the range 2 to 36 */
4355dfecf96Smrgchar *mpr_getstr(char *str, mpr *op, int base);
4365dfecf96Smrg
4375dfecf96Smrg#endif /* __mp_h_ */
438