Decimal floating-point built-in functions

Decimal floating-point built-in functions are provided for each DFP hardware instruction. XL C/C++ developers can use the decimal floating-point built-in functions and macros, or named constants, by calling the functions with appropriate parameters. It is not necessary to include a header file before using decimal floating-point built-in functions. They will be automatically defined by the compiler when DFP is enabled.

All decimal floating-point built-in functions require a hardware level of at least ARCH(7).

Single precision support is limited, as noted in Table 1.

Table 1. Decimal floating-point instruction prototypes for IEEE operations
PROTOTYPE and Notes® Description
_Decimal32   __d32_abs (_Decimal32); 
_Decimal64   __d64_abs (_Decimal64); 
_Decimal128   __d128_abs (_Decimal128); 
These functions return the absolute value of the parameter.
_Decimal32   __d32_copysign
 (_Decimal32 exponent_and_fraction, _Decimal32 sign);
  
_Decimal64   __d64_copysign 
(_Decimal64 exponent_and_fraction, _Decimal64 sign); 

_Decimal128   __d128_copysign
 (_Decimal128 exponent_and_fraction, _Decimal128 sign); 
These functions return the absolute value of the first parameter, with the sign of the second parameter.
_Decimal32   __d32_sNaN (void); 
_Decimal64   __d64_sNaN (void); 
_Decimal128   __d128_sNaN (void); 

_Decimal32   __d32_qNaN (void); 
_Decimal64   __d64_qNaN (void); 
_Decimal128   __d128_qNaN (void); 
These functions create quiet or signaling NaNs of the specified precision, with positive signs and zero payloads.
_Decimal64   __d64_integral (_Decimal64);
_Decimal128   __d128_integral (_Decimal128);
_Decimal64   __d64_integral_no_inexact (_Decimal64);
_Decimal128   __d128_integral_no_inexact (_Decimal128); 

The functions __d64_integral and __d128_integral allow an inexact exception. The instruction M4 bit 21 is set to 0.

The functions __d64_integral_no_inexact and __d128_integral_no_inexact suppress any inexact exception. The instruction M4 bit 21 is set to 1.

All these functions set the instruction M4 bit 20 to 0. If the input is a signaling NaN it is converted to a quiet NaN.

These functions round a decimal floating point value to an integer value in decimal floating point format; any digits after the decimal point are discarded. The current rounding mode is used.
_Decimal64   __d64_quantize
 (_Decimal64, _Decimal64, long round_mode); 

_Decimal128   __d128_quantize
 (_Decimal128, _Decimal128, long round_mode); 
The round_mode parameter must be a compile-time constant expression. Use either of the following:
These functions return the arithmetic value of the first parameter, with the exponent adjusted to match the second parameter. They can temporarily override the current rounding mode and use the specified rounding mode.
bool   __d64_same_quantum (_Decimal64, _Decimal64); 
bool   __d128_same_quantum (_Decimal128, _Decimal128); 
These functions compare the exponents of two parameters. If the exponents are the same, the functions return "true".
long   __d64_compare_signaling (_Decimal64, _Decimal64); 
long   __d128_compare_signaling (_Decimal128, _Decimal128); 

These functions normally return <0, ==0 or >0 to indicate the relation. If either value is a NaN, they return "-2" (unordered).

These functions compare two decimal floating-point values. Unlike a comparison using standard equality or relational operators, they also raise an Invalid Operation exception when either operand is either a quiet Nan or a signaling NaN.

long long   __d64_to_long_long (_Decimal64); 
long long   __d128_to_long_long (_Decimal128); 

long long   __d64_to_long_long_rounding (_Decimal64, long round_mode); 
long long   __d128_to_long_long_rounding (_Decimal128, long round_mode); 

The functions __d64_to_long_long ( ) and __d128_to_long_long ( ) use the current decimal rounding mode, while a cast always rounds towards zero.

The functions __d64_to_long_long_rounding ( ) and __d128_to_long_long_rounding ( ) can temporarily override the current rounding mode and use the specified rounding mode.

The round_mode parameter must be a compile-time constant expression. Use either of the following:
These functions convert a decimal floating point value to a 64-bit signed binary integer with rounding mode options.

unsigned long __dfp_get_round_mode (void);

This function gets the current decimal rounding mode from the z/Architecture® FPC register.

void __dfp_set_round_mode (unsigned long round_mode);

If the rounding mode is changed within a function, it must be restored before the function returns.
This function sets the specified decimal rounding mode in the z/Architecture FPC register, making it the current mode.
Table 2. Decimal floating-point instruction prototypes for IEEE . . . is operations
PROTOTYPE and Notes Description
bool __d32_isfinite (_Decimal32); 
bool __d64_isfinite (_Decimal64); 
bool __d128_isfinite (_Decimal128); 
These functions return "true" if the parameter is not positive or negative infinity, and is not a NaN.
bool __d32_isinf (_Decimal32); 
bool __d64_isinf (_Decimal64); 
bool __d128_isinf (_Decimal128);
These functions return "true" if the parameter is positive or negative infinity.
bool __d32_isnormal (_Decimal32);  
bool __d64_isnormal (_Decimal64); 
bool __d128_isnormal (_Decimal128); 
These functions return "true" if the parameter is in the normal range, not a subnormal, infinity or NaN.
bool __d32_issignaling (_Decimal32); 
bool __d64_issignaling (_Decimal64); 
bool __d128_issignaling (_Decimal128); 
These functions return "true" if the parameter is positive or negative signaling NaN.
bool __d32_issigned (_Decimal32);
bool __d64_issigned (_Decimal64); 
bool __d128_issigned (_Decimal128); 
These instructions return "true" if the parameter is negative, including negative zero, negative infinity and negative NaN.
bool __d32_issubnormal (_Decimal32);
bool __d64_issubnormal (_Decimal64); 
bool __d128_issubnormal (_Decimal128); 
These functions return "true" if the parameter is a subnormal.
bool __d32_iszero (_Decimal32);
bool __d64_iszero (_Decimal64); 
bool __d128_iszero (_Decimal128); 
These functions return "true" if the parameter is positive or negative zero.
Table 3. Decimal floating-point instruction prototypes for IBM Instructions
PROTOTYPE and Notes Description
_Decimal32   __d32_nabs (_Decimal32);
_Decimal64   __d64_nabs (_Decimal64); 
_Decimal128   __d128_nabs (_Decimal128); 
These functions return the negative of the absolute value of the parameter.
long long   __d32_to_gpr (_Decimal32); 
long long   __d64_to_gpr (_Decimal64); 
void   __d128_to_gprs (_Decimal128, long long *upper, long long *lower); 
These functions transfer a value from an FPR or FPR pair to a GPR, GPR pair, or four GPRs.
_Decimal32   __gpr_to_d32 (long long);  
_Decimal64   __gpr_to_d64 (long long);  
_Decimal128   __gprs_to_d128 (long long upper, long long lower); 
These functions transfer a value from a GPR, GPR pair, or four GPRs to an FPR or FPR pair.
_Decimal32   __d64_round_to_d32
 (_Decimal64, unsigned long round_mode, bool suppress_invalid); 

_Decimal64   __d128_round_to_d64
 (_Decimal128, unsigned long round_mode, bool suppress_invalid);
The round_mode parameter must be a compile-time constant expression. Use either of the following:
If the input value is a signaling NaN, and:
  • If suppress_invalid is false, the result will be a quiet NaN and an invalid operation exception will be raised.
  • If suppress_invalid is true, the result will be a signaling NaN and no exception will be raised.
These functions convert a value to a narrower format, with rounding control and invalid exception control that is unavailable when using a cast.
long long   __d64_to_signed_BCD (_Decimal64, bool CF); 

void   __d128_to_signed_BCD (_Decimal128, bool CorF,
                           unsigned long long *upper,
                           unsigned long long *lower); 

__d64_to_signed_BCD produces 15 decimal digits followed by a decimal sign in a 64-bit result.

__d128_to_signed_BCD produces 31 decimal digits followed by a decimal sign in a 128-bit result.

Negative values will be given the sign 0xD.

If CorF is false, positive values will be given the sign 0xC.

If CorF is true, positive values will be given the sign 0xF.

These functions convert the lower digits of the parameter to signed packed format.
_Decimal64   __signed_BCD_to_d64 (signed long long); 

_Decimal128   __signed_BCD_to_d128 (signed long long upper,
                                    signed long long lower); 

The signs 0xA, 0xC, 0xE, and 0xF will be treated as positive, and 0xB and 0xD as negative.

__signed_BCD_to_d64 converts 15 decimal digits followed by a decimal sign in a 64-bit input.

__signed_BCD_to_d128 converts 31 decimal digits followed by a decimal sign in a 128-bit input.

These functions convert signed packed decimal to decimal floating point.
_Decimal64   __unsigned_BCD_to_d64 (unsigned long long); 
_Decimal128   __unsigned_BCD_to_d128 (unsigned long long upper,
                                      unsigned long long lower); 

__unsigned_BCD_to_d64 converts 16 decimal digits with no sign in a 64-bit input.

__unsigned_BCD_to_d128 converts 32 decimal digits with no sign in a 128-bit input.

These functions convert the lower digits of the parameter to unsigned packed format.
_Decimal64   __d64_reround
 (_Decimal64, unsigned long number_of_digits, unsigned long round_mode); 

_Decimal128   __d128_reround
 (_Decimal128, unsigned long number_of_digits, unsigned long round_mode); 
The round_mode parameter must be a compile-time constant expression. Use either of the following:
These functions round a value to fewer digits. They can temporarily override the current rounding mode. For correct rounding, the input value must have been calculated using

ROUND_TO_PREPARE_FOR
_SHORTER_PRECISION

For details, see Definitions that support FPC register-rounding macros.
_Decimal64   __d64_insert_biased_exponent
 (_Decimal64, long biased_exponent); 

_Decimal128   __d128_insert_biased_exponent
 (_Decimal128, long biased_exponent); 
Notes:
  1. Also see the functions that return the exponent of a specified parameter.
  2. For the type definitions of infinity, quiet NaN, or signaling NaN, see Biased exponent definitions.
These functions return the digits and sign of the first parameter with the biased exponent of the second parameter, with special values for infinity, quiet NaN, or signaling NaN.
_Decimal64   __d64_shift_left
 (_Decimal64, unsigned long number_of_digits); 

_Decimal128   __d128_shift_left
 (_Decimal128, unsigned long number_of_digits); 
These functions return the parameter with the coefficient shifted to the left. The sign and exponent are unchanged. The shift count must be in the 0-to-63 range; otherwise the result is undefined.
_Decimal64   __d64_shift_right
 (_Decimal64, unsigned long number_of_digits); 

_Decimal128   __d128_shift_right
 (_Decimal128, unsigned long number_of_digits); 
These functions return the parameter with the coefficient shifted to the right. The sign and exponent are unchanged. The shift count must be in the 0-to-63 range; otherwise the result is undefined.
long   __d32_test_data_class
 (_Decimal32, unsigned long data_class_mask); 

long   __d64_test_data_class
 (_Decimal64, unsigned long data_class_mask); 

long   __d128_test_data_class
 (_Decimal128, unsigned long data_class_mask); 
These functions:
  • Determine the exponent type (zero, subnormal, normal, infinity, quiet NaN or signaling NaN) and sign of the value.
  • Return a long integer that indicates whether the exponent matches the mask specifications. If there is a match, the function returns "1"; if there is no match, the function returns "0".
    Note: The mask must be a constant expression at compile time. See Test Data Class masks.
Also see test data group functions.
These functions determine whether a parameter is in a defined data class or a set of data classes, by testing its exponent and sign.
long   __d32_test_data_group
 (_Decimal32, unsigned long data_group_mask); 

long   __d64_test_data_group
 (_Decimal64, unsigned long data_group_mask); 

long   __d128_test_data_group
 (_Decimal128, unsigned long data_group_mask);  
These functions:
  • Determine the exponent type (safe zero, subnormal, normal with no leading zero, or an infinity or NaN), as well as the sign and first digit of the parameter.
    Notes:
    1. A "safe zero" has leading zero digits and a non-extreme exponent.
    2. A "subnormal" can appear as either an extreme non-zero or a safe non-zero.
  • Return a long integer that indicates whether the exponent matches the mask specifications. If there is a match, the function returns "1"; if there is no match, the function returns "0".
    Note: The mask must be a constant expression at compile time. For the statements that define these masks, see Test Data Group masks.
Also see the test data class functions.
These functions determine whether a parameter is in a defined data group or set of data groups, by testing its exponent, sign and first digit.
long   __d64_biased_exponent (_Decimal64); 
long   __d128_biased_exponent (_Decimal128); 
These functions return the exponent of the parameter as an integer.
unsigned long long   __d64_to_unsigned_BCD (_Decimal64); 

void   __d128_to_unsigned_BCD (_Decimal128, 
                               bool CorF,
                               unsigned long long *upper,
                               unsigned long long *lower); 

Positive values will be given the sign 0xC if CorF is false or 0xF if it is true. Negative values will be given the sign 0xD.

__d64_to_unsigned_BCD produces 16 decimal digits with no sign in a 64-bit result.

__d128_to_unsigned_BCD produces 32 decimal digits with no sign in a 128-bit result.
Note: Any digits to the left of those are ignored. To access the ignored digits, use the appropriate __d#_shift_right function.
These functions convert the lower digits of the parameter to unsigned packed format.
long   __d64_compare_exponents (_Decimal64, _Decimal64); 
long   __d128_compare_exponents (_Decimal128, _Decimal128); 

If both exponents are finite, these return "<0", "==0" or ">0" to indicate the relation between the exponents.

If both exponents are infinite, they return "0".

If one exponent is infinite and the other is finite, they return "-2" (unordered).

These functions compare exponents to one another.
long   __d64_extract_significance (_Decimal64);  
long   __d128_extract_significance (_Decimal128); 
These functions normally return the number of significant digits in the input value.
Exceptions:
  • When the input is a zero, the return value is "0".
  • When the input is an infinity, the return value is "-1".
  • When the input is a quiet NaN, the return value is "-2".
  • When the input is a signaling NaN, the return value is "-3".
 void   __SFASR (unsigned long); 
This function modifies the Floating Point Control (FCP) register, and could raise an exception.
IBM® zEnterprise® EC12 provides hardware instructions for conversions between decimal floating-point and zoned types. When both the DFP and ARCH(10) compiler options are in effect, the following hardware built-in functions are available:
Table 4. Instruction prototypes for conversions between decimal floating-point and zoned types
PROTOTYPE and Notes Description
_Decimal64 __cdzt(void* source, 
                  unsigned char length, 
                  const unsigned char mask);

_Decimal128 __cxzt(void* source, 
                   unsigned char length, 
                   const unsigned char mask);

The source points to the memory location that contains data in valid zoned format.

The length specifies the length of the source field encoded in the machine instruction. The range of the length value can be "0-15" for __cdzt and "0-33" for __cxzt. When the length value is not a literal, an EX instruction is generated to execute a target CDZT or CXZT instruction.

The mask value provides the M3 value encoded in the machine instruction. The mask value must be provided as a literal.

The return value is the converted decimal floating-point value.

These functions convert zoned type to decimal floating-point type.
int __czdt(_Decimal64 source, 
           void* result, 
           unsigned char length, 
           const unsigned char mask);

int __czxt(_Decimal128 source, 
           void* result, 
           unsigned char length, 
           const unsigned char mask);

The source contains the decimal floating-point value to be converted.

The result points to the memory location that receives the converted data in zoned format.

The length specifies the number of rightmost digits of the decimal floating-point value to be converted. The length value specifies the length of the result field encoded in the machine instruction in bytes. The range of the length value can can be "0-15" for __czdt and "0-33" for __czxt. When the length value is not a literal, an EX instruction is generated to execute a target CZDT or CZXT instruction.

The mask value provides the M3 value encoded in the machine instruction. The mask value must be provided as a literal.

The return value is the condition code set by the instruction.

These functions convert decimal floating-point type to zoned type.