xref: /haiku/headers/libs/mapm/m_apm.h (revision 59d799dabcba86f92658ddb402f634e262d9aae7)
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
168 extern "C" {
169 #endif
170 
171 typedef unsigned char UCHAR;
172 
173 typedef 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 
183 typedef 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 
195 extern	M_APM	MM_Zero;
196 extern	M_APM	MM_One;
197 extern	M_APM	MM_Two;
198 extern	M_APM	MM_Three;
199 extern	M_APM	MM_Four;
200 extern	M_APM	MM_Five;
201 extern	M_APM	MM_Ten;
202 
203 extern	M_APM	MM_PI;
204 extern	M_APM	MM_HALF_PI;
205 extern	M_APM	MM_2_PI;
206 extern	M_APM	MM_E;
207 
208 extern	M_APM	MM_LOG_E_BASE_10;
209 extern	M_APM	MM_LOG_10_BASE_E;
210 extern	M_APM	MM_LOG_2_BASE_E;
211 extern	M_APM	MM_LOG_3_BASE_E;
212 
213 
214 /*
215  *	function prototypes
216  */
217 
218 extern	M_APM	m_apm_init(void);
219 extern	void	m_apm_free(M_APM);
220 extern	void	m_apm_free_all_mem(void);
221 extern	void	m_apm_trim_mem_usage(void);
222 extern	char	*m_apm_lib_version(char *);
223 extern	char	*m_apm_lib_short_version(char *);
224 
225 extern	void	m_apm_set_string(M_APM, char *);
226 extern	void	m_apm_set_double(M_APM, double);
227 extern	void	m_apm_set_long(M_APM, long);
228 
229 extern	void	m_apm_to_string(char *, int, M_APM);
230 extern  void	m_apm_to_fixpt_string(char *, int, M_APM);
231 extern  void	m_apm_to_fixpt_stringex(char *, int, M_APM, char, char, int);
232 extern  char	*m_apm_to_fixpt_stringexp(int, M_APM, char, char, int);
233 extern  void    m_apm_to_integer_string(char *, M_APM);
234 
235 extern	void	m_apm_absolute_value(M_APM, M_APM);
236 extern	void	m_apm_negate(M_APM, M_APM);
237 extern	void	m_apm_copy(M_APM, M_APM);
238 extern	void	m_apm_round(M_APM, int, M_APM);
239 extern	int	m_apm_compare(M_APM, M_APM);
240 extern	int	m_apm_sign(M_APM);
241 extern	int	m_apm_exponent(M_APM);
242 extern	int	m_apm_significant_digits(M_APM);
243 extern	int	m_apm_is_integer(M_APM);
244 extern	int	m_apm_is_even(M_APM);
245 extern	int	m_apm_is_odd(M_APM);
246 
247 extern	void	m_apm_gcd(M_APM, M_APM, M_APM);
248 extern	void	m_apm_lcm(M_APM, M_APM, M_APM);
249 
250 extern	void	m_apm_add(M_APM, M_APM, M_APM);
251 extern	void	m_apm_subtract(M_APM, M_APM, M_APM);
252 extern	void	m_apm_multiply(M_APM, M_APM, M_APM);
253 extern	void	m_apm_divide(M_APM, int, M_APM, M_APM);
254 extern	void	m_apm_integer_divide(M_APM, M_APM, M_APM);
255 extern	void	m_apm_integer_div_rem(M_APM, M_APM, M_APM, M_APM);
256 extern	void	m_apm_reciprocal(M_APM, int, M_APM);
257 extern	void	m_apm_factorial(M_APM, M_APM);
258 extern	void	m_apm_floor(M_APM, M_APM);
259 extern	void	m_apm_ceil(M_APM, M_APM);
260 extern	void	m_apm_get_random(M_APM);
261 extern	void	m_apm_set_random_seed(char *);
262 
263 extern	void	m_apm_sqrt(M_APM, int, M_APM);
264 extern	void	m_apm_cbrt(M_APM, int, M_APM);
265 extern	void	m_apm_log(M_APM, int, M_APM);
266 extern	void	m_apm_log10(M_APM, int, M_APM);
267 extern	void	m_apm_exp(M_APM, int, M_APM);
268 extern	void	m_apm_pow(M_APM, int, M_APM, M_APM);
269 extern  void	m_apm_integer_pow(M_APM, int, M_APM, int);
270 extern  void	m_apm_integer_pow_nr(M_APM, M_APM, int);
271 
272 extern	void	m_apm_sin_cos(M_APM, M_APM, int, M_APM);
273 extern	void	m_apm_sin(M_APM, int, M_APM);
274 extern	void	m_apm_cos(M_APM, int, M_APM);
275 extern	void	m_apm_tan(M_APM, int, M_APM);
276 extern	void	m_apm_arcsin(M_APM, int, M_APM);
277 extern	void	m_apm_arccos(M_APM, int, M_APM);
278 extern	void	m_apm_arctan(M_APM, int, M_APM);
279 extern	void	m_apm_arctan2(M_APM, int, M_APM, M_APM);
280 
281 extern  void    m_apm_sinh(M_APM, int, M_APM);
282 extern  void    m_apm_cosh(M_APM, int, M_APM);
283 extern  void    m_apm_tanh(M_APM, int, M_APM);
284 extern  void    m_apm_arcsinh(M_APM, int, M_APM);
285 extern  void    m_apm_arccosh(M_APM, int, M_APM);
286 extern  void    m_apm_arctanh(M_APM, int, M_APM);
287 
288 extern  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 
314 extern
315 #ifdef APM_CONVERT_FROM_C
316 "C"
317 #endif
318 int MM_cpp_min_precision;
319 
320 
321 class MAPM {
322 protected:
323 
324 /*
325 The M_APM structure here is implemented as a reference-
326 counted, copy-on-write data structure-- this makes copies
327 very fast, but that's why it's so ugly.  A MAPM object is
328 basically just a wrapper around a (possibly shared)
329 M_APM_struct myVal.
330 */
331 
332 
333 	M_APM myVal;  /* My M_APM structure */
create(void)334 	void create(void) {myVal=makeNew();}
destroy(void)335 	void destroy(void) {unref(myVal);myVal=NULL;}
copyFrom(M_APM Nval)336 	void copyFrom(M_APM Nval)
337 	{
338 		 M_APM oldVal=myVal;
339 		 myVal=Nval;
340 		 ref(myVal);
341 		 unref(oldVal);
342 	}
makeNew(void)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 	}
ref(M_APM val)349 	static void ref(M_APM val)
350 	{
351 		val->m_apm_refcount++;
352 	}
unref(M_APM val)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. */
val(void)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 	*/
cval(void)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         */
myDigits(void)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         */
digits(const MAPM & otherVal)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 	}
408 public:
409 	/* Constructors: */
MAPM(void)410 	MAPM(void) /* Default constructor (takes no value) */
411 		{create();}
MAPM(const MAPM & m)412 	MAPM(const MAPM &m) /* Copy constructor */
413 		{myVal=(M_APM)m.cval();ref(myVal);}
MAPM(M_APM m)414 	MAPM(M_APM m) /* M_APM constructor (refcount starts at one) */
415 		{myVal=(M_APM)m;ref(myVal);}
MAPM(const char * s)416 	MAPM(const char *s) /* Constructor from string */
417 		{create();m_apm_set_string(val(),(char *)s);}
MAPM(double d)418 	MAPM(double d) /* Constructor from double-precision float */
419 		{create();m_apm_set_double(val(),d);}
MAPM(int l)420 	MAPM(int l) /* Constructor from int */
421 		{create();m_apm_set_long(val(),l);}
MAPM(long l)422 	MAPM(long l) /* Constructor from long int */
423 		{create();m_apm_set_long(val(),l);}
424 	/* Destructor */
~MAPM()425 	~MAPM() {destroy();}
426 
427 	/* Extracting string descriptions: */
toString(char * dest,int decimalPlaces)428 	void toString(char *dest,int decimalPlaces) const
429 		{m_apm_to_string(dest,decimalPlaces,cval());}
toFixPtString(char * dest,int decimalPlaces)430 	void toFixPtString(char *dest,int decimalPlaces) const
431 		{m_apm_to_fixpt_string(dest,decimalPlaces,cval());}
toFixPtStringEx(char * dest,int dp,char a,char b,int c)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);}
toFixPtStringExp(int dp,char a,char b,int 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));}
toIntegerString(char * dest)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 
divide(const MAPM & m,int toDigits)497 	MAPM divide(const MAPM &m,int toDigits) const
498         	{MAPM ret;m_apm_divide(ret.val(),toDigits,cval(),
499 					        m.cval());return ret;}
divide(const MAPM & m)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: */
sign(void)510 	int sign(void) const
511 		{return m_apm_sign(cval());}
exponent(void)512 	int exponent(void) const
513 		{return m_apm_exponent(cval());}
significant_digits(void)514 	int significant_digits(void) const
515 		{return m_apm_significant_digits(cval());}
is_integer(void)516 	int is_integer(void) const
517 		{return m_apm_is_integer(cval());}
is_even(void)518 	int is_even(void) const
519 		{return m_apm_is_even(cval());}
is_odd(void)520 	int is_odd(void) const
521 		{return m_apm_is_odd(cval());}
522 
523 	/* Functions: */
abs(void)524 	MAPM abs(void) const
525 		{MAPM ret;m_apm_absolute_value(ret.val(),cval());return ret;}
neg(void)526 	MAPM neg(void) const
527 		{MAPM ret;m_apm_negate(ret.val(),cval());return ret;}
round(int toDigits)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)
MAPM_1aryFunc(cbrt)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());}
sincos(MAPM & sinR,MAPM & cosR)564 	void sincos(MAPM &sinR,MAPM &cosR)
565 		{sincos(sinR,cosR,myDigits());}
pow(const MAPM & m,int toDigits)566 	MAPM pow(const MAPM &m,int toDigits) const
567 		{MAPM ret;m_apm_pow(ret.val(),toDigits,cval(),
568 					  m.cval());return ret;}
pow(const MAPM & m)569 	MAPM pow(const MAPM &m) const {return pow(m,digits(m));}
atan2(const MAPM & x,int toDigits)570 	MAPM atan2(const MAPM &x,int toDigits) const
571 		{MAPM ret;m_apm_arctan2(ret.val(),toDigits,cval(),
572 					    x.cval());return ret;}
atan2(const MAPM & x)573 	MAPM atan2(const MAPM &x) const
574 		{return atan2(x,digits(x));}
575 
gcd(const MAPM & m)576 	MAPM gcd(const MAPM &m) const
577 		{MAPM ret;m_apm_gcd(ret.val(),cval(),m.cval());return ret;}
578 
lcm(const MAPM & m)579 	MAPM lcm(const MAPM &m) const
580 		{MAPM ret;m_apm_lcm(ret.val(),cval(),m.cval());return ret;}
581 
random(void)582 	static MAPM random(void)
583 		{MAPM ret;m_apm_get_random(ret.val());return ret;}
584 
floor(void)585 	MAPM floor(void) const
586 		{MAPM ret;m_apm_floor(ret.val(),cval());return ret;}
ceil(void)587 	MAPM ceil(void) const
588 		{MAPM ret;m_apm_ceil(ret.val(),cval());return ret;}
589 
590 	/* Functions defined only on integers: */
factorial(void)591 	MAPM factorial(void) const
592 		{MAPM ret;m_apm_factorial(ret.val(),cval());return ret;}
ipow_nr(int p)593 	MAPM ipow_nr(int p) const
594 		{MAPM ret;m_apm_integer_pow_nr(ret.val(),
595 				cval(),p);return ret;}
ipow(int p,int toDigits)596 	MAPM ipow(int p,int toDigits) const
597 		{MAPM ret;m_apm_integer_pow(ret.val(),
598 				toDigits,cval(),p);return ret;}
ipow(int p)599 	MAPM ipow(int p) const
600 		{return ipow(p,myDigits());}
integer_divide(const MAPM & denom)601 	MAPM integer_divide(const MAPM &denom) const
602 		{MAPM ret;m_apm_integer_divide(ret.val(),cval(),
603 		                       denom.cval());return ret;}
integer_div_rem(const MAPM & denom,MAPM & quot,MAPM & rem)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());}
div(const MAPM & denom)607 	MAPM div(const MAPM &denom) const {return integer_divide(denom);}
rem(const MAPM & 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 
fabs(const MAPM & m)614 inline MAPM fabs(const MAPM &m) {return m.abs();}
factorial(const MAPM & m)615 inline MAPM factorial(const MAPM &m) {return m.factorial();}
floor(const MAPM & m)616 inline MAPM floor(const MAPM &m) {return m.floor();}
ceil(const MAPM & m)617 inline MAPM ceil(const MAPM &m) {return m.ceil();}
get_random(void)618 inline 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)
MAPM_1aryFunc(cbrt)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 */
648 inline MAPM pow(const MAPM &x,const MAPM &y,int toDigits)
649 		{return x.pow(y,toDigits);}
pow(const MAPM & x,const MAPM & y)650 inline MAPM pow(const MAPM &x,const MAPM &y)
651 		{return x.pow(y);}
atan2(const MAPM & y,const MAPM & x,int toDigits)652 inline MAPM atan2(const MAPM &y,const MAPM &x,int toDigits)
653 		{return y.atan2(x,toDigits);}
atan2(const MAPM & y,const MAPM & x)654 inline MAPM atan2(const MAPM &y,const MAPM &x)
655 		{return y.atan2(x);}
gcd(const MAPM & u,const MAPM & v)656 inline MAPM gcd(const MAPM &u,const MAPM &v)
657 		{return u.gcd(v);}
lcm(const MAPM & u,const MAPM & v)658 inline MAPM lcm(const MAPM &u,const MAPM &v)
659 		{return u.lcm(v);}
660 #endif
661 #endif
662 
663