Various Functions¶
Applying the Context¶
finalize¶
void mpd_qfinalize(mpd_t *result, const mpd_context_t *ctx,
uint32_t *status);
void mpd_finalize(mpd_t *result, mpd_context_t *ctx);
Apply ctx to result. This function performs checks the exponent limits and performs rounding. The following conditions can occur:
MPD_Clamped
, MPD_Inexact
, MPD_Overflow
,
MPD_Rounded
, MPD_Subnormal
, MPD_Underflow
NaN Handling¶
These functions are convenience functions that take care of the elaborate NaN handling rules. They are meant to be used at the beginning of composite functions.
check-nan¶
int mpd_qcheck_nan(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
uint32_t *status);
int mpd_check_nan(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
If a is NaN or sNaN, set result to qNaN, copy any payload, apply ctx
to the payload and return 1. If a is sNaN, additionally set
MPD_Invalid_operation
.
Otherwise, result is undefined and the return value is 0.
check-nans¶
int mpd_qcheck_nans(mpd_t *result, const mpd_t *a, const mpd_t *b,
const mpd_context_t *ctx, uint32_t *status);
int mpd_check_nans(mpd_t *result, const mpd_t *a, const mpd_t *b,
mpd_context_t *ctx);
If either operand is NaN or sNaN, apply the precedence rules, set result
to qNaN, copy any payload, apply ctx to the payload and return 1. If
one of the operands is sNaN, additionally set MPD_Invalid_operation
.
Otherwise, result is undefined and the return value is 0.
Shifting and Rotating¶
shift¶
void mpd_qshift(mpd_t *result, const mpd_t *a, const mpd_t *b,
const mpd_context_t *ctx, uint32_t *status);
void mpd_shift(mpd_t *result, const mpd_t *a, const mpd_t *b,
mpd_context_t *ctx);
Set result to a shifted by b places. b must be in the range [-prec, prec]. A negative b indicates a right shift, a positive b a left shift. Digits that do not fit are discarded.
shiftn¶
void mpd_qshiftn(mpd_t *result, const mpd_t *a, mpd_ssize_t n,
const mpd_context_t *ctx, uint32_t *status);
void mpd_shiftn(mpd_t *result, const mpd_t *a, mpd_ssize_t n,
mpd_context_t *ctx);
Like mpd_qshift
, only that the number of places is specified by a
C integer type rather than a decimal. This function is not part of the
specification.
shiftl¶
int mpd_qshiftl(mpd_t *result, const mpd_t *a, mpd_ssize_t n,
uint32_t *status);
void mpd_shiftl(mpd_t *result, const mpd_t *a, mpd_ssize_t n,
mpd_context_t *ctx);
Set result to a, shifted by n places to the left. a must not be
a special number. Digits are never discarded, so the coefficient of
result might exceed prec. Return 1 on success. On failure, return 0
and add MPD_Malloc_error
to status.
If n is negative or the result would have more than MPD_SSIZE_MAX
digits, the behavior is undefined.
If result has more than MPD_MAX_PREC digits, not all functions are guaranteed to handle it correctly. However, there may be legitimate use cases, so mpd_qshiftl makes no attempt to prevent it.
This function is not part of the specification.
shiftr¶
mpd_uint_t mpd_qshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n,
uint32_t *status);
mpd_uint_t mpd_shiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n,
mpd_context_t *ctx);
Set result to a, shifted by n places to the right. a must not be
a special number. On success, return the digit relevant for rounding.
On failure, return MPD_UINT_MAX
and add MPD_Malloc_error
to status.
If n is negative, the behavior is undefined.
This function is not part of the specification.
shiftr-inplace¶
mpd_uint_t mpd_qshiftr_inplace(mpd_t *result, mpd_ssize_t n)
Like mpd_qshiftr
, but shifts result in place. result
must not be a special number. This function cannot fail.
rotate¶
void mpd_qrotate(mpd_t *result, const mpd_t *a, const mpd_t *b,
const mpd_context_t *ctx, uint32_t *status);
void mpd_rotate(mpd_t *result, const mpd_t *a, const mpd_t *b,
mpd_context_t *ctx);
Set result to a rotated by b places. b must be in the range [-prec, prec]. A negative b indicates a right rotation, a positive b a left rotation.
Logical Operations¶
Logical operands are finite numbers with a sign of 0, an exponent of 0 and a coefficient consisting only of ones and zeros.
and¶
void mpd_qand(mpd_t *result, const mpd_t *a, const mpd_t *b,
const mpd_context_t *ctx, uint32_t *status);
void mpd_and(mpd_t *result, const mpd_t *a, const mpd_t *b,
mpd_context_t *ctx);
Set result to the digit-wise logical and of a and b.
or¶
void mpd_qor(mpd_t *result, const mpd_t *a, const mpd_t *b,
const mpd_context_t *ctx, uint32_t *status);
void mpd_or(mpd_t *result, const mpd_t *a, const mpd_t *b,
mpd_context_t *ctx);
Set result to the digit-wise logical or of a and b.
xor¶
void mpd_qxor(mpd_t *result, const mpd_t *a, const mpd_t *b,
const mpd_context_t *ctx, uint32_t *status);
void mpd_xor(mpd_t *result, const mpd_t *a, const mpd_t *b,
mpd_context_t *ctx);
Set result to the digit-wise logical xor of a and b.
invert¶
void mpd_qinvert(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
uint32_t *status);
void mpd_invert(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
Set result to the digit-wise logical inversion of a.
Base Conversions¶
Functions for converting decimals to multi-precision integers and vice versa. Decimals that are exported must be integers.
Importing¶
void mpd_qimport_u16(mpd_t *result, const uint16_t *srcdata,
size_t srclen, uint8_t srcsign, uint32_t srcbase,
const mpd_context_t *ctx, uint32_t *status);
void mpd_import_u16(mpd_t *result, const uint16_t *srcdata,
size_t srclen, uint8_t srcsign, uint32_t srcbase,
mpd_context_t *ctx);
Convert a multi-precision integer at srcdata with base srcbase to a decimal. The least significant word is srcdata[0].
srcsign is MPD_POS
for positive and MPD_NEG
for
negative, srclen the length of srcdata.
Valid bases are in the range 2 <= srcbase <= UINT16_MAX
+ 1.
void mpd_qimport_u32(mpd_t *result, const uint32_t *srcdata,
size_t srclen, uint8_t srcsign, uint32_t srcbase,
const mpd_context_t *ctx, uint32_t *status);
void mpd_import_u32(mpd_t *result, const uint32_t *srcdata,
size_t srclen, uint8_t srcsign, uint32_t base,
mpd_context_t *ctx);
Convert a multi-precision integer at srcdata with base srcbase to a decimal. The least significant word is srcdata[0].
srcsign is MPD_POS
for positive and MPD_NEG
for
negative, srclen the length of srcdata.
Valid bases are in the range 2 <= srcbase <= UINT32_MAX
.
Exporting¶
mpd_sizeinbase(const mpd_t *a, uint32_t base);
Return the number of words needed to represent a decimal when converted to base. The decimal must be an integer, results are undefined for non-integers.
size_t mpd_qexport_u16(uint16_t **rdata, size_t rlen, uint32_t rbase,
const mpd_t *src, uint32_t *status);
size_t mpd_export_u16(uint16_t **rdata, size_t rlen, uint32_t rbase,
const mpd_t *src, mpd_context_t *ctx);
Set *rdata to src, converted to a representation in base rbase. The least significant word of the result is rdata[0]. src must be an integer.
If rdata is NULL, space is allocated by the function and rlen is irrelevant. In case of an error the allocated storage is freed and rdata is set back to NULL.
If rdata is non-NULL, it MUST be allocated by one of libmpdec’s
allocation functions and rlen MUST be correct. If necessary, the
function will resize rdata. Resizing is slow and should not occur
if rlen has been obtained by a call to mpd_sizeinbase
.
In case of an error the caller must free rdata.
Return value: In case of success, the length of the multi-precision integer
in the new base, SIZE_MAX
otherwise.
Valid bases are in the range 2 <= rbase <= UINT16_MAX
+ 1.
Changed in version 2.4.0: rdata is now resized if necessary.
size_t mpd_qexport_u32(uint32_t *rdata, size_t rlen, uint32_t rbase,
const mpd_t *src, uint32_t *status);
size_t mpd_export_u32(uint32_t *rdata, size_t rlen, uint32_t rbase,
const mpd_t *src, mpd_context_t *ctx);
Set *rdata to src, converted to a representation in base rbase. The least significant word of the result is rdata[0]. src must be an integer.
If rdata is NULL, space is allocated by the function and rlen is irrelevant. In case of an error the allocated storage is freed and rdata is set back to NULL.
If rdata is non-NULL, it MUST be allocated by one of libmpdec’s
allocation functions and rlen MUST be correct. If necessary, the
function will resize rdata. Resizing is slow and should not occur if
rlen has been obtained by a call to mpd_sizeinbase
. In case
of an error the caller must free rdata.
Return value: In case of success, the length of the multi-precision integer
in the new base, SIZE_MAX
otherwise.
Valid bases are in the range 2 <= rbase <= UINT32_MAX
.
Changed in version 2.4.0: rdata is now resized if necessary.
Required Functions¶
The functions in this section are not needed for this implementation. They are provided for full compliance with the specification.
void mpd_canonical(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
Same as mpd_copy
.
int mpd_iscanonical(const mpd_t *dec);
Return 1, for compatibility with the standard.
long mpd_radix(void);
Return 10.
Library version¶
/* Macros defining the components of the version as integers. */
MPD_MAJOR_VERSION
MPD_MINOR_VERSION
MPD_MICRO_VERSION
/* Macro defining the complete version as a string. */
MPD_VERSION
const char *mpd_version(void);
Library version information. mpd_version
returns the MPD_VERSION macro
from the header that the library was compiled with.
New in version 2.4.0.