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