# 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.

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.

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.