The decNumber Library, version 3.36
Copyright (c) IBM Corporation, 2006. All rights reserved. ©
6 Jul 2006
[previous | contents | next]

decNumber module

The decNumber module defines the data structure used for representing numbers in a form suitable for computation, and provides the functions for operating on those values.

The decNumber structure is optimized for efficient processing of relatively short numbers (tens or hundreds of digits); in particular it allows the use of fixed sized structures and minimizes copy and move operations. The functions in the module, however, support arbitrary precision arithmetic (up to 999,999,999 decimal digits, with exponents up to 9 digits).

The essential parts of a decNumber are the coefficient, which is the significand of the number, the exponent (which indicates the power of ten by which the coefficient should be multiplied), and the sign, which is 1 if the number is negative, or 0 otherwise. The numerical value of the number is then given by: (-1)sign × coefficient × 10exponent.

Numbers may also be a special value. The special values are NaN (Not a Number), which may be quiet (propagates quietly through operations) or signaling (raises the Invalid operation condition when encountered), and ±infinity.

These parts are encoded in the four fields of the decNumber structure:

digits
The digits field contains the length of the coefficient, in decimal digits.

digits is of type int32_t, and must have a value in the range 1 through 999,999,999.

exponent
The exponent field holds the exponent of the number. Its range is limited by the requirement that the range of the adjusted exponent of the number be balanced and fit within a whole number of decimal digits (in this implementation, be –999,999,999 through +999,999,999). The adjusted exponent is the exponent that would result if the number were expressed with a single digit before the decimal point, and is therefore given by exponent+digits-1.

When the extended flag in the context is 1, gradual underflow (using subnormal values) is enabled. In this case, the lower limit for the adjusted exponent becomes –999,999,999–(precision–1), where precision is the digits setting from the context; the adjusted exponent may then have 10 digits.

exponent is of type int32_t.

bits
The bits field comprises one bit which indicates the sign of the number (1 for negative, 0 otherwise), 3 bits which indicate the special values, and 4 further bits which are unused and reserved. These reserved bits must be zero.

If the number has a special value, just one of the indicator bits (DECINF, DECNAN, or DECSNAN) will be set (along with DECNEG iff the sign is 1). If DECINF is set digits must be 1 and the other fields must be 0. If the number is a NaN, the exponent must be zero and the coefficient holds any diagnostic information (with digits indicating its length, as for finite numbers). A zero coefficient indicates no diagnostic information.

bits is of type uint8_t (an unsigned byte). Masks for the named bits, and some useful macros, are defined in the header file.

lsu
The lsu field is one or more units in length (of type decNumberUnit, an unsigned integer), and contains the digits of the coefficient. Each unit represents one or more of the digits in the coefficient and has a binary value in the range 0 through 10n-1, where n is the number of digits in a unit and is the value set by DECDPUN. The size of a unit is the smallest of 1, 2, or 4 bytes which will contain the maximum value held in the unit.

The units comprising the coefficient start with the least significant unit (lsu). Each unit except the most significant unit (msu) contains DECDPUN digits. The msu contains from 1 through DECDPUN digits, and must not be 0 unless digits is 1 (for the value zero). Leading zeros in the msu are never included in the digits count, except for the value zero.

The number of units predefined for the lsu field is determined by DECNUMDIGITS, which defaults to 1 (the number of units will be DECNUMDIGITS divided by DECDPUN, rounded up to a whole unit).

For many applications, there will be a known maximum length for numbers and DECNUMDIGITS can be set to that length, as in Example 1. In others, the length may vary over a wide range and it then becomes the programmer’s responsibility to ensure that there are sufficient units available immediately following the decNumber lsu field. This can be achieved by enclosing the decNumber in other structures which append various lengths of unit arrays, or in the more general case by allocating storage with sufficient space for the other decNumber fields and the units of the number.

lsu is an array of type decNumberUnit (an unsigned integer whose length depends on the value of DECDPUN), with at least one element. If digits needs fewer units than the size of the array, remaining units are not used (they will neither be changed nor referenced). For special values, only the first unit need be 0.

It is expected that decNumbers will usually be constructed by conversions from other formats, such as strings or decimal64 structures, so the decNumber structure is in some sense an ‘internal’ representation; in particular, it is machine-dependent.[1] 

Examples:

If DECDPUN were 4, the value -1234.50 would be encoded with:

  • digits = 6
  • exponent = -2
  • bits = 0x80
  • lsu = {3450, 12}
  • the value 0 would be:
  • digits = 1
  • exponent = 0
  • bits = 0x00
  • lsu = {0}
  • and –¥ (minus infinity) would be:
  • digits = 1
  • exponent = 0
  • bits = 0xC0
  • lsu = {0}

  • Definitions

    The decNumber.h header file defines the decNumber data structure described above. It also includes:


    Functions

    The decNumber.c source file contains the public functions defined in the header file. These comprise conversions to and from strings, the arithmetic operations, and some utility functions.

    The functions all follow some general rules:


    Conversion functions

    The conversion functions build a decNumber from a string, or lay out a decNumber as a character string.

    decNumberFromString(number, string, context)

    This function is used to convert a character string to decNumber format. It implements the to-number conversion from the arithmetic specification.

    The conversion is exact provided that the numeric string has no more significant digits than are specified in context.digits. If there are more digits in the string, the value will be rounded to fit, using the context.round rounding mode. The context.digits field therefore both determines the maximum precision for unrounded numbers and defines the minimum size of the decNumber structure required.

    The arguments are:

    number
    (decNumber *) Pointer to the structure to be set from the character string.

    string
    (char *) Pointer to the input character string. This must be a valid numeric string, as defined in the appropriate specification. The string will not be altered.

    context
    (decContext *) Pointer to the context structure whose digits, emin, and emax fields indicate the maximum acceptable precision and exponent range, and whose status field is used to report any errors. If its extended field is 1, then special values (±Inf, ±Infinity, ±NaN, or ±sNaN, independent of case) are accepted, and the sign and exponent of zeros are preserved. NaNs may also specify diagnostic information as a string of digits immediately following the name.

    Returns number.

    Possible errors are DEC_Conversion_syntax (the string does not have the syntax of a number, which depends on the setting of extended in the context), DEC_Overflow (the adjusted exponent of the number is larger than context.emax), or DEC_Underflow (the adjusted exponent is less than context.emin and the conversion is not exact). If any of these conditions are set, the number structure will have a defined value as described in the arithmetic specification (this may be a subnormal or infinite value).

    decNumberToString(number, string)

    This function is used to convert a decNumber number to a character string, using scientific notation if an exponent is needed (that is, there will be just one digit before any decimal point). It implements the to-scientific-string conversion.

    The arguments are:

    number
    (decNumber *) Pointer to the structure to be converted to a string.

    string
    (char *) Pointer to the character string buffer which will receive the converted number. It must be at least 14 characters longer than the number of digits in the number (number->digits).

    Returns string.

    No error is possible from this function. Note that non-numeric strings (one of +Infinity, –Infinity, NaN, or sNaN) are possible, and NaNs may have a – sign and/or diagnostic information.

    decNumberToEngString(number, string)

    This function is used to convert a decNumber number to a character string, using engineering notation (where the exponent will be a multiple of three, and there may be up to three digits before any decimal point) if an exponent is needed. It implements the to-engineering-string conversion.

    The arguments and result are the same as for the decNumberToString function, and similarly no error is possible from this function.


    Arithmetic functions

    The arithmetic functions all follow the same syntax and rules, and are summarized below. They all take the following arguments:

    number
    (decNumber *) Pointer to the structure where the result will be placed.

    lhs
    (decNumber *) Pointer to the structure which is the left hand side (lhs) operand for the operation. This argument is omitted for monadic operations.

    rhs
    (decNumber *) Pointer to the structure which is the right hand side (rhs) operand for the operation.

    context
    (decContext *) Pointer to the context structure whose settings are used for determining the result and for reporting any exceptional conditions.

    Each function returns number.

    Some functions, such as decNumberExp, as described as mathematical functions. These have some restrictions: context.emax must be < 106, context.emin must be > –106, and context.digits must be < 106. Non-zero operands to these functions must also fit within these bounds.

    The precise definition of each operation can be found in the specification documents.

    decNumberAbs(number, rhs, context)

    The number is set to the absolute value of the rhs. This has the same effect as decNumberPlus unless rhs is negative, in which case it has the same effect as decNumberMinus.

    decNumberAdd(number, lhs, rhs, context)

    The number is set to the result of adding the lhs to the rhs.

    decNumberCompare(number, lhs, rhs, context)

    This function compares two numbers numerically. If the lhs is less than the rhs then the number will be set to the value -1. If they are equal (that is, when subtracted the result would be 0), then number is set to 0. If the lhs is greater than the rhs then the number will be set to the value 1. If the operands are not comparable (that is, one or both is a NaN) the result will be NaN.

    decNumberCompareTotal(number, lhs, rhs, context)

    This function compares two numbers using the IEEE 754r proposed ordering. If the lhs is less than the rhs in the total order then the number will be set to the value -1. If they are equal, then number is set to 0. If the lhs is greater than the rhs then the number will be set to the value 1.

    The total order differs from the numerical comparison in that: –NaN < –sNaN < –Infinity < –finites < –0 < +0 < +finites < +Infinity < +sNaN < +NaN. Also, 1.000 < 1.0 (etc.) and NaNs are ordered by payload.

    decNumberDivide(number, lhs, rhs, context)

    The number is set to the result of dividing the lhs by the rhs.

    decNumberDivideInteger(number, lhs, rhs, context)

    The number is set to the integer part of the result of dividing the lhs by the rhs.

    Note that it must be possible to express the result as an integer. That is, it must have no more digits than context.digits. If it does then DEC_Division_impossible is raised.

    decNumberExp(number, rhs, context)

    The number is set to e raised to the power of rhs, rounded if necessary using the digits setting in the context and using the round-half-even rounding algorithm.

    Finite results will always be full precision and inexact, except when rhs is a zero or –Infinity (giving 1 or 0 respectively). Inexact results will almost always be correctly rounded, but may be up to 1 ulp (unit in last place) in error in rare cases.

    This is a mathematical function; the 106 restrictions on precision and range apply as described above.

    decNumberLn(number, rhs, context)

    The number is set to the natural logarithm (logarithm in base e) of rhs, rounded if necessary using the digits setting in the context and using the round-half-even rounding algorithm. rhs must be positive or a zero.

    Finite results will always be full precision and inexact, except when rhs is equal to 1, which gives an exact result of 0. Inexact results will almost always be correctly rounded, but may be up to 1 ulp (unit in last place) in error in rare cases.

    This is a mathematical function; the 106 restrictions on precision and range apply as described above.

    decNumberLog10(number, rhs, context)

    The number is set to the logarithm in base ten of rhs, rounded if necessary using the digits setting in the context and using the round-half-even rounding algorithm. rhs must be positive or a zero.

    Finite results will always be full precision and inexact, except when rhs is equal to an integral power of ten, in which case the result is the exact integer.

    Inexact results will almost always be correctly rounded, but may be up to 1 ulp (unit in last place) in error in rare cases.

    This is a mathematical function; the 106 restrictions on precision and range apply as described above.

    decNumberMax(number, lhs, rhs, context)

    This function compares two numbers numerically and sets number to the larger. If the numbers compare equal then number is chosen with regard to sign and exponent. Unusually, if one operand is a quiet NaN and the other a number, then the number is returned.

    decNumberMin(number, lhs, rhs, context)

    This function compares two numbers numerically and sets number to the smaller. If the numbers compare equal then number is chosen with regard to sign and exponent. Unusually, if one operand is a quiet NaN and the other a number, then the number is returned.

    decNumberMinus(number, rhs, context)

    The number is set to the result of subtracting the rhs from 0. That is, it is negated, following the usual arithmetic rules; this may be used for implementing a prefix minus operation.

    decNumberMultiply(number, lhs, rhs, context)

    The number is set to the result of multiplying the lhs by the rhs.

    decNumberNormalize(number, rhs, context)

    This function has the same effect as decNumberPlus except that the final result is set to its simplest form. That is, a non-zero number which has any trailing zeros in the coefficient has those zeros removed by dividing the coefficient by the appropriate power of ten and adjusting the exponent accordingly, and a zero has its exponent set to 0.

    decNumberPlus(number, rhs, context)

    The number is set to the result of adding the rhs to 0. This takes place according to the settings given in the context, following the usual arithmetic rules. This may therefore be used for rounding or for implementing a prefix plus operation.

    decNumberPower(number, lhs, rhs, context)

    The number is set to the result of raising the lhs to the power of the rhs, rounded if necessary using the settings in the context.

    Results will be exact when the rhs has an integral value and the result does not need to be rounded, and also will be exact in certain special cases, such as when the lhs is a zero (see the arithmetic specification for details).

    Inexact results will always be full precision, and will almost always be correctly rounded, but may be up to 1 ulp (unit in last place) in error in rare cases.

    This is a mathematical function; the 106 restrictions on precision and range apply as described above, except that the normal range of values and context is allowed if the rhs has an integral value in the range –1999999997 through +999999999.[2] 

    decNumberQuantize(number, lhs, rhs, context)

    This function is used to modify a number so that its exponent has a specific value, equal to that of the rhs. The decNumberRescale function may also be used for this purpose, but requires the exponent to be given as a decimal number.

    When rhs is a finite number, its exponent is used as the requested exponent (it provides a ‘pattern’ for the result). Its coefficient and sign are ignored.

    The number is set to a value which is numerically equal (except for any rounding) to the lhs, modified as necessary so that it has the requested exponent. To achieve this, the coefficient of the number is adjusted (by rounding or shifting) so that its exponent has the requested value. For example, if the lhs had the value 123.4567, and the rhs had the value 0.12, the result would be 123.46 (that is, 12346 with an exponent of -2, matching the exponent of the rhs).

    Note that the exponent of the rhs may be positive, which will lead to the number being adjusted so that it is a multiple of the specified power of ten.

    If adjusting the exponent would mean that more than context.digits would be needed in the coefficient, then the DEC_Invalid_operation condition is raised. This guarantees that in the absence of error the exponent of number is always equal to that of the rhs.

    If either operand is a special value then the usual rules apply, except that if either operand is infinite and the other is finite then the DEC_Invalid_operation condition is raised, or if both are infinite then the result is the first operand.

    decNumberRemainder(number, lhs, rhs, context)

    The number is set to the remainder when lhs is divided by the rhs.

    That is, if the same lhs, rhs, and context arguments were given to the decNumberDivideInteger and decNumberRemainder functions, resulting in i and r respectively, then the identity

      lhs = (i × rhs) + r
    
    holds.

    Note that, as for decNumberDivideInteger, it must be possible to express the integer part of the result as an integer. That is, it must have no more digits than context.digits. If it does then DEC_Division_impossible is raised.

    decNumberRemainderNear(number, lhs, rhs, context)

    The number is set to the remainder when lhs is divided by the rhs, using the rules defined in IEEE 854. This follows the same definition as decNumberRemainder, except that the nearest integer (or the nearest even integer if the remainder is equidistant from two) is used for i instead of the result from decNumberDivideInteger.

    For example, if lhs had the value 10 and rhs had the value 6 then the result would be -2 (instead of 4) because the nearest multiple of 6 is 12 (rather than 6).

    decNumberRescale(number, lhs, rhs, context)

    This function is used to rescale a number so that its exponent has a specific value, given by the rhs. The decNumberQuantize function may also be used for this purpose, and is often easier to use.

    The rhs must be a whole number (before any rounding); that is, any digits in the fractional part of the number must be zero. It must have no more than nine digits, or context.digits digits, (whichever is smaller) in the integer part of the number.

    The number is set to a value which is numerically equal (except for any rounding) to the lhs, rescaled so that it has the requested exponent. To achieve this, the coefficient of the number is adjusted (by rounding or shifting) so that its exponent has the value of the rhs. For example, if the lhs had the value 123.4567, and decNumberRescale was used to set its exponent to -2, the result would be 123.46 (that is, 12346 with an exponent of -2).

    Note that the rhs may be positive, which will lead to the number being adjusted so that it is a multiple of the specified power of ten.

    If adjusting the scale would mean that more than context.digits would be needed in the coefficient, then the DEC_Invalid_operation condition is raised. This guarantees that in the absence of error the exponent of number is always equal to the rhs.

    decNumberSameQuantum(number, lhs, rhs)

    This function is used to test whether the exponents of two numbers are equal. The coefficients and signs of the operands (lhs and rhs) are ignored.

    If the exponents of the operands are equal, or if they are both Infinities or they are both NaNs, number is set to 1. In all other cases, number is set to 0. No error is possible.

    decNumberSquareRoot(number, rhs, context)

    The number is set to the square root of the rhs, rounded if necessary using the digits setting in the context and using the round-half-even rounding algorithm. The preferred exponent of the result is floor(exponent/2).

    decNumberSubtract(number, lhs, rhs, context)

    The number is set to the result of subtracting the rhs from the lhs.

    decNumberToIntegralValue(number, rhs, context)

    The number is set to the rhs, with any fractional part removed if necessary using the rounding mode in the context.

    No error is possible, no flags are set (unless the operand is a signaling NaN), and the result may have a positive exponent.


    Utility functions

    The utility functions provide for copying, trimming, and zeroing numbers, and for determining the version of the decNumber package.

    decNumberCopy(number, source)

    This function is used to copy the content of one decNumber structure to another. It is used when the structures may be of different sizes and hence a straightforward structure copy by C assignment is inappropriate. It also may have performance benefits when the number is short relative to the size of the structure, as only the units containing the digits in use in the source structure are copied.

    The arguments are:

    number
    (decNumber *) Pointer to the structure to receive the copy. It must have space for source->digits digits.

    source
    (decNumber *) Pointer to the structure which will be copied to number. All fields are copied, with the units containing the source->digits digits being copied starting from lsu. The source structure is unchanged.

    Returns number. No error is possible from this function.

    decNumberIsInfinite(number)

    This function is used to test whether a number is infinite.

    The argument is:

    number
    (decNumber *) Pointer to the structure whose value is to be tested.

    Returns 1 (true) if the number is infinite, or 0 (false) otherwise. This function may be implemented as a macro; no error is possible.

    decNumberIsNaN(number)

    This function is used to test whether a number is a NaN (quiet or signaling).

    The argument is:

    number
    (decNumber *) Pointer to the structure whose value is to be tested.

    Returns 1 (true) if the number is a NaN, or 0 (false) otherwise. This function may be implemented as a macro; no error is possible.

    decNumberIsNegative(number)

    This function is used to test whether a number is negative (either minus zero or less than zero).

    The argument is:

    number
    (decNumber *) Pointer to the structure whose value is to be tested.

    Returns 1 (true) if the number is negative, or 0 (false) otherwise. This function may be implemented as a macro; no error is possible.

    decNumberIsQNaN(number)

    This function is used to test whether a number is a Quiet NaN.

    The argument is:

    number
    (decNumber *) Pointer to the structure whose value is to be tested.

    Returns 1 (true) if the number is a Quiet NaN, or 0 (false) otherwise. This function may be implemented as a macro; no error is possible.

    decNumberIsSNaN(number)

    This function is used to test whether a number is a Signaling NaN.

    The argument is:

    number
    (decNumber *) Pointer to the structure whose value is to be tested.

    Returns 1 (true) if the number is a Signaling NaN, or 0 (false) otherwise. This function may be implemented as a macro; no error is possible.

    decNumberIsZero(number)

    This function is used to test whether a number is a zero (either positive or negative).

    The argument is:

    number
    (decNumber *) Pointer to the structure whose value is to be tested.

    Returns 1 (true) if the number is zero, or 0 (false) otherwise. This function may be implemented as a macro; no error is possible.

    decNumberTrim(number)

    This function is used to remove insignificant trailing zeros from a number. That is, if the number has any fractional trailing zeros they are removed by dividing the coefficient by the appropriate power of ten and adjusting the exponent accordingly.

    The argument is:

    number
    (decNumber *) Pointer to the structure whose value is to be trimmed.

    Returns number. No error is possible from this function.

    decNumberVersion()

    This function returns a pointer (char *) to a human-readable description of the version of the decNumber package being run. The string pointed to will have at most 16 characters and will be a constant, and will comprise two words (the name and a decimal number identifying the version) separated by a blank. For example:
      decNumber 3.02
    
    No error is possible from this function.

    decNumberZero(number)

    This function is used to set the value of a decNumber structure to zero.

    The argument is:

    number
    (decNumber *) Pointer to the structure to be set to 0. It must have space for one digit.

    Returns number. No error is possible from this function.


    Footnotes:
    [1] The layout of an integer might be big-endian or little-endian, for example.
    [2] This relaxation of the restrictions provides upwards compatibility with an earlier version of the decNumberPower function which could only handle an rhs with an integral value.

    [previous | contents | next]