1
2/*
3 *  M_APM  -  m_apm.h
4 *
5 *  Copyright (C) 1999 - 2007   Michael C. Ring
6 *
7 *  Permission to use, copy, and distribute this software and its
8 *  documentation for any purpose with or without fee is hereby granted,
9 *  provided that the above copyright notice appear in all copies and
10 *  that both that copyright notice and this permission notice appear
11 *  in supporting documentation.
12 *
13 *  Permission to modify the software is granted. Permission to distribute
14 *  the modified code is granted. Modifications are to be distributed by
15 *  using the file 'license.txt' as a template to modify the file header.
16 *  'license.txt' is available in the official MAPM distribution.
17 *
18 *  This software is provided "as is" without express or implied warranty.
19 */
20
21/*
22 *      This is the header file that the user will include.
23 *
24 *      $Log: m_apm.h,v $
25 *      Revision 1.42  2007/12/03 02:28:25  mike
26 *      update copyright
27 *
28 *      Revision 1.41  2007/12/03 01:21:35  mike
29 *      Update license
30 *      Update version to 4.9.5
31 *
32 *      Revision 1.40  2004/05/31 22:06:02  mike
33 *      add % operator to C++ wrapper
34 *
35 *      Revision 1.39  2004/05/24 04:11:41  mike
36 *      updated version to 4.9.2
37 *
38 *      Revision 1.38  2004/04/01 03:17:19  mike
39 *      update version to 4.9.1
40 *
41 *      Revision 1.37  2004/01/02 20:40:49  mike
42 *      fix date on copyright
43 *
44 *      Revision 1.36  2004/01/02 00:52:38  mike
45 *      update version to 4.9
46 *
47 *      Revision 1.35  2003/11/23 05:12:46  mike
48 *      update version
49 *
50 *      Revision 1.34  2003/07/21 20:59:54  mike
51 *      update version to 4.8
52 *
53 *      Revision 1.33  2003/05/14 21:19:23  mike
54 *      change version string
55 *
56 *      Revision 1.32  2003/05/06 21:29:11  mike
57 *      add defines for lib versions (and prototypes)
58 *
59 *      Revision 1.31  2002/11/04 20:46:33  mike
60 *      change definition of the M_APM structure
61 *
62 *      Revision 1.30  2002/11/03 23:36:24  mike
63 *      added new function, m_apm_integer_pow_nr
64 *
65 *      Revision 1.29  2002/02/14 21:43:00  mike
66 *      add set_random_seed prototype
67 *
68 *      Revision 1.28  2001/08/28 18:29:32  mike
69 *      fix fixptstringexp
70 *
71 *      Revision 1.27  2001/08/27 22:45:03  mike
72 *      fix typo
73 *
74 *      Revision 1.26  2001/08/27 22:43:06  mike
75 *      add new fix pt functions to C++ wrapper
76 *
77 *      Revision 1.25  2001/08/26 22:09:13  mike
78 *      add new prototype
79 *
80 *      Revision 1.24  2001/08/25 16:48:21  mike
81 *      add new prototypes
82 *
83 *      Revision 1.23  2001/07/16 18:40:27  mike
84 *      add free_all_mem, trim_mem_usage prototypes
85 *
86 *      Revision 1.22  2001/07/15 20:49:21  mike
87 *      added is_odd, is_even, gcd, lcm functions
88 *
89 *      Revision 1.21  2001/03/25 21:24:55  mike
90 *      add floor and ceil functions
91 *
92 *      Revision 1.20  2000/09/23 19:05:29  mike
93 *      add _reciprocal prototype
94 *
95 *      Revision 1.19  2000/08/21 23:30:13  mike
96 *      add _is_integer function
97 *
98 *      Revision 1.18  2000/07/06 00:10:15  mike
99 *      redo declare for MM_cpp_min_precision
100 *
101 *      Revision 1.17  2000/07/04 20:59:43  mike
102 *      move MM_cpp_min_precision into cplusplus block below
103 *
104 *      Revision 1.16  2000/07/04 20:49:04  mike
105 *      move 'MM_cpp_min_precision' inside the extern "C"
106 *      brackets
107 *
108 *      Revision 1.15  2000/04/06 21:19:38  mike
109 *      minor final tweaks from Orion
110 *
111 *      Revision 1.14  2000/04/05 20:15:25  mike
112 *      add cpp_min_precision
113 *
114 *      Revision 1.13  2000/04/04 22:20:09  mike
115 *      updated some comments from Orion
116 *
117 *      Revision 1.12  2000/04/04 19:46:36  mike
118 *      fix preincrement, postincrement operators
119 *      added some comments
120 *      added 'ipow' operators
121 *
122 *      Revision 1.11  2000/04/03 22:08:35  mike
123 *      added MAPM C++ wrapper class
124 *      supplied by Orion Sky Lawlor (olawlor@acm.org)
125 *
126 *      Revision 1.10  2000/04/03 18:40:28  mike
127 *      add #define atan2 for alias
128 *
129 *      Revision 1.9  2000/04/03 18:05:23  mike
130 *      added hyperbolic functions
131 *
132 *      Revision 1.8  2000/04/03 17:26:57  mike
133 *      add cbrt prototype
134 *
135 *      Revision 1.7  1999/09/18 03:11:23  mike
136 *      add new prototype
137 *
138 *      Revision 1.6  1999/09/18 03:08:25  mike
139 *      add new prototypes
140 *
141 *      Revision 1.5  1999/09/18 01:37:55  mike
142 *      added new prototype
143 *
144 *      Revision 1.4  1999/07/12 02:04:30  mike
145 *      added new function prototpye (m_apm_integer_string)
146 *
147 *      Revision 1.3  1999/05/15 21:04:08  mike
148 *      added factorial prototype
149 *
150 *      Revision 1.2  1999/05/12 20:50:12  mike
151 *      added more constants
152 *
153 *      Revision 1.1  1999/05/12 20:48:25  mike
154 *      Initial revision
155 *
156 *      $Id: m_apm.h,v 1.42 2007/12/03 02:28:25 mike Exp $
157 */
158
159#ifndef M__APM__INCLUDED
160#define M__APM__INCLUDED
161
162#ifdef __cplusplus
163/* Comment this line out if you've compiled the library as C++. */
164#define APM_CONVERT_FROM_C
165#endif
166
167#ifdef APM_CONVERT_FROM_C
168extern "C" {
169#endif
170
171typedef unsigned char UCHAR;
172
173typedef struct  {
174	UCHAR	*m_apm_data;
175	long	m_apm_id;
176	int     m_apm_refcount;       /* <- used only by C++ MAPM class */
177	int	m_apm_malloclength;
178	int	m_apm_datalength;
179	int	m_apm_exponent;
180	int	m_apm_sign;
181} M_APM_struct;
182
183typedef M_APM_struct *M_APM;
184
185
186#define MAPM_LIB_VERSION \
187    "MAPM Library Version 4.9.5  Copyright (C) 1999-2007, Michael C. Ring"
188#define MAPM_LIB_SHORT_VERSION "4.9.5"
189
190
191/*
192 *	convienient predefined constants
193 */
194
195extern	M_APM	MM_Zero;
196extern	M_APM	MM_One;
197extern	M_APM	MM_Two;
198extern	M_APM	MM_Three;
199extern	M_APM	MM_Four;
200extern	M_APM	MM_Five;
201extern	M_APM	MM_Ten;
202
203extern	M_APM	MM_PI;
204extern	M_APM	MM_HALF_PI;
205extern	M_APM	MM_2_PI;
206extern	M_APM	MM_E;
207
208extern	M_APM	MM_LOG_E_BASE_10;
209extern	M_APM	MM_LOG_10_BASE_E;
210extern	M_APM	MM_LOG_2_BASE_E;
211extern	M_APM	MM_LOG_3_BASE_E;
212
213
214/*
215 *	function prototypes
216 */
217
218extern	M_APM	m_apm_init(void);
219extern	void	m_apm_free(M_APM);
220extern	void	m_apm_free_all_mem(void);
221extern	void	m_apm_trim_mem_usage(void);
222extern	char	*m_apm_lib_version(char *);
223extern	char	*m_apm_lib_short_version(char *);
224
225extern	void	m_apm_set_string(M_APM, char *);
226extern	void	m_apm_set_double(M_APM, double);
227extern	void	m_apm_set_long(M_APM, long);
228
229extern	void	m_apm_to_string(char *, int, M_APM);
230extern  void	m_apm_to_fixpt_string(char *, int, M_APM);
231extern  void	m_apm_to_fixpt_stringex(char *, int, M_APM, char, char, int);
232extern  char	*m_apm_to_fixpt_stringexp(int, M_APM, char, char, int);
233extern  void    m_apm_to_integer_string(char *, M_APM);
234
235extern	void	m_apm_absolute_value(M_APM, M_APM);
236extern	void	m_apm_negate(M_APM, M_APM);
237extern	void	m_apm_copy(M_APM, M_APM);
238extern	void	m_apm_round(M_APM, int, M_APM);
239extern	int	m_apm_compare(M_APM, M_APM);
240extern	int	m_apm_sign(M_APM);
241extern	int	m_apm_exponent(M_APM);
242extern	int	m_apm_significant_digits(M_APM);
243extern	int	m_apm_is_integer(M_APM);
244extern	int	m_apm_is_even(M_APM);
245extern	int	m_apm_is_odd(M_APM);
246
247extern	void	m_apm_gcd(M_APM, M_APM, M_APM);
248extern	void	m_apm_lcm(M_APM, M_APM, M_APM);
249
250extern	void	m_apm_add(M_APM, M_APM, M_APM);
251extern	void	m_apm_subtract(M_APM, M_APM, M_APM);
252extern	void	m_apm_multiply(M_APM, M_APM, M_APM);
253extern	void	m_apm_divide(M_APM, int, M_APM, M_APM);
254extern	void	m_apm_integer_divide(M_APM, M_APM, M_APM);
255extern	void	m_apm_integer_div_rem(M_APM, M_APM, M_APM, M_APM);
256extern	void	m_apm_reciprocal(M_APM, int, M_APM);
257extern	void	m_apm_factorial(M_APM, M_APM);
258extern	void	m_apm_floor(M_APM, M_APM);
259extern	void	m_apm_ceil(M_APM, M_APM);
260extern	void	m_apm_get_random(M_APM);
261extern	void	m_apm_set_random_seed(char *);
262
263extern	void	m_apm_sqrt(M_APM, int, M_APM);
264extern	void	m_apm_cbrt(M_APM, int, M_APM);
265extern	void	m_apm_log(M_APM, int, M_APM);
266extern	void	m_apm_log10(M_APM, int, M_APM);
267extern	void	m_apm_exp(M_APM, int, M_APM);
268extern	void	m_apm_pow(M_APM, int, M_APM, M_APM);
269extern  void	m_apm_integer_pow(M_APM, int, M_APM, int);
270extern  void	m_apm_integer_pow_nr(M_APM, M_APM, int);
271
272extern	void	m_apm_sin_cos(M_APM, M_APM, int, M_APM);
273extern	void	m_apm_sin(M_APM, int, M_APM);
274extern	void	m_apm_cos(M_APM, int, M_APM);
275extern	void	m_apm_tan(M_APM, int, M_APM);
276extern	void	m_apm_arcsin(M_APM, int, M_APM);
277extern	void	m_apm_arccos(M_APM, int, M_APM);
278extern	void	m_apm_arctan(M_APM, int, M_APM);
279extern	void	m_apm_arctan2(M_APM, int, M_APM, M_APM);
280
281extern  void    m_apm_sinh(M_APM, int, M_APM);
282extern  void    m_apm_cosh(M_APM, int, M_APM);
283extern  void    m_apm_tanh(M_APM, int, M_APM);
284extern  void    m_apm_arcsinh(M_APM, int, M_APM);
285extern  void    m_apm_arccosh(M_APM, int, M_APM);
286extern  void    m_apm_arctanh(M_APM, int, M_APM);
287
288extern  void    m_apm_cpp_precision(int);   /* only for C++ wrapper */
289
290/* more intuitive alternate names for the ARC functions ... */
291
292#define m_apm_asin m_apm_arcsin
293#define m_apm_acos m_apm_arccos
294#define m_apm_atan m_apm_arctan
295#define m_apm_atan2 m_apm_arctan2
296
297#define m_apm_asinh m_apm_arcsinh
298#define m_apm_acosh m_apm_arccosh
299#define m_apm_atanh m_apm_arctanh
300
301#ifdef APM_CONVERT_FROM_C
302}      /* End extern "C" bracket */
303#endif
304
305#ifdef __cplusplus   /*<- Hides the class below from C compilers */
306
307/*
308    This class lets you use M_APM's a bit more intuitively with
309    C++'s operator and function overloading, constructors, etc.
310
311    Added 3/24/2000 by Orion Sky Lawlor, olawlor@acm.org
312*/
313
314extern
315#ifdef APM_CONVERT_FROM_C
316"C"
317#endif
318int MM_cpp_min_precision;
319
320
321class MAPM {
322protected:
323
324/*
325The M_APM structure here is implemented as a reference-
326counted, copy-on-write data structure-- this makes copies
327very fast, but that's why it's so ugly.  A MAPM object is
328basically just a wrapper around a (possibly shared)
329M_APM_struct myVal.
330*/
331
332
333	M_APM myVal;  /* My M_APM structure */
334	void create(void) {myVal=makeNew();}
335	void destroy(void) {unref(myVal);myVal=NULL;}
336	void copyFrom(M_APM Nval)
337	{
338		 M_APM oldVal=myVal;
339		 myVal=Nval;
340		 ref(myVal);
341		 unref(oldVal);
342	}
343	static M_APM makeNew(void)
344	{
345		M_APM val=m_apm_init();
346		/* refcount initialized to 1 by 'm_apm_init' */
347		return val;
348	}
349	static void ref(M_APM val)
350	{
351		val->m_apm_refcount++;
352	}
353	static void unref(M_APM val)
354	{
355		val->m_apm_refcount--;
356		if (val->m_apm_refcount==0)
357			m_apm_free(val);
358	}
359
360	/* This routine is called to get a private (mutable)
361	   copy of our current value. */
362	M_APM val(void)
363	{
364		if (myVal->m_apm_refcount==1)
365		/* Return my private myVal */
366			return myVal;
367
368		/* Otherwise, our copy of myVal is shared--
369		   we need to make a new private copy.
370                */
371		M_APM oldVal=myVal;
372		myVal=makeNew();
373		m_apm_copy(myVal,oldVal);
374		unref(oldVal);
375		return myVal;
376	}
377
378	/*BAD: C M_APM routines doesn't use "const" where they should--
379	  hence we have to cast to a non-const type here (FIX THIS!).
380
381	  (in due time.... MCR)
382	*/
383	M_APM cval(void) const
384	{
385		return (M_APM)myVal;
386	}
387	/* This is the default number of digits to use for
388	   1-ary functions like sin, cos, tan, etc.
389	   It's the larger of my digits and cpp_min_precision.
390        */
391	int myDigits(void) const
392	{
393		int maxd=m_apm_significant_digits(cval());
394		if (maxd<MM_cpp_min_precision) maxd=MM_cpp_min_precision;
395		return maxd;
396	}
397	/* This is the default number of digits to use for
398	   2-ary functions like divide, atan2, etc.
399	   It's the larger of my digits, his digits, and cpp_min_precision.
400        */
401	int digits(const MAPM &otherVal) const
402	{
403		int maxd=myDigits();
404		int his=m_apm_significant_digits(otherVal.cval());
405		if (maxd<his) maxd=his;
406		return maxd;
407	}
408public:
409	/* Constructors: */
410	MAPM(void) /* Default constructor (takes no value) */
411		{create();}
412	MAPM(const MAPM &m) /* Copy constructor */
413		{myVal=(M_APM)m.cval();ref(myVal);}
414	MAPM(M_APM m) /* M_APM constructor (refcount starts at one) */
415		{myVal=(M_APM)m;ref(myVal);}
416	MAPM(const char *s) /* Constructor from string */
417		{create();m_apm_set_string(val(),(char *)s);}
418	MAPM(double d) /* Constructor from double-precision float */
419		{create();m_apm_set_double(val(),d);}
420	MAPM(int l) /* Constructor from int */
421		{create();m_apm_set_long(val(),l);}
422	MAPM(long l) /* Constructor from long int */
423		{create();m_apm_set_long(val(),l);}
424	/* Destructor */
425	~MAPM() {destroy();}
426
427	/* Extracting string descriptions: */
428	void toString(char *dest,int decimalPlaces) const
429		{m_apm_to_string(dest,decimalPlaces,cval());}
430	void toFixPtString(char *dest,int decimalPlaces) const
431		{m_apm_to_fixpt_string(dest,decimalPlaces,cval());}
432	void toFixPtStringEx(char *dest,int dp,char a,char b,int c) const
433		{m_apm_to_fixpt_stringex(dest,dp,cval(),a,b,c);}
434	char *toFixPtStringExp(int dp,char a,char b,int c) const
435		{return(m_apm_to_fixpt_stringexp(dp,cval(),a,b,c));}
436	void toIntegerString(char *dest) const
437		{m_apm_to_integer_string(dest,cval());}
438
439	/* Basic operators: */
440	MAPM &operator=(const MAPM &m) /* Assigment operator */
441		{copyFrom((M_APM)m.cval());return *this;}
442	MAPM &operator=(const char *s) /* Assigment operator */
443		{m_apm_set_string(val(),(char *)s);return *this;}
444	MAPM &operator=(double d) /* Assigment operator */
445		{m_apm_set_double(val(),d);return *this;}
446	MAPM &operator=(int l) /* Assigment operator */
447		{m_apm_set_long(val(),l);return *this;}
448	MAPM &operator=(long l) /* Assigment operator */
449		{m_apm_set_long(val(),l);return *this;}
450	MAPM operator++() /* Prefix increment operator */
451		{return *this = *this+MM_One;}
452	MAPM operator--() /* Prefix decrement operator */
453		{return *this = *this-MM_One;}
454	const MAPM operator++(int)  /* Postfix increment operator */
455	{
456		MAPM old = *this;
457		++(*this);          /* Call prefix increment */
458		return old;
459	}
460	const MAPM operator--(int)  /* Postfix decrement operator */
461	{
462		MAPM old = *this;
463		--(*this);          /* Call prefix decrement */
464		return old;
465	}
466
467	/* Comparison operators */
468	int operator==(const MAPM &m) const /* Equality operator */
469	 {return m_apm_compare(cval(),m.cval())==0;}
470	int operator!=(const MAPM &m) const /* Inequality operator */
471	 {return m_apm_compare(cval(),m.cval())!=0;}
472	int operator<(const MAPM &m) const
473	 {return m_apm_compare(cval(),m.cval())<0;}
474	int operator<=(const MAPM &m) const
475	 {return m_apm_compare(cval(),m.cval())<=0;}
476	int operator>(const MAPM &m) const
477	 {return m_apm_compare(cval(),m.cval())>0;}
478	int operator>=(const MAPM &m) const
479	 {return m_apm_compare(cval(),m.cval())>=0;}
480
481	/* Basic arithmetic operators */
482	friend MAPM operator+(const MAPM &a,const MAPM &b)
483	 {MAPM ret;m_apm_add(ret.val(),a.cval(),b.cval());return ret;}
484	friend MAPM operator-(const MAPM &a,const MAPM &b)
485	 {MAPM ret;m_apm_subtract(ret.val(),a.cval(),b.cval());return ret;}
486	friend MAPM operator*(const MAPM &a,const MAPM &b)
487	 {MAPM ret;m_apm_multiply(ret.val(),a.cval(),b.cval());return ret;}
488	friend MAPM operator%(const MAPM &a,const MAPM &b)
489	 {MAPM quot,ret;m_apm_integer_div_rem(quot.val(),ret.val(),
490		a.cval(),b.cval());return ret;}
491
492	/* Default division keeps larger of cpp_min_precision, numerator
493	   digits of precision, or denominator digits of precision. */
494	friend MAPM operator/(const MAPM &a,const MAPM &b)
495		{return a.divide(b,a.digits(b));}
496
497	MAPM divide(const MAPM &m,int toDigits) const
498        	{MAPM ret;m_apm_divide(ret.val(),toDigits,cval(),
499					        m.cval());return ret;}
500	MAPM divide(const MAPM &m) const {return divide(m,digits(m));}
501
502	/* Assignment arithmetic operators */
503	MAPM &operator+=(const MAPM &m) {*this = *this+m;return *this;}
504	MAPM &operator-=(const MAPM &m) {*this = *this-m;return *this;}
505	MAPM &operator*=(const MAPM &m) {*this = *this*m;return *this;}
506	MAPM &operator/=(const MAPM &m) {*this = *this/m;return *this;}
507	MAPM &operator%=(const MAPM &m) {*this = *this%m;return *this;}
508
509	/* Extracting/setting simple information: */
510	int sign(void) const
511		{return m_apm_sign(cval());}
512	int exponent(void) const
513		{return m_apm_exponent(cval());}
514	int significant_digits(void) const
515		{return m_apm_significant_digits(cval());}
516	int is_integer(void) const
517		{return m_apm_is_integer(cval());}
518	int is_even(void) const
519		{return m_apm_is_even(cval());}
520	int is_odd(void) const
521		{return m_apm_is_odd(cval());}
522
523	/* Functions: */
524	MAPM abs(void) const
525		{MAPM ret;m_apm_absolute_value(ret.val(),cval());return ret;}
526	MAPM neg(void) const
527		{MAPM ret;m_apm_negate(ret.val(),cval());return ret;}
528	MAPM round(int toDigits) const
529		{MAPM ret;m_apm_round(ret.val(),toDigits,cval());return ret;}
530	MAPM operator-(void) const {return neg();}
531
532/* I got tired of typing the various declarations for a simple
533   1-ary real-to-real function on MAPM's; hence this define:
534   The digits-free versions return my digits of precision or
535   cpp_min_precision, whichever is bigger.
536*/
537
538#define MAPM_1aryFunc(func) \
539	MAPM func(int toDigits) const\
540		{MAPM ret;m_apm_##func(ret.val(),toDigits,cval());return ret;}\
541	MAPM func(void) const {return func(myDigits());}
542
543	MAPM_1aryFunc(sqrt)
544	MAPM_1aryFunc(cbrt)
545	MAPM_1aryFunc(log)
546	MAPM_1aryFunc(exp)
547	MAPM_1aryFunc(log10)
548	MAPM_1aryFunc(sin)
549	MAPM_1aryFunc(asin)
550	MAPM_1aryFunc(cos)
551	MAPM_1aryFunc(acos)
552	MAPM_1aryFunc(tan)
553	MAPM_1aryFunc(atan)
554	MAPM_1aryFunc(sinh)
555	MAPM_1aryFunc(asinh)
556	MAPM_1aryFunc(cosh)
557	MAPM_1aryFunc(acosh)
558	MAPM_1aryFunc(tanh)
559	MAPM_1aryFunc(atanh)
560#undef MAPM_1aryFunc
561
562	void sincos(MAPM &sinR,MAPM &cosR,int toDigits)
563		{m_apm_sin_cos(sinR.val(),cosR.val(),toDigits,cval());}
564	void sincos(MAPM &sinR,MAPM &cosR)
565		{sincos(sinR,cosR,myDigits());}
566	MAPM pow(const MAPM &m,int toDigits) const
567		{MAPM ret;m_apm_pow(ret.val(),toDigits,cval(),
568					  m.cval());return ret;}
569	MAPM pow(const MAPM &m) const {return pow(m,digits(m));}
570	MAPM atan2(const MAPM &x,int toDigits) const
571		{MAPM ret;m_apm_arctan2(ret.val(),toDigits,cval(),
572					    x.cval());return ret;}
573	MAPM atan2(const MAPM &x) const
574		{return atan2(x,digits(x));}
575
576	MAPM gcd(const MAPM &m) const
577		{MAPM ret;m_apm_gcd(ret.val(),cval(),m.cval());return ret;}
578
579	MAPM lcm(const MAPM &m) const
580		{MAPM ret;m_apm_lcm(ret.val(),cval(),m.cval());return ret;}
581
582	static MAPM random(void)
583		{MAPM ret;m_apm_get_random(ret.val());return ret;}
584
585	MAPM floor(void) const
586		{MAPM ret;m_apm_floor(ret.val(),cval());return ret;}
587	MAPM ceil(void) const
588		{MAPM ret;m_apm_ceil(ret.val(),cval());return ret;}
589
590	/* Functions defined only on integers: */
591	MAPM factorial(void) const
592		{MAPM ret;m_apm_factorial(ret.val(),cval());return ret;}
593	MAPM ipow_nr(int p) const
594		{MAPM ret;m_apm_integer_pow_nr(ret.val(),
595				cval(),p);return ret;}
596	MAPM ipow(int p,int toDigits) const
597		{MAPM ret;m_apm_integer_pow(ret.val(),
598				toDigits,cval(),p);return ret;}
599	MAPM ipow(int p) const
600		{return ipow(p,myDigits());}
601	MAPM integer_divide(const MAPM &denom) const
602		{MAPM ret;m_apm_integer_divide(ret.val(),cval(),
603		                       denom.cval());return ret;}
604	void integer_div_rem(const MAPM &denom,MAPM &quot,MAPM &rem) const
605		{m_apm_integer_div_rem(quot.val(),rem.val(),cval(),
606					             denom.cval());}
607	MAPM div(const MAPM &denom) const {return integer_divide(denom);}
608	MAPM rem(const MAPM &denom) const {MAPM ret,ignored;
609		integer_div_rem(denom,ignored,ret);return ret;}
610};
611
612/* math.h-style functions: */
613
614inline MAPM fabs(const MAPM &m) {return m.abs();}
615inline MAPM factorial(const MAPM &m) {return m.factorial();}
616inline MAPM floor(const MAPM &m) {return m.floor();}
617inline MAPM ceil(const MAPM &m) {return m.ceil();}
618inline MAPM get_random(void) {return MAPM::random();}
619
620/* I got tired of typing the various declarations for a simple
621   1-ary real-to-real function on MAPM's; hence this define:
622*/
623#define MAPM_1aryFunc(func) \
624	inline MAPM func(const MAPM &m) {return m.func();} \
625	inline MAPM func(const MAPM &m,int toDigits) {return m.func(toDigits);}
626
627/* Define a big block of simple functions: */
628	MAPM_1aryFunc(sqrt)
629	MAPM_1aryFunc(cbrt)
630	MAPM_1aryFunc(log)
631	MAPM_1aryFunc(exp)
632	MAPM_1aryFunc(log10)
633	MAPM_1aryFunc(sin)
634	MAPM_1aryFunc(asin)
635	MAPM_1aryFunc(cos)
636	MAPM_1aryFunc(acos)
637	MAPM_1aryFunc(tan)
638	MAPM_1aryFunc(atan)
639	MAPM_1aryFunc(sinh)
640	MAPM_1aryFunc(asinh)
641	MAPM_1aryFunc(cosh)
642	MAPM_1aryFunc(acosh)
643	MAPM_1aryFunc(tanh)
644	MAPM_1aryFunc(atanh)
645#undef MAPM_1aryFunc
646
647/* Computes x to the power y */
648inline MAPM pow(const MAPM &x,const MAPM &y,int toDigits)
649		{return x.pow(y,toDigits);}
650inline MAPM pow(const MAPM &x,const MAPM &y)
651		{return x.pow(y);}
652inline MAPM atan2(const MAPM &y,const MAPM &x,int toDigits)
653		{return y.atan2(x,toDigits);}
654inline MAPM atan2(const MAPM &y,const MAPM &x)
655		{return y.atan2(x);}
656inline MAPM gcd(const MAPM &u,const MAPM &v)
657		{return u.gcd(v);}
658inline MAPM lcm(const MAPM &u,const MAPM &v)
659		{return u.lcm(v);}
660#endif
661#endif
662
663