2 /* Copyright (c) 1987-2008 Sun Microsystems, Inc. All Rights Reserved.
3 * Copyright (c) 2008-2009 Robert Ancell
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21 /* This maths library is based on the MP multi-precision floating-point
22 * arithmetic package originally written in FORTRAN by Richard Brent,
23 * Computer Centre, Australian National University in the 1970's.
25 * It has been converted from FORTRAN into C using the freely available
26 * f2c translator, available via netlib on research.att.com.
28 * The subsequently converted C code has then been tidied up, mainly to
29 * remove any dependencies on the libI77 and libF77 support libraries.
31 * FOR A GENERAL DESCRIPTION OF THE PHILOSOPHY AND DESIGN OF MP,
32 * SEE - R. P. BRENT, A FORTRAN MULTIPLE-PRECISION ARITHMETIC
33 * PACKAGE, ACM TRANS. MATH. SOFTWARE 4 (MARCH 1978), 57-70.
34 * SOME ADDITIONAL DETAILS ARE GIVEN IN THE SAME ISSUE, 71-81.
35 * FOR DETAILS OF THE IMPLEMENTATION, CALLING SEQUENCES ETC. SEE
46 /* Size of the multiple precision values */
49 /* Base for numbers */
52 /* Object for a high precision floating point number representation
54 * x = sign * (MP_BASE^(exponent-1) + MP_BASE^(exponent-2) + ...)
58 /* Sign (+1, -1) or 0 for the value zero */
61 /* Exponent (to base MP_BASE) */
62 int exponent
, im_exponent
;
64 /* Normalized fraction */
65 int fraction
[MP_SIZE
], im_fraction
[MP_SIZE
];
75 /* Returns error string or NULL if no error */
76 // FIXME: Global variable
77 const char *mp_get_error(void);
79 /* Clear any current error */
80 void mp_clear_error(void);
87 int mp_compare_mp_to_mp(const MPNumber
*x
, const MPNumber
*y
);
89 /* Return true if the value is x == 0 */
90 bool mp_is_zero(const MPNumber
*x
);
92 /* Return true if x < 0 */
93 bool mp_is_negative(const MPNumber
*x
);
95 /* Return true if x is integer */
96 bool mp_is_integer(const MPNumber
*x
);
98 /* Return true if x is a positive integer */
99 bool mp_is_positive_integer(const MPNumber
*x
);
101 /* Return true if x is a natural number (an integer ≥ 0) */
102 bool mp_is_natural(const MPNumber
*x
);
104 /* Return true if x has an imaginary component */
105 bool mp_is_complex(const MPNumber
*x
);
107 /* Return true if x == y */
108 bool mp_is_equal(const MPNumber
*x
, const MPNumber
*y
);
110 /* Return true if x ≥ y */
111 bool mp_is_greater_equal(const MPNumber
*x
, const MPNumber
*y
);
113 /* Return true if x > y */
114 bool mp_is_greater_than(const MPNumber
*x
, const MPNumber
*y
);
116 /* Return true if x ≤ y */
117 bool mp_is_less_equal(const MPNumber
*x
, const MPNumber
*y
);
119 /* Return true if x < y */
120 bool mp_is_less_than(const MPNumber
*x
, const MPNumber
*y
);
123 void mp_abs(const MPNumber
*x
, MPNumber
*z
);
125 /* Sets z = Arg(x) */
126 void mp_arg(const MPNumber
*x
, MPAngleUnit unit
, MPNumber
*z
);
129 void mp_conjugate(const MPNumber
*x
, MPNumber
*z
);
132 void mp_real_component(const MPNumber
*x
, MPNumber
*z
);
135 void mp_imaginary_component(const MPNumber
*x
, MPNumber
*z
);
138 void mp_invert_sign(const MPNumber
*x
, MPNumber
*z
);
141 void mp_add(const MPNumber
*x
, const MPNumber
*y
, MPNumber
*z
);
144 void mp_add_integer(const MPNumber
*x
, int64_t y
, MPNumber
*z
);
146 /* Sets z = x + numerator ÷ denominator */
147 void mp_add_fraction(const MPNumber
*x
, int64_t numerator
, int64_t denominator
, MPNumber
*z
);
150 void mp_subtract(const MPNumber
*x
, const MPNumber
*y
, MPNumber
*z
);
153 void mp_multiply(const MPNumber
*x
, const MPNumber
*y
, MPNumber
*z
);
156 void mp_multiply_integer(const MPNumber
*x
, int64_t y
, MPNumber
*z
);
158 /* Sets z = x × numerator ÷ denominator */
159 void mp_multiply_fraction(const MPNumber
*x
, int64_t numerator
, int64_t denominator
, MPNumber
*z
);
162 void mp_divide(const MPNumber
*x
, const MPNumber
*y
, MPNumber
*z
);
165 void mp_divide_integer(const MPNumber
*x
, int64_t y
, MPNumber
*z
);
168 void mp_reciprocal(const MPNumber
*, MPNumber
*);
170 /* Sets z = sgn(x) */
171 void mp_sgn(const MPNumber
*x
, MPNumber
*z
);
173 void mp_integer_component(const MPNumber
*x
, MPNumber
*z
);
175 /* Sets z = x mod 1 */
176 void mp_fractional_component(const MPNumber
*x
, MPNumber
*z
);
179 void mp_fractional_part(const MPNumber
*x
, MPNumber
*z
);
182 void mp_floor(const MPNumber
*x
, MPNumber
*z
);
185 void mp_ceiling(const MPNumber
*x
, MPNumber
*z
);
188 void mp_round(const MPNumber
*x
, MPNumber
*z
);
191 void mp_ln(const MPNumber
*x
, MPNumber
*z
);
193 /* Sets z = log_n x */
194 void mp_logarithm(int64_t n
, const MPNumber
*x
, MPNumber
*z
);
197 void mp_get_pi(MPNumber
*z
);
200 void mp_get_eulers(MPNumber
*z
);
202 /* Sets z = i (√−1) */
203 void mp_get_i(MPNumber
*z
);
206 void mp_root(const MPNumber
*x
, int64_t n
, MPNumber
*z
);
209 void mp_sqrt(const MPNumber
*x
, MPNumber
*z
);
212 void mp_factorial(const MPNumber
*x
, MPNumber
*z
);
214 /* Sets z = x mod y */
215 void mp_modulus_divide(const MPNumber
*x
, const MPNumber
*y
, MPNumber
*z
);
218 void mp_xpowy(const MPNumber
*x
, const MPNumber
*y
, MPNumber
*z
);
221 void mp_xpowy_integer(const MPNumber
*x
, int64_t y
, MPNumber
*z
);
224 void mp_epowy(const MPNumber
*x
, MPNumber
*z
);
226 /* Returns a list of all prime factors in x as MPNumbers */
227 GList
* mp_factorize(const MPNumber
*x
);
230 void mp_set_from_mp(const MPNumber
*x
, MPNumber
*z
);
233 void mp_set_from_float(float x
, MPNumber
*z
);
236 void mp_set_from_double(double x
, MPNumber
*z
);
239 void mp_set_from_integer(int64_t x
, MPNumber
*z
);
242 void mp_set_from_unsigned_integer(uint64_t x
, MPNumber
*z
);
244 /* Sets z = numerator ÷ denominator */
245 void mp_set_from_fraction(int64_t numerator
, int64_t denominator
, MPNumber
*z
);
247 /* Sets z = r(cos theta + i sin theta) */
248 void mp_set_from_polar(const MPNumber
*r
, MPAngleUnit unit
, const MPNumber
*theta
, MPNumber
*z
);
250 /* Sets z = x + iy */
251 void mp_set_from_complex(const MPNumber
*x
, const MPNumber
*y
, MPNumber
*z
);
253 /* Sets z to be a uniform random number in the range [0, 1] */
254 void mp_set_from_random(MPNumber
*z
);
256 /* Sets z from a string representation in 'text'.
257 * Returns true on success.
259 bool mp_set_from_string(const char *text
, int default_base
, MPNumber
*z
);
261 /* Returns x as a native single-precision floating point number */
262 float mp_cast_to_float(const MPNumber
*x
);
264 /* Returns x as a native double-precision floating point number */
265 double mp_cast_to_double(const MPNumber
*x
);
267 /* Returns x as a native integer */
268 int64_t mp_cast_to_int(const MPNumber
*x
);
270 /* Returns x as a native unsigned integer */
271 uint64_t mp_cast_to_unsigned_int(const MPNumber
*x
);
274 void mp_sin(const MPNumber
*x
, MPAngleUnit unit
, MPNumber
*z
);
277 void mp_cos(const MPNumber
*x
, MPAngleUnit unit
, MPNumber
*z
);
280 void mp_tan(const MPNumber
*x
, MPAngleUnit unit
, MPNumber
*z
);
282 /* Sets z = sin⁻¹ x */
283 void mp_asin(const MPNumber
*x
, MPAngleUnit unit
, MPNumber
*z
);
285 /* Sets z = cos⁻¹ x */
286 void mp_acos(const MPNumber
*x
, MPAngleUnit unit
, MPNumber
*z
);
288 /* Sets z = tan⁻¹ x */
289 void mp_atan(const MPNumber
*x
, MPAngleUnit unit
, MPNumber
*z
);
291 /* Sets z = sinh x */
292 void mp_sinh(const MPNumber
*x
, MPNumber
*z
);
294 /* Sets z = cosh x */
295 void mp_cosh(const MPNumber
*x
, MPNumber
*z
);
297 /* Sets z = tanh x */
298 void mp_tanh(const MPNumber
*x
, MPNumber
*z
);
300 /* Sets z = sinh⁻¹ x */
301 void mp_asinh(const MPNumber
*x
, MPNumber
*z
);
303 /* Sets z = cosh⁻¹ x */
304 void mp_acosh(const MPNumber
*x
, MPNumber
*z
);
306 /* Sets z = tanh⁻¹ x */
307 void mp_atanh(const MPNumber
*x
, MPNumber
*z
);
309 /* Returns true if x is cannot be represented in a binary word of length 'wordlen' */
310 bool mp_is_overflow(const MPNumber
*x
, int wordlen
);
312 /* Sets z = boolean AND for each bit in x and z */
313 void mp_and(const MPNumber
*x
, const MPNumber
*y
, MPNumber
*z
);
315 /* Sets z = boolean OR for each bit in x and z */
316 void mp_or(const MPNumber
*x
, const MPNumber
*y
, MPNumber
*z
);
318 /* Sets z = boolean XOR for each bit in x and z */
319 void mp_xor(const MPNumber
*x
, const MPNumber
*y
, MPNumber
*z
);
321 /* Sets z = boolean XNOR for each bit in x and z for word of length 'wordlen' */
322 void mp_xnor(const MPNumber
*x
, const MPNumber
*y
, int wordlen
, MPNumber
*z
);
324 /* Sets z = boolean NOT for each bit in x and z for word of length 'wordlen' */
325 void mp_not(const MPNumber
*x
, int wordlen
, MPNumber
*z
);
327 /* Sets z = x masked to 'wordlen' bits */
328 void mp_mask(const MPNumber
*x
, int wordlen
, MPNumber
*z
);
330 /* Sets z = x shifted by 'count' bits. Positive shift increases the value, negative decreases */
331 void mp_shift(const MPNumber
*x
, int count
, MPNumber
*z
);
333 /* Sets z to be the ones complement of x for word of length 'wordlen' */
334 void mp_ones_complement(const MPNumber
*x
, int wordlen
, MPNumber
*z
);
336 /* Sets z to be the twos complement of x for word of length 'wordlen' */
337 void mp_twos_complement(const MPNumber
*x
, int wordlen
, MPNumber
*z
);