===========================================================================

				  Libdfp
	    The "Decimal Floating Point C Library" User's Guide
		   for the GNU/Linux OS and GLIBC 2.10+
		      Contributed by IBM Corporation
	    Copyright (C) 2010 - 2014 Free Software Foundation

===========================================================================
NOTE:Eight space tabs are the optimum editor setting for reading this file.
===========================================================================

		Author(s) : Ryan S. Arnold <rsa@us.ibm.com>
		      Date Created: January 27, 2010
		       Last Changed: August 8, 2012

---------------------------------------------------------------------------
Table of Contents:

	1.  Introduction
	  1.1.  ISO/IEC TR 24732
	  1.2.  ISO/IEC DTR 24733
	  1.3.  IEEE 754-2008 (DPD & BID Encodings)
	  1.4.  Backends (libdecnumber & libbid)
	2.  Availability
	3.  Compliance With ISO/IEC TR 24732
	  3.1  __STDC_DEC_FP__
	  3.2  __STDC_WANT_DEC_FP__
	  3.3  GNU99 Compatibility
	  3.4  _Decimal[32|64|128] Data Types
	    3.4.1  _Decimal[32|64|128] Encoding
	  3.5  scanf Support
	  3.6  printf Support
	    3.5.1 printf "a,A" Conversion Specifier
	4.  Compliance With ISO/IEC DTR 24733
	  4.1  C++ decimal[32|64|128] Types Compatibility
	  4.2  C++ decimal[32|64|128] operator<< and operator>> Support
	  4.3  Printing decimal[32|64|128] Types and Precision
	5.  Dependencies
	  5.1  GNU/Linux OS
	  5.2  GLIBC Minimum Version
	  5.3  GCC With --enable-decimal-float Support
	6.  DFP Headers
	7.  Compile and Link
	8.  Unsupported/Non-Standard Additions
	9.  Known Limitations

---------------------------------------------------------------------------
1.  Introduction

The "Decimal Floating Point C Library" is an implementation of ISO/IEC
Technical report  "ISO/IEC TR 24732" which describes the C-Language library
routines necessary to provide the C library runtime support for decimal
floating point data types introduced in IEEE 754-2008, namely _Decimal32,
_Decimal64, and _Decimal128.

---------------------------------------------------------------------------
1.1. ISO/IEC TR 24732

The decimal floating point extension to the C programming language is
described in the ratified ISO/IEC Technical Report 24732.

The latest description of ISO/IEC TR 24732 at the time of this writing can
be found here:

	http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1312.pdf

A rationale can be found here:

	http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1242.pdf

And the last draft for new standard can be found at:

	http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1775.pdf

---------------------------------------------------------------------------
1.2.  ISO/IEC DTR 24733

The decimal floating point extension to the C++ programming language is
described in ISO/IEC DRAFT Technical Report 24733.

The latest description of ISO/IEC DTR 24733 at the time of this writing
can be found here:

	http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2849.pdf	

---------------------------------------------------------------------------
1.3. IEEE754-2008 (DPD & BID Encodings)

IEEE 754-2008 defines two different encodings for the decimal floating
point data types.  These are DPD and BID.

	DPD (Densely Packed Decimal) - IBM sponsored encoding (implemented
				       in hardware).

	BID (Binary Integer Decimal) - Intel sponsored encoding.

A simple explanation of the general overview of Decimal Floaing Point
can be found at

	http://speleotrove.com/decimal/decbits.pdf

The BID format encoding general explanation can be found at

	BID - Binary-Integer Decimal Encoding for Decimal Floating Point
	| Ping Tak Peter Tang
	http://m1.archiveorange.com/m/att/KGyKy/ArchiveOrange_Ps0PWkD0ZgCLBVQYnJEcnXblPpEa.pdf

Both encodings can be investigated in the draft IEEE754r:

	http://754r.ucbtest.org/drafts/archive/2006-10-04.pdf

---------------------------------------------------------------------------
1.4. Backends (libdecnumber & libbid)

Libdfp use of "libdecnumber" backend library for software emulation. And
for the most part, a user of libdfp should not have to be concerned with
the libdfp backend.

The user's interface is that defined by ISO/IEC TR 24732, i.e. the Decimal
Floating Point addition to the C Language specification.

---------------------------------------------------------------------------
2. Availability

Libdfp attempts to provide an encoding agnostic API to users based upon the
_Decimal32, _Decimal64, and _Decimal128 data-types and the proposed C-Language
extension for Decimal Floating Point Types.

---------------------------------------------------------------------------
3. Compliance With ISO/IEC TR 24732

This section covers issues related to compliance with ISO/IEC TR 24732, the
ratified ISO C DFP Technical Report.

---------------------------------------------------------------------------
3.1 __STDC_DEC_FP__

The draft standard ISO/IEC TR 24732 specifies the macro __STDC_DEC_FP__ as
integer constant 200805L to indicate conformance to the technical report.

This macro describes properties of the compiler and library that together
satisfy the technical report.

The intention is that user applications may check for conformance with the
following:

#ifdef __STDC_DEC_FP__
/* Select implementation conforming to the TR.  */
#else
/* Select non-conforming DFP emulation library.  */
#endif

Since __STDC_DEC_FP__ is a property fulfilled by both the compiler and
library the compiler can't predefine this macro without know if the user is
using libdfp.  There is currently no mechanism for the compiler to
determine this early in the translation unit.

This will eventually be provided, once a mechanism is added into GLIBC and
GCC for identifying stdc predefines as highlighted in this email:

http://sourceware.org/ml/libc-alpha/2009-04/msg00005.html

At that point libdfp will provide __STDC_DEC_FP__ for GLIBC versions
greater than FOO and GCC versions greater than BAR.

---------------------------------------------------------------------------
3.2 __STDC_WANT_DEC_FP__

The standard ISO/IEC TR 24732 indicates that programs that wish to use
Decimal Floating Point should define the following macro:

	__STDC_WANT_DEC_FP__

There is no set value for this macro.

Simply passing -D__STDC_WANT_DEC_FP__ on compilation, or defining it in your
program should suffice:

#define __STDC_WANT_DEC_FP__

This macro is REQUIRED when including dfp/math.h dfp/fenv.h, etc to pick
up the DFP function prototypes and data types defined in these headers.

---------------------------------------------------------------------------
3.3 GNU99 Compatibility

GNU99 compatibility is required to pick up some DFP prototypes that are
similar to the binary floating point prototypes guarded in <math.h> by
__USE_ISOC99 and others.  It will define __USE_ISOC99.

Use the following compilation flag: -std=gnu99

NOTE: -std=gnu99 IS NOT THE SAME AS __USE_ISOC99 though -std=gnu99 DOES
DEFINE __USE_ISOC99!  Additionally, simply using -std=c99 isn't enough!

NOTE: If you forget to use -std=gnu99 you may notice that you will get very
screwy results when you call dfp math functions.  If the compiler can't find
the prototypes (due to missing defines) it will attempt to create a default
prototype which will have an incorrect return type.

Compile with -Wall to pick up undefined prototype warnings.

---------------------------------------------------------------------------
3.4  _Decimal* Data Types

The Decimal Floating Point data types are as follows:

	_Decimal32
	_Decimal64
	_Decimal128

The floating point suffix for DFP constants follows:

	'DF' for _Decimal32, e.g. _Decimal32 d32 = 1.045DF;
	'DD' for _Decimal64, e.g. _Decimal64 d64 = 1.4738273DD;
	'DL' for _Decimal128, e.g. _Decimal128 d128 = 1.0823382394823945DL;

NOTE: Assigning a naked constant to a DFP variable will actually be
performing a binary to decimal conversion and, depending on the precision,
can assign an incorrect number.  Always use the decimal floating point
suffix, e.g.,

	_Decimal64 d64 = 1.0DD;

The following will result in a binary float to decimal float conversion:

	_Decimal64 d64 = 1.0;

---------------------------------------------------------------------------
3.4.1  _Decimal[32|64|128] Encoding

Consider the following _Decimal64 values and encodings (displayed in declet
triples):

	/* Encoded as "+1,000,000,000,000,000e+285"  */
	_Decimal64 d64 = 1.000000000000000e300DD;

	/* Encoded as "+0,000,000,000,000,001e+300"  */
	_Decimal64 e64 = 1e300DD;

These values are equivalent in comparison but there is inherently more
precision in the first value and this should be preserved when the value is
printed.

As described in section 3.6.1, the a/A conversion specifier is used to
direct printf to use the precision encoded in the actual value for the
output string precision.

---------------------------------------------------------------------------
3.5 scanf Support

Libdfp does not, and will not comply with the TR 24732 requirement for the
addition of scanf in support of decimal floating point data types.  The
strtod[32|64|128] functions can be used for the same purpose without the
implications of scanf.

This is main due the fact GLIBC does not support scanf hooks as it does
for printf.

---------------------------------------------------------------------------
3.6 printf Support

Libdfp supports the addition of the printf format codes indicated by TR
24732.  GLIBC proper owns the printf implementation.  Libdfp utilizes the
printf-hooks mechanism provided by GLIBC to register support of the DFP
format codes.

The fully functional printf-hooks mechanism was debuted in GLIBC 2.10.

Libdfp has a library constructor which registers the Libdfp printf handlers
with the libc.  If the version of GLIBC that is loaded when your application
is executed is too old (pre-2.10) and doesn't have the printf-hooks interface
you will get an undefined reference error against GLIBC.

When libdfp is loaded printf will recognize the following length modifiers:

	%H - for _Decimal32
	%D - for _Decimal64
	%DD - for _Decimal128

It will recognize the following conversion specifier 'spec' characters:

	e,E
	f,F
	g,G
	a,A  (as debuted in ISO/IEC TR 24732)

Therefore, any combination of DFP length modifiers and spec characters is
supported.

3.6.1 printf "a,A" Conversion Specifier
---------------------------------------------------------------------------

The ISO-C DFP specification adds "a/A" as a printf conversion specifier.
This conversion specifier is unique in that when it is used the precision
of the output string includes as many of the significant digits in the
mantissa in the as possible unless there are fewer digits in the mantissa
than in the specified precision.  Following are some examples to
demonstrate the use of the a/A conversion specifier.

	printf("Result: %.1HaDF\n", 6543.00DF);

	Result: 7E+3DF

	printf("Result: %.5HaDF\n", 6543.00DF);

	Result: 6543.0DF

	printf("Result: %.4HaDF\n", 6543.00DF);

	Result: 6543DF

	/* Example where the implicit number of digits is less than the
	 * explicit precision.  */
	printf("Result: %.8HaDF\n", 6543.00DF);

	Result: 6543.00DF

If your compiler is being pedantic you may get the following warning (due
to -Wformat) when using the a/A conversion specifier with the H/D/DD
length modifiers.

	warning: use of ‘H’ length modifier with ‘A’ type character [-Wformat]

This is not a real problem.  It simply hints at the issue described in
section 3.1.  When the compiler and library are able to define
__STDC_DEC_FP__ then the compiler can detect that libdfp is available and
that a/A conv specifier is a valid combination with the H/D?DD length
modifiers.

---------------------------------------------------------------------------
4. Compliance With ISO/IEC DTR 24733

This section covers issues related to compliance with ISO/IEC DTR 24733,
the ISO C++ DFP Draft Technical Report.

4.1  C++ decimal[32|64|128] Types Compatibility
---------------------------------------------------------------------------

Your C++ compiler may not yet provide the ISO C DFP _Decimal[32|64|128]
types.

Per the C++ DFP specification: ISO/IEC JTC1 SC22 WG21 N2732 "Extension for
the programming language C++ to support decimal floating point arithmetic",
the header float.h shall include the following C-compatibility convenience
typedefs:

	typedef std::decimal::decimal32  _Decimal32;
	typedef std::decimal::decimal64  _Decimal64;
	typedef std::decimal::decimal128 _Decimal128;

This allows C++ programs, which use the native decimal32, decimal64, and
decimal128 types to use the _Decimal32, _Decimal64, and_Decimal128
types.

Your compiler may or may not yet have this defined in float.h.  As a matter
of convenience, libdfp has provided these headers in the libdfp headers
directory include/dfp/float.h

4.2  C++ decimal[32|64|128] operator<< and operator>> Support
---------------------------------------------------------------------------

Your C++ compiler may not provide operator<< and operator>> support
for std::decimal::decimal[32|64|128] data types.  Per the C++ DFP
specification: ISO/IEC JTC1 SC22 WG21 N2732 "Extension for the programming
language C++ to support decimal floating point arithmetic", the header
<decimal> shall provide the following operator overloads.

namespace std {
namespace decimal {

  template <class charT, class traits>
    std::basic_istream<charT, traits> &
      operator>>(std::basic_istream<charT, traits> & is,
                 decimal32 & d);

  template <class charT, class traits>
    std::basic_istream<charT, traits> &
      operator>>(std::basic_istream<charT, traits> & is,
                 decimal64 & d);

  template <class charT, class traits>
    std::basic_istream<charT, traits> &
      operator>>(std::basic_istream<charT, traits> & is,
                 decimal128 & d);

  template <class charT, class traits>
    std::basic_ostream<charT, traits> &
      operator<<(std::basic_ostream<charT, traits> & os,
                 decimal32 d);

  template <class charT, class traits>
    std::basic_ostream<charT, traits> &
      operator<<(std::basic_ostream<charT, traits> & os,
                 decimal64 d);

  template <class charT, class traits>
    std::basic_ostream<charT, traits> &
      operator<<(std::basic_ostream<charT, traits> & os,
                 decimal128 d);
}}

Per http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51486, since C++ decimal
support is defined in a technical report and not ratified into the actual
C++ standard the <decimal> header shouldn't be located in the default
headers include directory.  As a result the <decimal> header is located in
the include/decimal directory.  Therefore, in order to include the decimal
header implicitly use the following in applications:

#include <decimal/decimal>

4.3  Printing decimal[32|64|128] Types and Precision
---------------------------------------------------------------------------

Libdfp provides two mechanisms for printing decimal floating-point data
types in string representation.  These are via the C++ ostream operator
"<<" for decimal[32|64|128] data types and the ISO C printf interface
(described in section 3.6) for _Decimal[32|64|128] data types.

The ISO C DFP Technical Report provides well described extensions to the
printf interface for decimal floating-point types.

Unfortunately, the DFP C++ Draft Technical Report simply describes the
ostream operator that needs to be provided for string formatting but does
not fully describe the procedure for printing full precision decimal
types considering the fully encoded precision in decimal types.  Please
refer to section 3.4.1 for a discussion of the encoding.

The base C++ specification describes ostream operator support for
floating-point types as equivalent to corresponding ISO C printf conversion
specifiers (as described in the following table):

C++ ios_base::fmtflags       | ISO C printf equivalent conv spec
-----------------------------|-----------------------------------------
<default-no-flags>           |    g
ios::fixed                   |    f
ios::scientific              |    e
ios::fixed | ios::scientific |    a
ios::upper                   |    G/F/E/A
ios::lower                   |    g/f/e/a

Since the DFP C++ Draft Technical Report makes no explicit provisions for
format codes specific to decimal floating-point types the Libdfp
implementation falls back on the equivalency to printf conversion
specifiers described in this table.

Under binary floating-point the a/A spec is used to print hexadecimal
representation of floating point values, which is why no precision is
allowed to convert (truncate and round) the output string representation.

The C++ specification indicates that a/A is specified by passing
ios::fixed | ios::scientific in the ios_base::fmtflags for the stream.  When
this combination of flags is specified the precision set in the ostream
(whether the default or user specified) is not honored or used in the
printing of the type.

As described in section 3.5.1, the overridden a/A conversion specifier is
the most desireable conversion specifier used with printf for decimal
floating-point types since it preserves the encoded precision in the output
string representation by default (when no explicit precision is specified).

Since there is no interface specified in the DFP C or C++ specifications
for querying the number of significant digits in a decimal floating-point
value the user should most often use the a/A conversion specifier in order
to preserve significant digits.

The caveat, of course, is that since the C++ specification does not provide
a way to programmatically determine whether the queried stream precision is
the default of '6', or a value set by the user, nor does the C++
specification allow stream precision to be considered when printing the a/A
style conversion, this ostream operator implementation can not pass the
stream precision on to the printf function.

Therefore, all use of (ios::fixed | ios::scientific) will result in full
precision output and it will not honor the output precision specified in
the stream.

---------------------------------------------------------------------------
5. Dependencies

---------------------------------------------------------------------------
5.1 GNU/Linux OS

Libdfp is only enabled to work on the GNU/Linux OS.

---------------------------------------------------------------------------
5.2 GLIBC Minimum Version

Libdfp version 1.0.0 relies upon a minimum GLIBC 2.10 for printf-hooks
support.  The libdfp configure stage will check the libc that it is linked
against for the printf-hook support and will warn if it is not found.

---------------------------------------------------------------------------
5.3 GCC With --enable-decimal-float Support

There's a dependency on a version of GCC which supports Decimal Floating
Point.  Use the following to determine if your compiler supports it:

	gcc -v 2>&1 | grep "\-\-enable\-decimal\-float"

If decimal floating point support is not available in your compiler the
libdfp configure stage will fail with a warning.

---------------------------------------------------------------------------
6.  DFP Headers

The following Libdfp headers extend the existing system headers.  If the path
to the Libdfp headers is included in the search path then these will be picked
up prior to the system headers.

	dfp/fenv.h
	dfp/math.h
	dfp/stdlib.h
	dfp/wchar.h
	dfp/float.h
	dfp/decimal/decimal

Each of these headers uses the GCC construct #include_next in order to pick up
the system header as well, e.g.,

	dfp/math.h will #include_next <math.h>
	dfp/decimal/decimal will #include_next <decimal/decimal>

This mechanism allows Libdfp to add the Decimal interfaces required by the
specification to the aforementioned headers.

In order to pick up the Libdfp prototypes and classification macro
overrides compile with the following:

  -I/pathto/include/dfp/ -D__STDC_WANT_DEC_FP__=1

Using -I instead of -isystem is suggested because -I indicates that the
specified headers are picked up BEFORE the system headers, which is what we
want.

Then in the application source simply using the following include will
pick up both /pathto/include/dfp/<foo>.h and /usr/include/<foo>.h:

	#include <math.h>
	#include <fenv.h>
	#include <stdlib.h>
	#include <wchar.h>

	/* And for C++ programs */
	#include <float.h>
	#include <decimal/decimal>

Due to the use of #include_next in the DFP headers (in order to wrap the
default system headers with DFP prototypes) the methodology of including
"dfp/" in the include path, and then excluding -I/pathto/include/dfp/ is
NOT supported.

DO NOT DO THE FOLLOWING:

	#include <dfp/math.h>
	#include <dfp/fenv.h>
	#include <dfp/stdlib.h>
	#include <dfp/wchar.h>
	#include <dfp/float.h>
	#include <dfp/decimal/decimal>

---------------------------------------------------------------------------
7.  Compile and Link

A compilation and link for a DFP program will look like the following:

	$(CC) -Wall test_dfp.c -o test_dfp -D__STDC_WANT_DEC_FP__ \
	-std=gnu99 -ldfp

---------------------------------------------------------------------------
8.  Unsupported/Non-Standard Additions

Libdfp provides a non-standard method for output of the decoded Densely
Packed Decimal representation using the decoded[32|64|128]() functions.  The
output format is:

	[sign][MSD],[decoded-declet-1],
	...,[decoded-declet-n][E][+|-][decoded exponent]

Examples:

  +0,000,000E+0 = decoded32(0DF)
  +0,000,000,000,001,000E-1 = decoded64(100.0DD)
  -0,000,000,000,000,000,000,000,000,039,654,003E-3 = decoded128(-39654.003DL)
  +9,876,543E+22 = decoded32(9.876543E+28DF)

WARNING:  Do NOT rely on these methods for user space code.  They're only
provided for toolchain development debug support.

A header file providing the prototype for these functions is not provided by
the Advance Toolchain to discourage you from using them.  If you MUST use them
define the following prototypes in your program:

	/* char * should ref a 14 byte char array,
	 * +0,000,000E+0\0  */
	extern char * decoded32 (_Decimal32, char*);

	/* char * should ref a 26 byte char array,
	 * +0,000,000,000,000,000E+0\0  */
	extern char * decoded64 (_Decimal64, char*);

	/* char * should ref a 50 byte char array,
	 * +0,000,000,000,000,000,000,000,000,000,000,000E+0\0  */
	extern char * decoded128 (_Decimal128, char*);

---------------------------------------------------------------------------
9. Known Limitations

IEEE754r currently has an addendum awaiting vote whereby the default quantum
for conversions involving zero will go to a zero exponent (e.g.  0 equals
0.0).  The current IEEE754r specification dictates that the quantum shall go
to the largest supported by the data type, e.g.  _Decimal32 0.0E191;
_Decimal64 0.0E767, _Decimal128 0.0E12287.

Observation of the advance toolchain results will show that we don't follow
any particular convention.  This may change in the future.

For the following examples notice the DPD encoding on both power6[x] and
non-power6:

	_Decimal32 d32 = 0.0DF;
	_Decimal64 d64 = 0.0DD;
	_Decimal128 d128 = 0.0DL;
	
	(_Decimal128)0.0DF: [+0,000,000E+0]
	(_Decimal128)0.0DD: [+0,000,000,000,000,000E+0]
	(_Decimal128)0.0DL: [+0,000,000,000,000,000,000,000,000,000,000,000E+0]

On power6[x] notice the representation of zero after an [int|long|long long]
conversion to _Decimal[32|64|128] respectively:

	(_Decimal32)0DF = (int)0: [+0,000,000E+0]
	(_Decimal32)0.0DF = (float)0.000000: [+0,000,000E+0]
	(_Decimal64)0DD = (long)0: [+0,000,000,000,000,000E+0]
	(_Decimal64)0.0DD = (double)0.000000: [+0,000,000,000,000,000E+0]
	(_Decimal128)0DL = (long long)0:
	  [+0,000,000,000,000,000,000,000,000,000,000,000E+0]
	(_Decimal128)0.0DL = (long double)0.000000:
	  [+0,000,000,000,000,000,000,000,000,000,000,000E+0]

Notice the difference with soft-dfp:

	(_Decimal32)0.0DF = (int)0: [+0,000,000E-1]
	(_Decimal32)0.0DF = (float)0.000000: [+0,000,000E+0]
	(_Decimal64)0.0DD = (long)0: [+0,000,000,000,000,000E-1]
	(_Decimal64)0.0DD = (double)0.000000: [+0,000,000,000,000,000E+0]
	(_Decimal128)0.0DL = (long long)0:
	  [+0,000,000,000,000,000,000,000,000,000,000,000E-1]
	(_Decimal128)0.0DL = (long double)0.000000:
	  [+0,000,000,000,000,000,000,000,000,000,000,000E+0]

Namely the negative sign of the exponent with soft-dfp for int to _Decimal
conversions.
