The decNumber Library, version 3.68
Copyright (c) IBM Corporation, 2010. All rights reserved. ©
23 Jan 2010
[previous | contents | next]

decimal32, decimal64, and decimal128 modules

The decimal32, decimal64, and decimal128 modules define the data structures and conversion functions for the IEEE 754 decimal-encoded compressed decimal formats which are 32, 64, or 128 bits (4, 8, or 16 bytes) long, respectively. These provide up to 7, 16, or 34 digits of decimal precision in a compact and machine-independent form. Details of the formats are available at:
  http://speleotrove.com/decimal/decbits.html 
These modules provide the interface between the compressed numbers and the decNumber internal format (and also provide string conversions). The decFloats modules provide arithmetic and other functions which work on data in the same formats directly. Example 7 and Example 8 in the User’s Guide show how to work with data in the formats with or without using the decNumber module.

Apart from the different lengths and ranges of the numbers, these three modules are identical, so this section just describes the decimal64 module. The definitions and functions for the other two formats are the same, except for the obvious name and value changes.

In this implementation each format is represented as an array of unsigned bytes. There is therefore just one field in the decimal64 structure:

bytes
The bytes field represents the eight bytes of a decimal64 number, using Densely Packed Decimal encoding for the coefficient.[1] 

The storage of a number in the bytes array is assumed to follow the byte ordering (‘endianness’) of the computing platform (if big-endian, then bytes[0] contains the sign bit of the format). The code in these modules requires that the DECLITEND tuning parameter be set to match the endianness of the platform.

Note that the equivalent structures in the decFloats modules are identical except for their names. It is therefore safe to cast pointers between them if they are the same size (for example between decimal64 and decDouble). This means that these modules can be used as proxies between the decNumber module and the decFloats modules.

The decimal64 module includes private functions for coding and decoding Densely Packed Decimal data; these functions are shared by the other compressed format modules. Hence, when using any of these three then decimal64.c must be compiled too.


Definitions

The decimal64.h header file defines the decimal64 data structure described above. It includes the decNumber.h header file, to simplify use, and (if not already defined) it sets the DECNUMDIGITS constant to 16, so that any declared decNumber will be the right size to contain any decimal64 number.

If more than one of the three decimal format header files are used in a program, they must be included in decreasing order of size so that the largest value of DECNUMDIGITS will be used.

The decimal64.h header file also contains:

The decimal64 module also contains the shared routines for compressing and expanding Densely Packed Decimal data, and uses the decDPD.h header file. The latter contains look-up tables which are used for encoding and decoding Densely Packed Decimal data (only three of of the tables in the header file are used). These tables are automatically generated and should not need altering.


Functions

The decimal64.c source file contains the public functions defined in the header file. These comprise conversions to and from strings and decNumbers, and some utilities.

When a decContext structure is used to report errors, the same rules are followed as for other modules. That is, a trap may be raised, etc.

decimal64FromString(decimal64, string, context)

This function is used to convert a character string to decimal64 format. It implements the to-number conversion in the arithmetic specification (that is, it accepts subnormal numbers, NaNs, and infinities, and it preserves the sign and exponent of 0). If necessary, the value will be rounded to fit.

The arguments are:

decimal64
(decimal64 *) 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 specification. The string will not be altered.

context
(decContext *) Pointer to the context structure which controls the conversion, as for the decNumberFromString function except that the precision and exponent range are fixed for each format (the values of emax, emin, and digits are ignored).

Returns decimal64.

Possible errors are DEC_Conversion_syntax (the string does not have the syntax of a number), DEC_Overflow (the adjusted exponent of the number is positive and is greater than emax for the format), or DEC_Underflow (the adjusted exponent of the number is negative and is less than emin for the format and the conversion is not exact). If one of these conditions is set, the decimal64 structure will have the value NaN, ±Infinity or the largest possible finite number, or a finite (possibly subnormal) number respectively, with the same sign as the converted number after overflow or underflow.

decimal64ToString(decimal64, string)

This function is used to convert a decimal64 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 in the arithmetic specification.

The arguments are:

decimal64
(decimal64 *) 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 DECIMAL64_String (24) characters long.

Returns string; no error is possible from this function.

decimal64ToEngString(decimal64, string)

This function is used to convert a decimal64 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 in the arithmetic specification.

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

decimal64FromNumber(decimal64, number, context)

This function is used to convert a decNumber to decimal64 format.

The arguments are:

decimal64
(decimal64 *) Pointer to the structure to be set from the decNumber. This may receive a numeric value (including subnormal values and –0) or a special value.

number
(decNumber *) Pointer to the input structure. The decNumber structure will not be altered.

context
(decContext *) Pointer to a context structure whose status field is used to report any error and whose other fields are used to control rounding, etc., as required.

Returns decimal64.

The possible errors are as for the decimal64FromString function, except that DEC_Conversion_syntax is not possible.

decimal64ToNumber(decimal64, number)

This function is used to convert a decimal64 number to decNumber form in preparation for arithmetic or other operations.

The arguments are:

decimal64
(decimal64 *) Pointer to the structure to be converted to a decNumber. The decimal64 structure will not be altered.

number
(decNumber *) Pointer to the result structure. It must have space for 16 digits of precision.

Returns number; no error is possible from this function.

decimal64Canonical(decimal64, source)

This function is used to ensure that a decimal64 number is encoded with the canonical form. That is, all declets use the preferred 1000 encodings and an infinity has a coefficient of zero.

The arguments are:

decimal64
(decimal64 *) Pointer to the structure to receive a copy of source, with canonical encoding.

source
(decimal64 *) Pointer to the structure to be converted to a canonical encoding.

Returns decimal64; no error is possible from this function.

decimal64IsCanonical(decimal64)

This function is used to test whether a decimal64 number is encoded with the canonical form. That is, that all declets use the preferred 1000 encodings and an infinity has a coefficient of zero.

The argument is:

decimal64
(decimal64 *) Pointer to the structure to be tested.

Returns an unsigned integer (uint32_t *) which is 1 if decimal64 has canonical encoding, or 0 otherwise. No error is possible from this function.


Footnotes:
[1] See http://speleotrove.com/decimal/DPDecimal.html for a summary of Densely Packed Decimal encoding.

[previous | contents | next]