2 * Copyright (C) 1987-2008 Sun Microsystems, Inc. All Rights Reserved.
3 * Copyright (C) 2008-2011 Robert Ancell.
5 * This program is free software: you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License as published by the Free Software
7 * Foundation, either version 2 of the License, or (at your option) any later
8 * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
12 /* This maths library is based on the MP multi-precision floating-point
13 * arithmetic package originally written in FORTRAN by Richard Brent,
14 * Computer Centre, Australian National University in the 1970's.
16 * It has been converted from FORTRAN into C using the freely available
17 * f2c translator, available via netlib on research.att.com.
19 * The subsequently converted C code has then been tidied up, mainly to
20 * remove any dependencies on the libI77 and libF77 support libraries.
22 * FOR A GENERAL DESCRIPTION OF THE PHILOSOPHY AND DESIGN OF MP,
23 * SEE - R. P. BRENT, A FORTRAN MULTIPLE-PRECISION ARITHMETIC
24 * PACKAGE, ACM TRANS. MATH. SOFTWARE 4 (MARCH 1978), 57-70.
25 * SOME ADDITIONAL DETAILS ARE GIVEN IN THE SAME ISSUE, 71-81.
26 * FOR DETAILS OF THE IMPLEMENTATION, CALLING SEQUENCES ETC. SEE
37 /* Size of the multiple precision values */
40 /* Base for numbers */
43 /* Object for a high precision floating point number representation
45 * x = sign * (MP_BASE^(exponent-1) + MP_BASE^(exponent-2) + ...)
49 /* Sign (+1, -1) or 0 for the value zero */
52 /* Exponent (to base MP_BASE) */
53 int exponent
, im_exponent
;
55 /* Normalized fraction */
56 int fraction
[MP_SIZE
], im_fraction
[MP_SIZE
];
66 /* Returns error string or NULL if no error */
67 // FIXME: Global variable
68 const char *mp_get_error(void);
70 /* Clear any current error */
71 void mp_clear_error(void);
78 int mp_compare_mp_to_mp(const MPNumber
*x
, const MPNumber
*y
);
80 /* Return true if the value is x == 0 */
81 bool mp_is_zero(const MPNumber
*x
);
83 /* Return true if x < 0 */
84 bool mp_is_negative(const MPNumber
*x
);
86 /* Return true if x is integer */
87 bool mp_is_integer(const MPNumber
*x
);
89 /* Return true if x is a positive integer */
90 bool mp_is_positive_integer(const MPNumber
*x
);
92 /* Return true if x is a natural number (an integer ≥ 0) */
93 bool mp_is_natural(const MPNumber
*x
);
95 /* Return true if x has an imaginary component */
96 bool mp_is_complex(const MPNumber
*x
);
98 /* Return true if x == y */
99 bool mp_is_equal(const MPNumber
*x
, const MPNumber
*y
);
101 /* Return true if x ≥ y */
102 bool mp_is_greater_equal(const MPNumber
*x
, const MPNumber
*y
);
104 /* Return true if x > y */
105 bool mp_is_greater_than(const MPNumber
*x
, const MPNumber
*y
);
107 /* Return true if x ≤ y */
108 bool mp_is_less_equal(const MPNumber
*x
, const MPNumber
*y
);
110 /* Return true if x < y */
111 bool mp_is_less_than(const MPNumber
*x
, const MPNumber
*y
);
114 void mp_abs(const MPNumber
*x
, MPNumber
*z
);
116 /* Sets z = Arg(x) */
117 void mp_arg(const MPNumber
*x
, MPAngleUnit unit
, MPNumber
*z
);
120 void mp_conjugate(const MPNumber
*x
, MPNumber
*z
);
123 void mp_real_component(const MPNumber
*x
, MPNumber
*z
);
126 void mp_imaginary_component(const MPNumber
*x
, MPNumber
*z
);
129 void mp_invert_sign(const MPNumber
*x
, MPNumber
*z
);
132 void mp_add(const MPNumber
*x
, const MPNumber
*y
, MPNumber
*z
);
135 void mp_add_integer(const MPNumber
*x
, int64_t y
, MPNumber
*z
);
137 /* Sets z = x + numerator ÷ denominator */
138 void mp_add_fraction(const MPNumber
*x
, int64_t numerator
, int64_t denominator
, MPNumber
*z
);
141 void mp_subtract(const MPNumber
*x
, const MPNumber
*y
, MPNumber
*z
);
144 void mp_multiply(const MPNumber
*x
, const MPNumber
*y
, MPNumber
*z
);
147 void mp_multiply_integer(const MPNumber
*x
, int64_t y
, MPNumber
*z
);
149 /* Sets z = x × numerator ÷ denominator */
150 void mp_multiply_fraction(const MPNumber
*x
, int64_t numerator
, int64_t denominator
, MPNumber
*z
);
153 void mp_divide(const MPNumber
*x
, const MPNumber
*y
, MPNumber
*z
);
156 void mp_divide_integer(const MPNumber
*x
, int64_t y
, MPNumber
*z
);
159 void mp_reciprocal(const MPNumber
*, MPNumber
*);
161 /* Sets z = sgn(x) */
162 void mp_sgn(const MPNumber
*x
, MPNumber
*z
);
164 void mp_integer_component(const MPNumber
*x
, MPNumber
*z
);
166 /* Sets z = x mod 1 */
167 void mp_fractional_component(const MPNumber
*x
, MPNumber
*z
);
170 void mp_fractional_part(const MPNumber
*x
, MPNumber
*z
);
173 void mp_floor(const MPNumber
*x
, MPNumber
*z
);
176 void mp_ceiling(const MPNumber
*x
, MPNumber
*z
);
179 void mp_round(const MPNumber
*x
, MPNumber
*z
);
182 void mp_ln(const MPNumber
*x
, MPNumber
*z
);
184 /* Sets z = log_n x */
185 void mp_logarithm(int64_t n
, const MPNumber
*x
, MPNumber
*z
);
188 void mp_get_pi(MPNumber
*z
);
191 void mp_get_eulers(MPNumber
*z
);
193 /* Sets z = i (√−1) */
194 void mp_get_i(MPNumber
*z
);
197 void mp_root(const MPNumber
*x
, int64_t n
, MPNumber
*z
);
200 void mp_sqrt(const MPNumber
*x
, MPNumber
*z
);
203 void mp_factorial(const MPNumber
*x
, MPNumber
*z
);
205 /* Sets z = x mod y */
206 void mp_modulus_divide(const MPNumber
*x
, const MPNumber
*y
, MPNumber
*z
);
209 void mp_xpowy(const MPNumber
*x
, const MPNumber
*y
, MPNumber
*z
);
212 void mp_xpowy_integer(const MPNumber
*x
, int64_t y
, MPNumber
*z
);
215 void mp_epowy(const MPNumber
*x
, MPNumber
*z
);
217 /* Returns a list of all prime factors in x as MPNumbers */
218 GList
* mp_factorize(const MPNumber
*x
);
221 void mp_set_from_mp(const MPNumber
*x
, MPNumber
*z
);
224 void mp_set_from_float(float x
, MPNumber
*z
);
227 void mp_set_from_double(double x
, MPNumber
*z
);
230 void mp_set_from_integer(int64_t x
, MPNumber
*z
);
233 void mp_set_from_unsigned_integer(uint64_t x
, MPNumber
*z
);
235 /* Sets z = numerator ÷ denominator */
236 void mp_set_from_fraction(int64_t numerator
, int64_t denominator
, MPNumber
*z
);
238 /* Sets z = r(cos theta + i sin theta) */
239 void mp_set_from_polar(const MPNumber
*r
, MPAngleUnit unit
, const MPNumber
*theta
, MPNumber
*z
);
241 /* Sets z = x + iy */
242 void mp_set_from_complex(const MPNumber
*x
, const MPNumber
*y
, MPNumber
*z
);
244 /* Sets z to be a uniform random number in the range [0, 1] */
245 void mp_set_from_random(MPNumber
*z
);
247 /* Sets z from a string representation in 'text'.
248 * Returns true on success.
250 bool mp_set_from_string(const char *text
, int default_base
, MPNumber
*z
);
252 /* Returns x as a native single-precision floating point number */
253 float mp_cast_to_float(const MPNumber
*x
);
255 /* Returns x as a native double-precision floating point number */
256 double mp_cast_to_double(const MPNumber
*x
);
258 /* Returns x as a native integer */
259 int64_t mp_cast_to_int(const MPNumber
*x
);
261 /* Returns x as a native unsigned integer */
262 uint64_t mp_cast_to_unsigned_int(const MPNumber
*x
);
265 void mp_sin(const MPNumber
*x
, MPAngleUnit unit
, MPNumber
*z
);
268 void mp_cos(const MPNumber
*x
, MPAngleUnit unit
, MPNumber
*z
);
271 void mp_tan(const MPNumber
*x
, MPAngleUnit unit
, MPNumber
*z
);
273 /* Sets z = sin⁻¹ x */
274 void mp_asin(const MPNumber
*x
, MPAngleUnit unit
, MPNumber
*z
);
276 /* Sets z = cos⁻¹ x */
277 void mp_acos(const MPNumber
*x
, MPAngleUnit unit
, MPNumber
*z
);
279 /* Sets z = tan⁻¹ x */
280 void mp_atan(const MPNumber
*x
, MPAngleUnit unit
, MPNumber
*z
);
282 /* Sets z = sinh x */
283 void mp_sinh(const MPNumber
*x
, MPNumber
*z
);
285 /* Sets z = cosh x */
286 void mp_cosh(const MPNumber
*x
, MPNumber
*z
);
288 /* Sets z = tanh x */
289 void mp_tanh(const MPNumber
*x
, MPNumber
*z
);
291 /* Sets z = sinh⁻¹ x */
292 void mp_asinh(const MPNumber
*x
, MPNumber
*z
);
294 /* Sets z = cosh⁻¹ x */
295 void mp_acosh(const MPNumber
*x
, MPNumber
*z
);
297 /* Sets z = tanh⁻¹ x */
298 void mp_atanh(const MPNumber
*x
, MPNumber
*z
);
300 /* Returns true if x is cannot be represented in a binary word of length 'wordlen' */
301 bool mp_is_overflow(const MPNumber
*x
, int wordlen
);
303 /* Sets z = boolean AND for each bit in x and z */
304 void mp_and(const MPNumber
*x
, const MPNumber
*y
, MPNumber
*z
);
306 /* Sets z = boolean OR for each bit in x and z */
307 void mp_or(const MPNumber
*x
, const MPNumber
*y
, MPNumber
*z
);
309 /* Sets z = boolean XOR for each bit in x and z */
310 void mp_xor(const MPNumber
*x
, const MPNumber
*y
, MPNumber
*z
);
312 /* Sets z = boolean XNOR for each bit in x and z for word of length 'wordlen' */
313 void mp_xnor(const MPNumber
*x
, const MPNumber
*y
, int wordlen
, MPNumber
*z
);
315 /* Sets z = boolean NOT for each bit in x and z for word of length 'wordlen' */
316 void mp_not(const MPNumber
*x
, int wordlen
, MPNumber
*z
);
318 /* Sets z = x masked to 'wordlen' bits */
319 void mp_mask(const MPNumber
*x
, int wordlen
, MPNumber
*z
);
321 /* Sets z = x shifted by 'count' bits. Positive shift increases the value, negative decreases */
322 void mp_shift(const MPNumber
*x
, int count
, MPNumber
*z
);
324 /* Sets z to be the ones complement of x for word of length 'wordlen' */
325 void mp_ones_complement(const MPNumber
*x
, int wordlen
, MPNumber
*z
);
327 /* Sets z to be the twos complement of x for word of length 'wordlen' */
328 void mp_twos_complement(const MPNumber
*x
, int wordlen
, MPNumber
*z
);