Support both μs and us for entering microseconds
[gcalctool.git] / src / mp.h
blob634bb0147757d3f48208b3731edc2b3d1170d000
1 /*
2 * Copyright (C) 1987-2008 Sun Microsystems, Inc. All Rights Reserved.
3 * Copyright (C) 2008-2011 Robert Ancell.
4 *
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
9 * license.
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
27 * THE MP USERS GUIDE.
30 #ifndef MP_H
31 #define MP_H
33 #include <stdbool.h>
34 #include <stdint.h>
35 #include <glib.h>
37 /* Size of the multiple precision values */
38 #define MP_SIZE 1000
40 /* Base for numbers */
41 #define MP_BASE 10000
43 /* Object for a high precision floating point number representation
45 * x = sign * (MP_BASE^(exponent-1) + MP_BASE^(exponent-2) + ...)
47 typedef struct
49 /* Sign (+1, -1) or 0 for the value zero */
50 int sign, im_sign;
52 /* Exponent (to base MP_BASE) */
53 int exponent, im_exponent;
55 /* Normalized fraction */
56 int fraction[MP_SIZE], im_fraction[MP_SIZE];
57 } MPNumber;
59 typedef enum
61 MP_RADIANS,
62 MP_DEGREES,
63 MP_GRADIANS
64 } MPAngleUnit;
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);
73 /* Returns:
74 * 0 if x == y
75 * <0 if x < y
76 * >0 if x > y
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);
113 /* Sets z = |x| */
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);
119 /* Sets z = ‾̅x */
120 void mp_conjugate(const MPNumber *x, MPNumber *z);
122 /* Sets z = Re(x) */
123 void mp_real_component(const MPNumber *x, MPNumber *z);
125 /* Sets z = Im(x) */
126 void mp_imaginary_component(const MPNumber *x, MPNumber *z);
128 /* Sets z = −x */
129 void mp_invert_sign(const MPNumber *x, MPNumber *z);
131 /* Sets z = x + y */
132 void mp_add(const MPNumber *x, const MPNumber *y, MPNumber *z);
134 /* Sets z = x + y */
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);
140 /* Sets z = x − y */
141 void mp_subtract(const MPNumber *x, const MPNumber *y, MPNumber *z);
143 /* Sets z = x × y */
144 void mp_multiply(const MPNumber *x, const MPNumber *y, MPNumber *z);
146 /* Sets z = x × y */
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);
152 /* Sets z = x ÷ y */
153 void mp_divide(const MPNumber *x, const MPNumber *y, MPNumber *z);
155 /* Sets z = x ÷ y */
156 void mp_divide_integer(const MPNumber *x, int64_t y, MPNumber *z);
158 /* Sets z = 1 ÷ x */
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);
169 /* Sets z = {x} */
170 void mp_fractional_part(const MPNumber *x, MPNumber *z);
172 /* Sets z = ⌊x⌋ */
173 void mp_floor(const MPNumber *x, MPNumber *z);
175 /* Sets z = ⌈x⌉ */
176 void mp_ceiling(const MPNumber *x, MPNumber *z);
178 /* Sets z = [x] */
179 void mp_round(const MPNumber *x, MPNumber *z);
181 /* Sets z = ln x */
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);
187 /* Sets z = π */
188 void mp_get_pi(MPNumber *z);
190 /* Sets z = e */
191 void mp_get_eulers(MPNumber *z);
193 /* Sets z = i (√−1) */
194 void mp_get_i(MPNumber *z);
196 /* Sets z = n√x */
197 void mp_root(const MPNumber *x, int64_t n, MPNumber *z);
199 /* Sets z = √x */
200 void mp_sqrt(const MPNumber *x, MPNumber *z);
202 /* Sets z = x! */
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);
208 /* Sets z = x^y */
209 void mp_xpowy(const MPNumber *x, const MPNumber *y, MPNumber *z);
211 /* Sets z = x^y */
212 void mp_xpowy_integer(const MPNumber *x, int64_t y, MPNumber *z);
214 /* Sets z = e^x */
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);
220 /* Sets z = x */
221 void mp_set_from_mp(const MPNumber *x, MPNumber *z);
223 /* Sets z = x */
224 void mp_set_from_float(float x, MPNumber *z);
226 /* Sets z = x */
227 void mp_set_from_double(double x, MPNumber *z);
229 /* Sets z = x */
230 void mp_set_from_integer(int64_t x, MPNumber *z);
232 /* Sets z = x */
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);
264 /* Sets z = sin x */
265 void mp_sin(const MPNumber *x, MPAngleUnit unit, MPNumber *z);
267 /* Sets z = cos x */
268 void mp_cos(const MPNumber *x, MPAngleUnit unit, MPNumber *z);
270 /* Sets z = tan x */
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);
330 #endif /* MP_H */