• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2008-2024 Stefan Krah. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 
28 #ifndef LIBMPDEC_MPDECIMAL_H_
29 #define LIBMPDEC_MPDECIMAL_H_
30 
31 
32 #ifdef __cplusplus
33   #include <cinttypes>
34   #include <climits>
35   #include <cstdint>
36   #include <cstdio>
37   #include <cstdlib>
38   #define MPD_UINT8_C(x) (static_cast<uint8_t>(x))
39 extern "C" {
40 #else
41   #include <inttypes.h>
42   #include <limits.h>
43   #include <stdint.h>
44   #include <stdio.h>
45   #include <stdlib.h>
46   #define MPD_UINT8_C(x) ((uint8_t)x)
47   #undef inline
48   #define inline __inline
49 #endif
50 
51 
52 #define MPD_PRAGMA(x)
53 #define MPD_HIDE_SYMBOLS_START
54 #define MPD_HIDE_SYMBOLS_END
55 #define EXTINLINE extern inline
56 
57 #define IMPORTEXPORT
58 
59 #if defined (BUILD_LIBMPDEC)
60   #undef IMPORTEXPORT
61   #define IMPORTEXPORT __declspec(dllexport)
62 #elif defined(_DLL)
63   #undef IMPORTEXPORT
64   #define IMPORTEXPORT __declspec(dllimport)
65 #endif
66 
67 
68 /******************************************************************************/
69 /*                                  Version                                   */
70 /******************************************************************************/
71 
72 #define MPD_MAJOR_VERSION 4
73 #define MPD_MINOR_VERSION 0
74 #define MPD_MICRO_VERSION 0
75 
76 #define MPD_VERSION "4.0.0"
77 
78 #define MPD_VERSION_HEX ((MPD_MAJOR_VERSION << 24) | \
79                          (MPD_MINOR_VERSION << 16) | \
80                          (MPD_MICRO_VERSION <<  8))
81 
82 IMPORTEXPORT const char *mpd_version(void);
83 
84 
85 /******************************************************************************/
86 /*                      Types for 64 bit architectures                        */
87 /******************************************************************************/
88 
89 /* ABI: 64-bit */
90 #define MPD_CONFIG_64 1
91 
92 #ifdef MPD_CONFIG_32
93   #error "cannot use MPD_CONFIG_32 with 64-bit header."
94 #endif
95 
96 #ifdef CONFIG_32
97   #error "cannot use CONFIG_32 with 64-bit header."
98 #endif
99 
100 
101 /* types for modular and base arithmetic */
102 #define MPD_UINT_MAX UINT64_MAX
103 #define MPD_BITS_PER_UINT 64
104 typedef uint64_t mpd_uint_t;  /* unsigned mod type */
105 
106 #define MPD_SIZE_MAX SIZE_MAX
107 typedef size_t mpd_size_t; /* unsigned size type */
108 
109 /* type for exp, digits, len, prec */
110 #define MPD_SSIZE_MAX INT64_MAX
111 #define MPD_SSIZE_MIN INT64_MIN
112 typedef int64_t mpd_ssize_t;
113 #define _mpd_strtossize strtoll
114 
115 /* decimal arithmetic */
116 #define MPD_RADIX 10000000000000000000ULL  /* 10**19 */
117 #define MPD_RDIGITS 19
118 #define MPD_MAX_POW10 19
119 #define MPD_EXPDIGITS 19  /* MPD_EXPDIGITS <= MPD_RDIGITS+1 */
120 
121 #define MPD_MAXTRANSFORM_2N 4294967296ULL      /* 2**32 */
122 #define MPD_MAX_PREC 999999999999999999LL
123 #define MPD_MAX_PREC_LOG2 64
124 #define MPD_ELIMIT  1000000000000000000LL
125 #define MPD_MAX_EMAX   999999999999999999LL    /* ELIMIT-1 */
126 #define MPD_MIN_EMIN  (-999999999999999999LL)  /* -EMAX */
127 #define MPD_MIN_ETINY (MPD_MIN_EMIN-(MPD_MAX_PREC-1))
128 #define MPD_EXP_INF 2000000000000000001LL
129 #define MPD_EXP_CLAMP (-4000000000000000001LL)
130 #define MPD_MAXIMPORT 105263157894736842L /* ceil((2*MPD_MAX_PREC)/MPD_RDIGITS) */
131 #define MPD_IEEE_CONTEXT_MAX_BITS 512     /* 16*(log2(MPD_MAX_EMAX / 3)-3) */
132 
133 /* conversion specifiers */
134 #define PRI_mpd_uint_t PRIu64
135 #define PRI_mpd_ssize_t PRIi64
136 
137 #if MPD_SIZE_MAX != MPD_UINT_MAX
138   #error "unsupported platform: need mpd_size_t == mpd_uint_t"
139 #endif
140 
141 
142 /******************************************************************************/
143 /*                                Context                                     */
144 /******************************************************************************/
145 
146 enum {
147     MPD_ROUND_UP,          /* round away from 0               */
148     MPD_ROUND_DOWN,        /* round toward 0 (truncate)       */
149     MPD_ROUND_CEILING,     /* round toward +infinity          */
150     MPD_ROUND_FLOOR,       /* round toward -infinity          */
151     MPD_ROUND_HALF_UP,     /* 0.5 is rounded up               */
152     MPD_ROUND_HALF_DOWN,   /* 0.5 is rounded down             */
153     MPD_ROUND_HALF_EVEN,   /* 0.5 is rounded to even          */
154     MPD_ROUND_05UP,        /* round zero or five away from 0  */
155     MPD_ROUND_TRUNC,       /* truncate, but set infinity      */
156     MPD_ROUND_GUARD
157 };
158 
159 enum { MPD_CLAMP_DEFAULT, MPD_CLAMP_IEEE_754, MPD_CLAMP_GUARD };
160 
161 IMPORTEXPORT extern const char * const mpd_round_string[MPD_ROUND_GUARD];
162 IMPORTEXPORT extern const char * const mpd_clamp_string[MPD_CLAMP_GUARD];
163 
164 
165 typedef struct mpd_context_t {
166     mpd_ssize_t prec;   /* precision */
167     mpd_ssize_t emax;   /* max positive exp */
168     mpd_ssize_t emin;   /* min negative exp */
169     uint32_t traps;     /* status events that should be trapped */
170     uint32_t status;    /* status flags */
171     uint32_t newtrap;   /* set by mpd_addstatus_raise() */
172     int      round;     /* rounding mode */
173     int      clamp;     /* clamp mode */
174     int      allcr;     /* all functions correctly rounded */
175 } mpd_context_t;
176 
177 
178 /* Status flags */
179 #define MPD_Clamped             0x00000001U
180 #define MPD_Conversion_syntax   0x00000002U
181 #define MPD_Division_by_zero    0x00000004U
182 #define MPD_Division_impossible 0x00000008U
183 #define MPD_Division_undefined  0x00000010U
184 #define MPD_Fpu_error           0x00000020U
185 #define MPD_Inexact             0x00000040U
186 #define MPD_Invalid_context     0x00000080U
187 #define MPD_Invalid_operation   0x00000100U
188 #define MPD_Malloc_error        0x00000200U
189 #define MPD_Not_implemented     0x00000400U
190 #define MPD_Overflow            0x00000800U
191 #define MPD_Rounded             0x00001000U
192 #define MPD_Subnormal           0x00002000U
193 #define MPD_Underflow           0x00004000U
194 #define MPD_Max_status         (0x00008000U-1U)
195 
196 /* Conditions that result in an IEEE 754 exception */
197 #define MPD_IEEE_Invalid_operation (MPD_Conversion_syntax |   \
198                                     MPD_Division_impossible | \
199                                     MPD_Division_undefined |  \
200                                     MPD_Fpu_error |           \
201                                     MPD_Invalid_context |     \
202                                     MPD_Invalid_operation |   \
203                                     MPD_Malloc_error)         \
204 
205 /* Errors that require the result of an operation to be set to NaN */
206 #define MPD_Errors (MPD_IEEE_Invalid_operation | \
207                     MPD_Division_by_zero)
208 
209 /* Default traps */
210 #define MPD_Traps (MPD_IEEE_Invalid_operation | \
211                    MPD_Division_by_zero |       \
212                    MPD_Overflow |               \
213                    MPD_Underflow)
214 
215 /* Official name */
216 #define MPD_Insufficient_storage MPD_Malloc_error
217 
218 /* IEEE 754 interchange format contexts */
219 #define MPD_DECIMAL32 32
220 #define MPD_DECIMAL64 64
221 #define MPD_DECIMAL128 128
222 
223 
224 #define MPD_MINALLOC_MIN 2
225 #define MPD_MINALLOC_MAX 64
226 IMPORTEXPORT extern mpd_ssize_t MPD_MINALLOC;
227 IMPORTEXPORT extern void (* mpd_traphandler)(mpd_context_t *);
228 IMPORTEXPORT void mpd_dflt_traphandler(mpd_context_t *);
229 
230 IMPORTEXPORT void mpd_setminalloc(mpd_ssize_t n);
231 IMPORTEXPORT void mpd_init(mpd_context_t *ctx, mpd_ssize_t prec);
232 
233 IMPORTEXPORT void mpd_maxcontext(mpd_context_t *ctx);
234 IMPORTEXPORT void mpd_defaultcontext(mpd_context_t *ctx);
235 IMPORTEXPORT void mpd_basiccontext(mpd_context_t *ctx);
236 IMPORTEXPORT int mpd_ieee_context(mpd_context_t *ctx, int bits);
237 
238 IMPORTEXPORT mpd_ssize_t mpd_getprec(const mpd_context_t *ctx);
239 IMPORTEXPORT mpd_ssize_t mpd_getemax(const mpd_context_t *ctx);
240 IMPORTEXPORT mpd_ssize_t mpd_getemin(const mpd_context_t *ctx);
241 IMPORTEXPORT int mpd_getround(const mpd_context_t *ctx);
242 IMPORTEXPORT uint32_t mpd_gettraps(const mpd_context_t *ctx);
243 IMPORTEXPORT uint32_t mpd_getstatus(const mpd_context_t *ctx);
244 IMPORTEXPORT int mpd_getclamp(const mpd_context_t *ctx);
245 IMPORTEXPORT int mpd_getcr(const mpd_context_t *ctx);
246 
247 IMPORTEXPORT int mpd_qsetprec(mpd_context_t *ctx, mpd_ssize_t prec);
248 IMPORTEXPORT int mpd_qsetemax(mpd_context_t *ctx, mpd_ssize_t emax);
249 IMPORTEXPORT int mpd_qsetemin(mpd_context_t *ctx, mpd_ssize_t emin);
250 IMPORTEXPORT int mpd_qsetround(mpd_context_t *ctx, int newround);
251 IMPORTEXPORT int mpd_qsettraps(mpd_context_t *ctx, uint32_t flags);
252 IMPORTEXPORT int mpd_qsetstatus(mpd_context_t *ctx, uint32_t flags);
253 IMPORTEXPORT int mpd_qsetclamp(mpd_context_t *ctx, int c);
254 IMPORTEXPORT int mpd_qsetcr(mpd_context_t *ctx, int c);
255 IMPORTEXPORT void mpd_addstatus_raise(mpd_context_t *ctx, uint32_t flags);
256 
257 
258 /******************************************************************************/
259 /*                           Decimal Arithmetic                               */
260 /******************************************************************************/
261 
262 /* mpd_t flags */
263 #define MPD_POS                 MPD_UINT8_C(0)
264 #define MPD_NEG                 MPD_UINT8_C(1)
265 #define MPD_INF                 MPD_UINT8_C(2)
266 #define MPD_NAN                 MPD_UINT8_C(4)
267 #define MPD_SNAN                MPD_UINT8_C(8)
268 #define MPD_SPECIAL (MPD_INF|MPD_NAN|MPD_SNAN)
269 #define MPD_STATIC              MPD_UINT8_C(16)
270 #define MPD_STATIC_DATA         MPD_UINT8_C(32)
271 #define MPD_SHARED_DATA         MPD_UINT8_C(64)
272 #define MPD_CONST_DATA          MPD_UINT8_C(128)
273 #define MPD_DATAFLAGS (MPD_STATIC_DATA|MPD_SHARED_DATA|MPD_CONST_DATA)
274 
275 /* mpd_t */
276 typedef struct mpd_t {
277     uint8_t flags;
278     mpd_ssize_t exp;
279     mpd_ssize_t digits;
280     mpd_ssize_t len;
281     mpd_ssize_t alloc;
282     mpd_uint_t *data;
283 } mpd_t;
284 
285 
286 /******************************************************************************/
287 /*                                    Triple                                  */
288 /******************************************************************************/
289 
290 /* status cases for getting a triple */
291 enum mpd_triple_class {
292   MPD_TRIPLE_NORMAL,
293   MPD_TRIPLE_INF,
294   MPD_TRIPLE_QNAN,
295   MPD_TRIPLE_SNAN,
296   MPD_TRIPLE_ERROR,
297 };
298 
299 typedef struct {
300   enum mpd_triple_class tag;
301   uint8_t sign;
302   uint64_t hi;
303   uint64_t lo;
304   int64_t exp;
305 } mpd_uint128_triple_t;
306 
307 IMPORTEXPORT int mpd_from_uint128_triple(mpd_t *result, const mpd_uint128_triple_t *triple, uint32_t *status);
308 IMPORTEXPORT mpd_uint128_triple_t mpd_as_uint128_triple(const mpd_t *a);
309 
310 
311 /******************************************************************************/
312 /*                       Quiet, thread-safe functions                         */
313 /******************************************************************************/
314 
315 /* format specification */
316 typedef struct mpd_spec_t {
317     mpd_ssize_t min_width; /* minimum field width */
318     mpd_ssize_t prec;      /* fraction digits or significant digits */
319     char type;             /* conversion specifier */
320     char align;            /* alignment */
321     char sign;             /* sign printing/alignment */
322     char sign_coerce;      /* coerce to positive zero */
323     char fill[5];          /* fill character */
324     const char *dot;       /* decimal point */
325     const char *sep;       /* thousands separator */
326     const char *grouping;  /* grouping of digits */
327 } mpd_spec_t;
328 
329 /* output to a string */
330 IMPORTEXPORT char *mpd_to_sci(const mpd_t *dec, int fmt);
331 IMPORTEXPORT char *mpd_to_eng(const mpd_t *dec, int fmt);
332 IMPORTEXPORT mpd_ssize_t mpd_to_sci_size(char **res, const mpd_t *dec, int fmt);
333 IMPORTEXPORT mpd_ssize_t mpd_to_eng_size(char **res, const mpd_t *dec, int fmt);
334 IMPORTEXPORT int mpd_validate_lconv(mpd_spec_t *spec);
335 IMPORTEXPORT int mpd_parse_fmt_str(mpd_spec_t *spec, const char *fmt, int caps);
336 IMPORTEXPORT char *mpd_qformat_spec(const mpd_t *dec, const mpd_spec_t *spec, const mpd_context_t *ctx, uint32_t *status);
337 IMPORTEXPORT char *mpd_qformat(const mpd_t *dec, const char *fmt, const mpd_context_t *ctx, uint32_t *status);
338 
339 #define MPD_NUM_FLAGS 15
340 #define MPD_MAX_FLAG_STRING 208
341 #define MPD_MAX_FLAG_LIST (MPD_MAX_FLAG_STRING+18)
342 #define MPD_MAX_SIGNAL_LIST 121
343 IMPORTEXPORT int mpd_snprint_flags(char *dest, int nmemb, uint32_t flags);
344 IMPORTEXPORT int mpd_lsnprint_flags(char *dest, int nmemb, uint32_t flags, const char *flag_string[]);
345 IMPORTEXPORT int mpd_lsnprint_signals(char *dest, int nmemb, uint32_t flags, const char *signal_string[]);
346 
347 /* output to a file */
348 IMPORTEXPORT void mpd_fprint(FILE *file, const mpd_t *dec);
349 IMPORTEXPORT void mpd_print(const mpd_t *dec);
350 
351 /* assignment from a string */
352 IMPORTEXPORT void mpd_qset_string(mpd_t *dec, const char *s, const mpd_context_t *ctx, uint32_t *status);
353 IMPORTEXPORT void mpd_qset_string_exact(mpd_t *dec, const char *s, uint32_t *status);
354 
355 /* set to NaN with error flags */
356 IMPORTEXPORT void mpd_seterror(mpd_t *result, uint32_t flags, uint32_t *status);
357 /* set a special with sign and type */
358 IMPORTEXPORT void mpd_setspecial(mpd_t *result, uint8_t sign, uint8_t type);
359 /* set coefficient to zero or all nines */
360 IMPORTEXPORT void mpd_zerocoeff(mpd_t *result);
361 IMPORTEXPORT void mpd_qmaxcoeff(mpd_t *result, const mpd_context_t *ctx, uint32_t *status);
362 
363 /* quietly assign a C integer type to an mpd_t */
364 IMPORTEXPORT void mpd_qset_ssize(mpd_t *result, mpd_ssize_t a, const mpd_context_t *ctx, uint32_t *status);
365 IMPORTEXPORT void mpd_qset_i32(mpd_t *result, int32_t a, const mpd_context_t *ctx, uint32_t *status);
366 IMPORTEXPORT void mpd_qset_uint(mpd_t *result, mpd_uint_t a, const mpd_context_t *ctx, uint32_t *status);
367 IMPORTEXPORT void mpd_qset_u32(mpd_t *result, uint32_t a, const mpd_context_t *ctx, uint32_t *status);
368 #ifndef MPD_LEGACY_COMPILER
369 IMPORTEXPORT void mpd_qset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx, uint32_t *status);
370 IMPORTEXPORT void mpd_qset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx, uint32_t *status);
371 IMPORTEXPORT void mpd_qset_i64_exact(mpd_t *result, int64_t a, uint32_t *status);
372 IMPORTEXPORT void mpd_qset_u64_exact(mpd_t *result, uint64_t a, uint32_t *status);
373 #endif
374 
375 /* quietly assign a C integer type to an mpd_t with a static coefficient */
376 IMPORTEXPORT void mpd_qsset_ssize(mpd_t *result, mpd_ssize_t a, const mpd_context_t *ctx, uint32_t *status);
377 IMPORTEXPORT void mpd_qsset_i32(mpd_t *result, int32_t a, const mpd_context_t *ctx, uint32_t *status);
378 IMPORTEXPORT void mpd_qsset_uint(mpd_t *result, mpd_uint_t a, const mpd_context_t *ctx, uint32_t *status);
379 IMPORTEXPORT void mpd_qsset_u32(mpd_t *result, uint32_t a, const mpd_context_t *ctx, uint32_t *status);
380 
381 /* quietly get a C integer type from an mpd_t */
382 IMPORTEXPORT mpd_ssize_t mpd_qget_ssize(const mpd_t *dec, uint32_t *status);
383 IMPORTEXPORT mpd_uint_t mpd_qget_uint(const mpd_t *dec, uint32_t *status);
384 IMPORTEXPORT mpd_uint_t mpd_qabs_uint(const mpd_t *dec, uint32_t *status);
385 
386 IMPORTEXPORT int32_t mpd_qget_i32(const mpd_t *dec, uint32_t *status);
387 IMPORTEXPORT uint32_t mpd_qget_u32(const mpd_t *dec, uint32_t *status);
388 #ifndef MPD_LEGACY_COMPILER
389 IMPORTEXPORT int64_t mpd_qget_i64(const mpd_t *dec, uint32_t *status);
390 IMPORTEXPORT uint64_t mpd_qget_u64(const mpd_t *dec, uint32_t *status);
391 #endif
392 
393 /* quiet functions */
394 IMPORTEXPORT int mpd_qcheck_nan(mpd_t *nanresult, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
395 IMPORTEXPORT int mpd_qcheck_nans(mpd_t *nanresult, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
396 IMPORTEXPORT void mpd_qfinalize(mpd_t *result, const mpd_context_t *ctx, uint32_t *status);
397 
398 IMPORTEXPORT const char *mpd_class(const mpd_t *a, const mpd_context_t *ctx);
399 
400 IMPORTEXPORT int mpd_qcopy(mpd_t *result, const mpd_t *a, uint32_t *status);
401 IMPORTEXPORT int mpd_qcopy_cxx(mpd_t *result, const mpd_t *a);
402 IMPORTEXPORT mpd_t *mpd_qncopy(const mpd_t *a);
403 IMPORTEXPORT int mpd_qcopy_abs(mpd_t *result, const mpd_t *a, uint32_t *status);
404 IMPORTEXPORT int mpd_qcopy_negate(mpd_t *result, const mpd_t *a, uint32_t *status);
405 IMPORTEXPORT int mpd_qcopy_sign(mpd_t *result, const mpd_t *a, const mpd_t *b, uint32_t *status);
406 
407 IMPORTEXPORT void mpd_qand(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
408 IMPORTEXPORT void mpd_qinvert(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
409 IMPORTEXPORT void mpd_qlogb(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
410 IMPORTEXPORT void mpd_qor(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
411 IMPORTEXPORT void mpd_qscaleb(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
412 IMPORTEXPORT void mpd_qxor(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
413 IMPORTEXPORT int mpd_same_quantum(const mpd_t *a, const mpd_t *b);
414 
415 IMPORTEXPORT void mpd_qrotate(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
416 IMPORTEXPORT int mpd_qshiftl(mpd_t *result, const mpd_t *a, mpd_ssize_t n, uint32_t *status);
417 IMPORTEXPORT mpd_uint_t mpd_qshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n, uint32_t *status);
418 IMPORTEXPORT mpd_uint_t mpd_qshiftr_inplace(mpd_t *result, mpd_ssize_t n);
419 IMPORTEXPORT void mpd_qshift(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
420 IMPORTEXPORT void mpd_qshiftn(mpd_t *result, const mpd_t *a, mpd_ssize_t n, const mpd_context_t *ctx, uint32_t *status);
421 
422 IMPORTEXPORT int mpd_qcmp(const mpd_t *a, const mpd_t *b, uint32_t *status);
423 IMPORTEXPORT int mpd_qcompare(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
424 IMPORTEXPORT int mpd_qcompare_signal(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
425 IMPORTEXPORT int mpd_cmp_total(const mpd_t *a, const mpd_t *b);
426 IMPORTEXPORT int mpd_cmp_total_mag(const mpd_t *a, const mpd_t *b);
427 IMPORTEXPORT int mpd_compare_total(mpd_t *result, const mpd_t *a, const mpd_t *b);
428 IMPORTEXPORT int mpd_compare_total_mag(mpd_t *result, const mpd_t *a, const mpd_t *b);
429 
430 IMPORTEXPORT void mpd_qround_to_intx(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
431 IMPORTEXPORT void mpd_qround_to_int(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
432 IMPORTEXPORT void mpd_qtrunc(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
433 IMPORTEXPORT void mpd_qfloor(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
434 IMPORTEXPORT void mpd_qceil(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
435 
436 IMPORTEXPORT void mpd_qabs(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
437 IMPORTEXPORT void mpd_qmax(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
438 IMPORTEXPORT void mpd_qmax_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
439 IMPORTEXPORT void mpd_qmin(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
440 IMPORTEXPORT void mpd_qmin_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
441 IMPORTEXPORT void mpd_qminus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
442 IMPORTEXPORT void mpd_qplus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
443 IMPORTEXPORT void mpd_qnext_minus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
444 IMPORTEXPORT void mpd_qnext_plus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
445 IMPORTEXPORT void mpd_qnext_toward(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
446 IMPORTEXPORT void mpd_qquantize(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
447 IMPORTEXPORT void mpd_qrescale(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, const mpd_context_t *ctx, uint32_t *status);
448 IMPORTEXPORT void mpd_qrescale_fmt(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, const mpd_context_t *ctx, uint32_t *status);
449 IMPORTEXPORT void mpd_qreduce(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
450 IMPORTEXPORT void mpd_qadd(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
451 IMPORTEXPORT void mpd_qadd_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, const mpd_context_t *ctx, uint32_t *status);
452 IMPORTEXPORT void mpd_qadd_i32(mpd_t *result, const mpd_t *a, int32_t b, const mpd_context_t *ctx, uint32_t *status);
453 IMPORTEXPORT void mpd_qadd_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, const mpd_context_t *ctx, uint32_t *status);
454 IMPORTEXPORT void mpd_qadd_u32(mpd_t *result, const mpd_t *a, uint32_t b, const mpd_context_t *ctx, uint32_t *status);
455 IMPORTEXPORT void mpd_qsub(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
456 IMPORTEXPORT void mpd_qsub_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, const mpd_context_t *ctx, uint32_t *status);
457 IMPORTEXPORT void mpd_qsub_i32(mpd_t *result, const mpd_t *a, int32_t b, const mpd_context_t *ctx, uint32_t *status);
458 IMPORTEXPORT void mpd_qsub_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, const mpd_context_t *ctx, uint32_t *status);
459 IMPORTEXPORT void mpd_qsub_u32(mpd_t *result, const mpd_t *a, uint32_t b, const mpd_context_t *ctx, uint32_t *status);
460 IMPORTEXPORT void mpd_qmul(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
461 IMPORTEXPORT void mpd_qmul_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, const mpd_context_t *ctx, uint32_t *status);
462 IMPORTEXPORT void mpd_qmul_i32(mpd_t *result, const mpd_t *a, int32_t b, const mpd_context_t *ctx, uint32_t *status);
463 IMPORTEXPORT void mpd_qmul_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, const mpd_context_t *ctx, uint32_t *status);
464 IMPORTEXPORT void mpd_qmul_u32(mpd_t *result, const mpd_t *a, uint32_t b, const mpd_context_t *ctx, uint32_t *status);
465 IMPORTEXPORT void mpd_qfma(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c, const mpd_context_t *ctx, uint32_t *status);
466 IMPORTEXPORT void mpd_qdiv(mpd_t *q, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
467 IMPORTEXPORT void mpd_qdiv_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, const mpd_context_t *ctx, uint32_t *status);
468 IMPORTEXPORT void mpd_qdiv_i32(mpd_t *result, const mpd_t *a, int32_t b, const mpd_context_t *ctx, uint32_t *status);
469 IMPORTEXPORT void mpd_qdiv_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, const mpd_context_t *ctx, uint32_t *status);
470 IMPORTEXPORT void mpd_qdiv_u32(mpd_t *result, const mpd_t *a, uint32_t b, const mpd_context_t *ctx, uint32_t *status);
471 IMPORTEXPORT void mpd_qdivint(mpd_t *q, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
472 IMPORTEXPORT void mpd_qrem(mpd_t *r, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
473 IMPORTEXPORT void mpd_qrem_near(mpd_t *r, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
474 IMPORTEXPORT void mpd_qdivmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
475 IMPORTEXPORT void mpd_qpow(mpd_t *result, const mpd_t *base, const mpd_t *exp, const mpd_context_t *ctx, uint32_t *status);
476 IMPORTEXPORT void mpd_qpowmod(mpd_t *result, const mpd_t *base, const mpd_t *exp, const mpd_t *mod, const mpd_context_t *ctx, uint32_t *status);
477 IMPORTEXPORT void mpd_qexp(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
478 IMPORTEXPORT void mpd_qln10(mpd_t *result, mpd_ssize_t prec, uint32_t *status);
479 IMPORTEXPORT void mpd_qln(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
480 IMPORTEXPORT void mpd_qlog10(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
481 IMPORTEXPORT void mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
482 IMPORTEXPORT void mpd_qinvroot(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
483 #ifndef MPD_LEGACY_COMPILER
484 IMPORTEXPORT void mpd_qadd_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status);
485 IMPORTEXPORT void mpd_qadd_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status);
486 IMPORTEXPORT void mpd_qsub_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status);
487 IMPORTEXPORT void mpd_qsub_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status);
488 IMPORTEXPORT void mpd_qmul_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status);
489 IMPORTEXPORT void mpd_qmul_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status);
490 IMPORTEXPORT void mpd_qdiv_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status);
491 IMPORTEXPORT void mpd_qdiv_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status);
492 #endif
493 
494 
495 IMPORTEXPORT size_t mpd_sizeinbase(const mpd_t *a, uint32_t base);
496 IMPORTEXPORT void mpd_qimport_u16(mpd_t *result, const uint16_t *srcdata, size_t srclen,
497                                   uint8_t srcsign, uint32_t srcbase,
498                                   const mpd_context_t *ctx, uint32_t *status);
499 IMPORTEXPORT void mpd_qimport_u32(mpd_t *result, const uint32_t *srcdata, size_t srclen,
500                                   uint8_t srcsign, uint32_t srcbase,
501                                   const mpd_context_t *ctx, uint32_t *status);
502 IMPORTEXPORT size_t mpd_qexport_u16(uint16_t **rdata, size_t rlen, uint32_t base,
503                                     const mpd_t *src, uint32_t *status);
504 IMPORTEXPORT size_t mpd_qexport_u32(uint32_t **rdata, size_t rlen, uint32_t base,
505                                     const mpd_t *src, uint32_t *status);
506 
507 
508 /******************************************************************************/
509 /*                           Signalling functions                             */
510 /******************************************************************************/
511 
512 IMPORTEXPORT char *mpd_format(const mpd_t *dec, const char *fmt, mpd_context_t *ctx);
513 IMPORTEXPORT void mpd_import_u16(mpd_t *result, const uint16_t *srcdata, size_t srclen, uint8_t srcsign, uint32_t base, mpd_context_t *ctx);
514 IMPORTEXPORT void mpd_import_u32(mpd_t *result, const uint32_t *srcdata, size_t srclen, uint8_t srcsign, uint32_t base, mpd_context_t *ctx);
515 IMPORTEXPORT size_t mpd_export_u16(uint16_t **rdata, size_t rlen, uint32_t base, const mpd_t *src, mpd_context_t *ctx);
516 IMPORTEXPORT size_t mpd_export_u32(uint32_t **rdata, size_t rlen, uint32_t base, const mpd_t *src, mpd_context_t *ctx);
517 IMPORTEXPORT void mpd_finalize(mpd_t *result, mpd_context_t *ctx);
518 IMPORTEXPORT int mpd_check_nan(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
519 IMPORTEXPORT int mpd_check_nans(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
520 IMPORTEXPORT void mpd_set_string(mpd_t *result, const char *s, mpd_context_t *ctx);
521 IMPORTEXPORT void mpd_maxcoeff(mpd_t *result, mpd_context_t *ctx);
522 IMPORTEXPORT void mpd_sset_ssize(mpd_t *result, mpd_ssize_t a, mpd_context_t *ctx);
523 IMPORTEXPORT void mpd_sset_i32(mpd_t *result, int32_t a, mpd_context_t *ctx);
524 IMPORTEXPORT void mpd_sset_uint(mpd_t *result, mpd_uint_t a, mpd_context_t *ctx);
525 IMPORTEXPORT void mpd_sset_u32(mpd_t *result, uint32_t a, mpd_context_t *ctx);
526 IMPORTEXPORT void mpd_set_ssize(mpd_t *result, mpd_ssize_t a, mpd_context_t *ctx);
527 IMPORTEXPORT void mpd_set_i32(mpd_t *result, int32_t a, mpd_context_t *ctx);
528 IMPORTEXPORT void mpd_set_uint(mpd_t *result, mpd_uint_t a, mpd_context_t *ctx);
529 IMPORTEXPORT void mpd_set_u32(mpd_t *result, uint32_t a, mpd_context_t *ctx);
530 #ifndef MPD_LEGACY_COMPILER
531 IMPORTEXPORT void mpd_set_i64(mpd_t *result, int64_t a, mpd_context_t *ctx);
532 IMPORTEXPORT void mpd_set_u64(mpd_t *result, uint64_t a, mpd_context_t *ctx);
533 #endif
534 IMPORTEXPORT mpd_ssize_t mpd_get_ssize(const mpd_t *a, mpd_context_t *ctx);
535 IMPORTEXPORT mpd_uint_t mpd_get_uint(const mpd_t *a, mpd_context_t *ctx);
536 IMPORTEXPORT mpd_uint_t mpd_abs_uint(const mpd_t *a, mpd_context_t *ctx);
537 IMPORTEXPORT int32_t mpd_get_i32(const mpd_t *a, mpd_context_t *ctx);
538 IMPORTEXPORT uint32_t mpd_get_u32(const mpd_t *a, mpd_context_t *ctx);
539 #ifndef MPD_LEGACY_COMPILER
540 IMPORTEXPORT int64_t mpd_get_i64(const mpd_t *a, mpd_context_t *ctx);
541 IMPORTEXPORT uint64_t mpd_get_u64(const mpd_t *a, mpd_context_t *ctx);
542 #endif
543 IMPORTEXPORT void mpd_and(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
544 IMPORTEXPORT void mpd_copy(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
545 IMPORTEXPORT void mpd_canonical(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
546 IMPORTEXPORT void mpd_copy_abs(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
547 IMPORTEXPORT void mpd_copy_negate(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
548 IMPORTEXPORT void mpd_copy_sign(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
549 IMPORTEXPORT void mpd_invert(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
550 IMPORTEXPORT void mpd_logb(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
551 IMPORTEXPORT void mpd_or(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
552 IMPORTEXPORT void mpd_rotate(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
553 IMPORTEXPORT void mpd_scaleb(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
554 IMPORTEXPORT void mpd_shiftl(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx);
555 IMPORTEXPORT mpd_uint_t mpd_shiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx);
556 IMPORTEXPORT void mpd_shiftn(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx);
557 IMPORTEXPORT void mpd_shift(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
558 IMPORTEXPORT void mpd_xor(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
559 IMPORTEXPORT void mpd_abs(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
560 IMPORTEXPORT int mpd_cmp(const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
561 IMPORTEXPORT int mpd_compare(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
562 IMPORTEXPORT int mpd_compare_signal(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
563 IMPORTEXPORT void mpd_add(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
564 IMPORTEXPORT void mpd_add_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx);
565 IMPORTEXPORT void mpd_add_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx);
566 IMPORTEXPORT void mpd_add_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx);
567 IMPORTEXPORT void mpd_add_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx);
568 IMPORTEXPORT void mpd_sub(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
569 IMPORTEXPORT void mpd_sub_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx);
570 IMPORTEXPORT void mpd_sub_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx);
571 IMPORTEXPORT void mpd_sub_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx);
572 IMPORTEXPORT void mpd_sub_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx);
573 IMPORTEXPORT void mpd_div(mpd_t *q, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
574 IMPORTEXPORT void mpd_div_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx);
575 IMPORTEXPORT void mpd_div_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx);
576 IMPORTEXPORT void mpd_div_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx);
577 IMPORTEXPORT void mpd_div_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx);
578 IMPORTEXPORT void mpd_divmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
579 IMPORTEXPORT void mpd_divint(mpd_t *q, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
580 IMPORTEXPORT void mpd_exp(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
581 IMPORTEXPORT void mpd_fma(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c, mpd_context_t *ctx);
582 IMPORTEXPORT void mpd_ln(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
583 IMPORTEXPORT void mpd_log10(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
584 IMPORTEXPORT void mpd_max(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
585 IMPORTEXPORT void mpd_max_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
586 IMPORTEXPORT void mpd_min(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
587 IMPORTEXPORT void mpd_min_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
588 IMPORTEXPORT void mpd_minus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
589 IMPORTEXPORT void mpd_mul(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
590 IMPORTEXPORT void mpd_mul_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx);
591 IMPORTEXPORT void mpd_mul_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx);
592 IMPORTEXPORT void mpd_mul_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx);
593 IMPORTEXPORT void mpd_mul_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx);
594 IMPORTEXPORT void mpd_next_minus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
595 IMPORTEXPORT void mpd_next_plus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
596 IMPORTEXPORT void mpd_next_toward(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
597 IMPORTEXPORT void mpd_plus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
598 IMPORTEXPORT void mpd_pow(mpd_t *result, const mpd_t *base, const mpd_t *exp, mpd_context_t *ctx);
599 IMPORTEXPORT void mpd_powmod(mpd_t *result, const mpd_t *base, const mpd_t *exp, const mpd_t *mod, mpd_context_t *ctx);
600 IMPORTEXPORT void mpd_quantize(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
601 IMPORTEXPORT void mpd_rescale(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, mpd_context_t *ctx);
602 IMPORTEXPORT void mpd_reduce(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
603 IMPORTEXPORT void mpd_rem(mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
604 IMPORTEXPORT void mpd_rem_near(mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
605 IMPORTEXPORT void mpd_round_to_intx(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
606 IMPORTEXPORT void mpd_round_to_int(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
607 IMPORTEXPORT void mpd_trunc(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
608 IMPORTEXPORT void mpd_floor(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
609 IMPORTEXPORT void mpd_ceil(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
610 IMPORTEXPORT void mpd_sqrt(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
611 IMPORTEXPORT void mpd_invroot(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
612 
613 #ifndef MPD_LEGACY_COMPILER
614 IMPORTEXPORT void mpd_add_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx);
615 IMPORTEXPORT void mpd_add_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx);
616 IMPORTEXPORT void mpd_sub_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx);
617 IMPORTEXPORT void mpd_sub_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx);
618 IMPORTEXPORT void mpd_div_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx);
619 IMPORTEXPORT void mpd_div_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx);
620 IMPORTEXPORT void mpd_mul_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx);
621 IMPORTEXPORT void mpd_mul_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx);
622 #endif
623 
624 
625 /******************************************************************************/
626 /*                          Configuration specific                            */
627 /******************************************************************************/
628 
629 IMPORTEXPORT void mpd_qsset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx, uint32_t *status);
630 IMPORTEXPORT void mpd_qsset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx, uint32_t *status);
631 IMPORTEXPORT void mpd_sset_i64(mpd_t *result, int64_t a, mpd_context_t *ctx);
632 IMPORTEXPORT void mpd_sset_u64(mpd_t *result, uint64_t a, mpd_context_t *ctx);
633 
634 
635 
636 /******************************************************************************/
637 /*                       Get attributes of a decimal                          */
638 /******************************************************************************/
639 
640 IMPORTEXPORT EXTINLINE mpd_ssize_t mpd_adjexp(const mpd_t *dec);
641 IMPORTEXPORT EXTINLINE mpd_ssize_t mpd_etiny(const mpd_context_t *ctx);
642 IMPORTEXPORT EXTINLINE mpd_ssize_t mpd_etop(const mpd_context_t *ctx);
643 IMPORTEXPORT EXTINLINE mpd_uint_t mpd_msword(const mpd_t *dec);
644 IMPORTEXPORT EXTINLINE int mpd_word_digits(mpd_uint_t word);
645 /* most significant digit of a word */
646 IMPORTEXPORT EXTINLINE mpd_uint_t mpd_msd(mpd_uint_t word);
647 /* least significant digit of a word */
648 IMPORTEXPORT EXTINLINE mpd_uint_t mpd_lsd(mpd_uint_t word);
649 /* coefficient size needed to store 'digits' */
650 IMPORTEXPORT EXTINLINE mpd_ssize_t mpd_digits_to_size(mpd_ssize_t digits);
651 /* number of digits in the exponent, undefined for MPD_SSIZE_MIN */
652 IMPORTEXPORT EXTINLINE int mpd_exp_digits(mpd_ssize_t exp);
653 IMPORTEXPORT EXTINLINE int mpd_iscanonical(const mpd_t *dec);
654 IMPORTEXPORT EXTINLINE int mpd_isfinite(const mpd_t *dec);
655 IMPORTEXPORT EXTINLINE int mpd_isinfinite(const mpd_t *dec);
656 IMPORTEXPORT EXTINLINE int mpd_isinteger(const mpd_t *dec);
657 IMPORTEXPORT EXTINLINE int mpd_isnan(const mpd_t *dec);
658 IMPORTEXPORT EXTINLINE int mpd_isnegative(const mpd_t *dec);
659 IMPORTEXPORT EXTINLINE int mpd_ispositive(const mpd_t *dec);
660 IMPORTEXPORT EXTINLINE int mpd_isqnan(const mpd_t *dec);
661 IMPORTEXPORT EXTINLINE int mpd_issigned(const mpd_t *dec);
662 IMPORTEXPORT EXTINLINE int mpd_issnan(const mpd_t *dec);
663 IMPORTEXPORT EXTINLINE int mpd_isspecial(const mpd_t *dec);
664 IMPORTEXPORT EXTINLINE int mpd_iszero(const mpd_t *dec);
665 /* undefined for special numbers */
666 IMPORTEXPORT EXTINLINE int mpd_iszerocoeff(const mpd_t *dec);
667 IMPORTEXPORT EXTINLINE int mpd_isnormal(const mpd_t *dec, const mpd_context_t *ctx);
668 IMPORTEXPORT EXTINLINE int mpd_issubnormal(const mpd_t *dec, const mpd_context_t *ctx);
669 /* odd word */
670 IMPORTEXPORT EXTINLINE int mpd_isoddword(mpd_uint_t word);
671 /* odd coefficient */
672 IMPORTEXPORT EXTINLINE int mpd_isoddcoeff(const mpd_t *dec);
673 /* odd decimal, only defined for integers */
674 IMPORTEXPORT int mpd_isodd(const mpd_t *dec);
675 /* even decimal, only defined for integers */
676 IMPORTEXPORT int mpd_iseven(const mpd_t *dec);
677 /* 0 if dec is positive, 1 if dec is negative */
678 IMPORTEXPORT EXTINLINE uint8_t mpd_sign(const mpd_t *dec);
679 /* 1 if dec is positive, -1 if dec is negative */
680 IMPORTEXPORT EXTINLINE int mpd_arith_sign(const mpd_t *dec);
681 IMPORTEXPORT EXTINLINE long mpd_radix(void);
682 IMPORTEXPORT EXTINLINE int mpd_isdynamic(const mpd_t *dec);
683 IMPORTEXPORT EXTINLINE int mpd_isstatic(const mpd_t *dec);
684 IMPORTEXPORT EXTINLINE int mpd_isdynamic_data(const mpd_t *dec);
685 IMPORTEXPORT EXTINLINE int mpd_isstatic_data(const mpd_t *dec);
686 IMPORTEXPORT EXTINLINE int mpd_isshared_data(const mpd_t *dec);
687 IMPORTEXPORT EXTINLINE int mpd_isconst_data(const mpd_t *dec);
688 IMPORTEXPORT mpd_ssize_t mpd_trail_zeros(const mpd_t *dec);
689 
690 
691 /******************************************************************************/
692 /*                       Set attributes of a decimal                          */
693 /******************************************************************************/
694 
695 /* set number of decimal digits in the coefficient */
696 IMPORTEXPORT EXTINLINE void mpd_setdigits(mpd_t *result);
697 IMPORTEXPORT EXTINLINE void mpd_set_sign(mpd_t *result, uint8_t sign);
698 /* copy sign from another decimal */
699 IMPORTEXPORT EXTINLINE void mpd_signcpy(mpd_t *result, const mpd_t *a);
700 IMPORTEXPORT EXTINLINE void mpd_set_infinity(mpd_t *result);
701 IMPORTEXPORT EXTINLINE void mpd_set_qnan(mpd_t *result);
702 IMPORTEXPORT EXTINLINE void mpd_set_snan(mpd_t *result);
703 IMPORTEXPORT EXTINLINE void mpd_set_negative(mpd_t *result);
704 IMPORTEXPORT EXTINLINE void mpd_set_positive(mpd_t *result);
705 IMPORTEXPORT EXTINLINE void mpd_set_dynamic(mpd_t *result);
706 IMPORTEXPORT EXTINLINE void mpd_set_static(mpd_t *result);
707 IMPORTEXPORT EXTINLINE void mpd_set_dynamic_data(mpd_t *result);
708 IMPORTEXPORT EXTINLINE void mpd_set_static_data(mpd_t *result);
709 IMPORTEXPORT EXTINLINE void mpd_set_shared_data(mpd_t *result);
710 IMPORTEXPORT EXTINLINE void mpd_set_const_data(mpd_t *result);
711 IMPORTEXPORT EXTINLINE void mpd_clear_flags(mpd_t *result);
712 IMPORTEXPORT EXTINLINE void mpd_set_flags(mpd_t *result, uint8_t flags);
713 IMPORTEXPORT EXTINLINE void mpd_copy_flags(mpd_t *result, const mpd_t *a);
714 
715 
716 /******************************************************************************/
717 /*                              Error Macros                                  */
718 /******************************************************************************/
719 
720 #define mpd_err_fatal(...) \
721     do {fprintf(stderr, "%s:%d: error: ", __FILE__, __LINE__); \
722         fprintf(stderr, __VA_ARGS__);  fputc('\n', stderr);    \
723         abort();                                               \
724     } while (0)
725 #define mpd_err_warn(...) \
726     do {fprintf(stderr, "%s:%d: warning: ", __FILE__, __LINE__); \
727         fprintf(stderr, __VA_ARGS__); fputc('\n', stderr);       \
728     } while (0)
729 
730 
731 /******************************************************************************/
732 /*                            Memory handling                                 */
733 /******************************************************************************/
734 
735 IMPORTEXPORT extern void *(* mpd_mallocfunc)(size_t size);
736 IMPORTEXPORT extern void *(* mpd_callocfunc)(size_t nmemb, size_t size);
737 IMPORTEXPORT extern void *(* mpd_reallocfunc)(void *ptr, size_t size);
738 IMPORTEXPORT extern void (* mpd_free)(void *ptr);
739 
740 IMPORTEXPORT void *mpd_callocfunc_em(size_t nmemb, size_t size);
741 
742 IMPORTEXPORT void *mpd_alloc(mpd_size_t nmemb, mpd_size_t size);
743 IMPORTEXPORT void *mpd_calloc(mpd_size_t nmemb, mpd_size_t size);
744 IMPORTEXPORT void *mpd_realloc(void *ptr, mpd_size_t nmemb, mpd_size_t size, uint8_t *err);
745 IMPORTEXPORT void *mpd_sh_alloc(mpd_size_t struct_size, mpd_size_t nmemb, mpd_size_t size);
746 
747 IMPORTEXPORT mpd_t *mpd_qnew(void);
748 IMPORTEXPORT mpd_t *mpd_new(mpd_context_t *ctx);
749 IMPORTEXPORT mpd_t *mpd_qnew_size(mpd_ssize_t nwords);
750 IMPORTEXPORT EXTINLINE void mpd_del(mpd_t *dec);
751 
752 IMPORTEXPORT EXTINLINE void mpd_uint_zero(mpd_uint_t *dest, mpd_size_t len);
753 IMPORTEXPORT EXTINLINE int mpd_qresize(mpd_t *result, mpd_ssize_t nwords, uint32_t *status);
754 IMPORTEXPORT EXTINLINE int mpd_qresize_zero(mpd_t *result, mpd_ssize_t nwords, uint32_t *status);
755 IMPORTEXPORT EXTINLINE void mpd_minalloc(mpd_t *result);
756 
757 IMPORTEXPORT int mpd_resize(mpd_t *result, mpd_ssize_t nwords, mpd_context_t *ctx);
758 IMPORTEXPORT int mpd_resize_zero(mpd_t *result, mpd_ssize_t nwords, mpd_context_t *ctx);
759 
760 #undef IMPORTEXPORT
761 #undef EXTINLINE
762 
763 #ifdef __cplusplus
764 } /* END extern "C" */
765 #endif
766 
767 
768 #endif /* LIBMPDEC_MPDECIMAL_H_ */
769