<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
<head>
  <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
  <title>Decimal Types for C++: Third Draft</title>
</head>

<body>
<pre>
                                                  Doc No:   SC22/WG21/N1965
                                                            J16/06-0035
                                                  Date:     2006-02-25
                                                  Project:  JTC1.22.32
                                                  Reply to: Robert Klarer
                                                            IBM Canada, Ltd.
                                                            klarer@ca.ibm.com
</pre>

<h1>
Decimal Types for C++: Draft 3
</h1>

<h1>
0 About this document
</h1>
<p>
[<i>Editor's note:</i> this document is being proposed (by me) as a basis for continuing work.  None of the design choices implied in this work is final.  Better ideas, as well as comments and critiques will be gratefully received.]
</p>
<p>
This document is known to be incomplet, inkorrect, and badly forma<sup>tt</sup>ed.
</p>
<h1>
1 Introduction 
</h1>
<p>
Most of today's general purpose computing architectures provide binary floating-point arithmetic in hardware.  Binary float-point is an efficient representation that minimizes memory use, and is simpler to implement than floating-point arithmetic using other bases.  It has therefore become the norm for scientific computations, with almost all implementations following the IEEE-754 standard for binary floating-point arithmetic.
</p>
<p>
However, human computation and communication of numeric values almost always uses decimal arithmetic, and decimal notations.  Laboratory notes, scientific papers, legal documents, business reports and financial statements all record numeric values in decimal form.  When numeric data are given to a program or are displayed to a user, binary to-and-from decimal conversion is required.  There are inherent rounding errors involved in such conversions; decimal fractions cannot, in general, be represented exactly by floating-point values.  These errors often cause usability and efficiency problems, depending on the application.
</p>
<p>
These problems are minor when the application domain accepts, or requires results to have, associated error estimates (as is the case with scientific applications).  However, in business and financial applications, computations are either required to be exact (with no rounding errors) unless explicitly rounded, or be supported by detailed analyses that are auditable to be correct.  Such applications therefore have to take special care in handling any rounding errors introduced by the computations.
</p>
<p>
The most efficient way to avoid conversion error is to use decimal arithmetic.  Recognizing this, the IEEE-754R Standard for Floating-Point Arithmetic specifies decimal floating-point encodings and arithmetic.  This technical report specifies extensions to the International Standard for the C++ programming language to permit the use of decimal arithmetic in a manner consistent with the IEEE-754R standard.
</p>
<h2>
1.1 Arithmetic model
</h2>
<p>
This Technical Report is based on a model of decimal arithmetic which is a formalization of the decimal system of numeration (Algorism) as further defined and constrained by the relevant standards,
IEEE-854, ANSI X3-274, and IEEE-754R.
</p>
<p>
There are three components to the model:
</p>
<ul>
<li>
<i>numbers</i> - which represent the values which can be manipulated by, or be the results of, the core operations defined in the model
</li>
<li>
<i>operations</i> - the core operations (such as addition, multiplication, etc.) which can be carried out on numbers
</li>
<li>
<i>context</i> - which represents the user-selectable parameters and rules which govern the results of arithmetic operations (for example, the rounding mode to be used)
</li>
</ul>
<p>
The model defines these components in the abstract. It defines neither the way in which operations are expressed (which might vary depending on the computer language or other interface being used), nor the concrete representation (specific layout in storage, or in a processor's register, for example) of numbers or context.
</p>
<p>
From the perspective of the C++ language, <i>numbers</i> are represented by data types, <i>operations</i> are defined within expressions, and <i>context</i>
is the floating environment specified in <code>&lt;cfenv&gt;</code> and <code>&lt;fenv.h&gt;</code>. This Technical Report
specifies how the C++ language implements these components.
</p>
<p>
Note: A description of the arithmetic model can be found in
http://www2.hursley.ibm.com/decimal/decarith.html.
</p>
<h2>
1.2 Encodings
</h2>
<p>
In the C++ International Standard, the representation of a floating-point number is specified in an abstract form where the constituent components of the representation are defined (sign, exponent, significand) but the internals of these components are not.   In particular, the exponent range, significand size and the base (or radix), are implementation defined. This allows flexibility for an implementation to take advantage of its underlying hardware architecture. Furthermore, certain behaviors of operations are also implementation defined, for example in the area of handling of special numbers and in exceptions.
</p>
<p>
This approach was inherited from the C programming language.  At the time that C was first standardized, there were already various hardware implementations of floating-point arithmetic in common use. Specifying the exact details of a representation would make most of the existing C implementations at the time not conforming.
</p>
<p>
The C99 standard specifies a binding to IEEE-754 (annex F).  Still, conformance to IEEE-754 is not a mandatory requirement.  A C99 implementation that conforms to IEEE-754 defines the macro __STDC_IEC_559__.
</p>
<p>
This Technical Report specifies decimal floating-point arithmetic according to the IEEE-754R standard, with the constituent components of the representation defined. This is more stringent than the approach taken for the floating point types in the C++ standard.  Since it is expected that all decimal floating-point hardware implementations will conform to the IEEE-754R standard, binding to this standard directly benefits both implementers and programmers.
</p>
<h2>
1.3 References
</h2>
<p>
The following standards contain provisions which, through reference in this text, constitute provisions of this Technical Report.  For dated references, subsequent amendment to, or revisions of, any of these publications do not apply.  However, parties to agreements based on this Technical Report are encouraged to investigate the possibility of applying the most recent editions of the normative documents indicated below.  For undated references, the latest edition of the normative document referred applies.  Members of the IEC and ISO maintain registers of current valid International Standards.
</p>
<p>
1.3.1 ISO/IEC 14882:2003, <em>Information technology -- Programming languages, their environments and system software interfaces -- Programming Language C++</em>.
</p>
<p>
1.3.2 ISO/IEC TR 19768:2005, <em>Information technology -- Programming languages, their environments and system software interfaces -- Technical Report on C++ Library Extensions</em>.
</p>
<p>
1.3.3 ANSI/IEEE 754R - <em>IEEE Standard for Floating-Point Arithmetic.  The Institute of Electrical and Electronic Engineers, Inc.</em>.
</p>
<p>
1.3.4 ANSI/IEEE 854-1997 - <em>IEEE Standard for Radix-Independent Floating-Point Arithmetic.  The Institute of Electrical and Electronic Engineers, Inc., New York,</em> 1987.
</p>
<h1>
2 Conventions
</h1>
<p>
This technical report is non-normative; the extensions that it describes may be considered for inclusion in a future revision of the International Standard for C++, but they are not currently required for conformance to that standard.  Furthermore, it is conceivable that a future revision of the International Standard will include facilities that are similar and not identical to the extensions described in this report,
</p>
<p>
Although this report describes extensions to the <em>C++ standard library</em>, vendors may choose to implement these extensions in the C++ language translator itself.  This practice is permitted so long as all well-formed programs are accepted by the implementation, and the semantics of those programs are the same as they would be had the extensions taken the form of a library.
[<em>Note:</em> The same practice is permitted with respect to the implementation of the C++ standard library. <em>--end note</em>]
</p>
<p>
The result of deriving a user-defined type from <code>std::dfp::decimal32</code>, <code>std::dfp::decimal64</code>, or <code>std::dfp::decimal128</code> is undefined.
</p>
<h2>
2.1 Relation to C++ Standard Library Introduction
</h2>
<p>
Unless otherwise specified, the whole of the ISO C++ Standard Library introduction [lib.library] is included into this Technical Report by reference.
</p>
<p>
This Technical Report introduces the following elements to supplement those described in [lib.structure.specifications]:
</p>
<ul>
<li>
<b>Constraints:</b> constraints on template arguments; these are enforced by the implementation
</li>
<li>
<b>Expansion:</b> the semantics of a macro's expansion text
</li>
</ul>
<h2>
2.2 Relation to "Technical Report on C++ Library Extensions"
</h2>
<p>
Unless otherwise specified, the following sections of ISO/IEC Technical Report 19768: "Technical Report on C++ Library Extensions" are included into this Technical Report by reference:
</p>
<ul>
<li>General [tr.intro]</li>
<li>Metaprogramming and type traits [tr.meta]</li>
<li>Additions to header <code>&lt;functional&gt;</code> synopsis [tr.unord.fun.syn]</li>
<li>Class template <code>hash</code> [tr.unord.hash]</li>
<li>C compatibility [tr.c99]</li>
</ul>
<h2>
2.3 Categories of extensions
</h2>
<p>
This technical report describes 4 categories of library extensions:
</p>
<ol>
<li>
New library components (types and functions) that are declared entirely in new headers, such as the type <code>dfp::decimal32</code> in the <code>&lt;dec32></code> header.
</li>
<li>
New library components declared as additions to existing standard headers, such as the functions added to the headers <code>&lt;cmath></code> and <code>&lt;math.h></code> in clause 3.7.
</li>
<li>
New library components declared as additions to TR1 headers, such as the template <code>is_decimal_floating_point</code> added to the header <code>&lt;type_traits></code> in clause 3.12.
</li>
<li>
Additions to standard library components, such as the specializations of <code>std::numeric_limits</code> in clauses 3.2.16, 3.3.16, and 3.4.16.
</li>
</ol>
<p>
New headers are distinguished from extensions to existing headers by the title of the <i>synopsis</i> clause.  In the first case the title is of the form "Header <code>&lt;foo></code> synopsis," and the synopsis includes all namespace scope declarations contained in the header.  In the second case the title is of the form "Additions to header <code>&lt;foo></code> synopsis" and the synopsis includes only the extensions, <i>i.e.</i> those namespace scope declarations that are not present in the C++ standard or TR1.
</p>
<h2>
2.4 Namespaces and headers
</h2>
<p>
The extensions described in this technical report are declared within the namespace <code>dfp</code>, which is nested inside the namespace <code>std</code>.
</p>
<p>
Unless otherwise specified, references to other entities described in this technical report are assumed to be qualified with <code>std::dfp::</code>, references to entities described in the C++ standard library are assumed to be qualified with <code>std::</code>, and references to entities described in TR1 are assumed to be qualified with <code>std::tr1::</code>.
</p>
<p>
Even when an extension is specified as additions to standard headers (the second and third categories in section 2.3), vendors should not simply add declarations to standard headers in a way that would be visible to users by default [<em>Note:</em> That would fail to be standard conforming, because the new names, even within a namespace, could conflict with user macros. <em>--end note</em>]  Users should be required to take explicit action to have access to library extensions.
It is recommended either that additional declarations in standard headers be protected with a macro that is not defined by default, or else that all extended headers, including both new headers and parallel versions of standard headers with nonstandard declarations, be placed in a separate directory that is not part of the default search path.
</p>
<h1>
3 Decimal floating-point types
</h1>
<p>
This Technical Report introduces three <i>decimal floating-point types</i>, named decimal32, decimal64, and decimal128.  The set of values of type decimal32 is a subset of the set of values of type decimal64; the set of values of the type decimal64 is a subset of the set of values of the type decimal128.  Support for decimal128 is optional.
</p>
<h2>
3.1 Decimal type encodings 
</h2>
<p>
The three decimal encoding formats defined in IEEE-754R correspond to the three decimal floating types as follows:
</p>
<ul>
<li>
decimal32 is a <em>decimal32</em> number, which is encoded in four consecutive bytes (32 bits)
</li>
<li>
decimal64 is a <em>decimal64</em> number, which is encoded in eight consecutive bytes (64 bits)
</li>
<li>
decimal128 is a <em>decimal128</em> number, which is encoded in 16 consecutive bytes (128 bits)
</li>
</ul>
<p>
[<i>Note:</i> this implies that <code>sizeof(std::dfp::decimal32) == 4</code>, <code>sizeof(std::dfp::decimal64) == 8</code>, and <code>sizeof(std::dfp::decimal128) == 16</code>.  <i>--end note</i>]
</p>
<p>
The finite numbers are defined by a sign, an exponent, (which is a power of ten), and a decimal integer coefficient.  The value of a finite number is given by (1)<sup>sign</sup> x coefficient x 10<sup>exponent</sup>.  Refer to IEEE-754R for details of the format.
</p>
<p>
These formats are characterized by the length of the coefficient, and the maximum and minimum exponent.  Table 1 shows these characteristics by format.
</p>
<h4>Table 1 -- Format Characteristics</h4>
<table border="1">
  <tbody>
    <tr>
      <td>Format</td>
      <td><b>decimal32</b></td>
      <td><b>decimal64</b></td>
      <td><b>decimal128</b></td>

    </tr>
    <tr>
      <td>Coefficient length in digits</td>
      <td>7</td>
      <td>16</td>
      <td>34</td>
    </tr>

    <tr>
      <td>Maximum Exponent (E<sub>max</sub>)</td>
      <td>96</td>
      <td>384</td>
      <td>6144</td>
    </tr>

    <tr>
      <td>Minimum Exponent (E<sub>min</sub>)</td>
      <td>-95</td>
      <td>-383</td>
      <td>-6143</td>
    </tr>
  </tbody>
</table>
<h2>
3.2 32-bit Decimal type
</h2>
<h3>
3.2.1 Header <code>&lt;dec32></code> synopsis
</h3>
<pre>
      #include &lt;iosfwd>

      namespace std {
      namespace dfp {
        class decimal32;

        // <i>3.2.9 initialization from coefficient and exponent:</i>
        decimal32 make_decimal32(long long <i>coeff</i>, int <i>exponent</i>);
        decimal32 make_decimal32(unsigned long long <i>coeff</i>, int <i>exponent</i>);

        // <i>3.2.10 conversion to generic floating-point type:</i>
        long double decimal32_to_long_double(decimal32 <i>d</i>);
        long double decimal_to_long_double(decimal32 <i>d)</i>;

        // <i>3.2.11 unary arithmetic operators:</i>
        decimal32 operator+(const decimal32 &amp; <i>lhs</i>);
        decimal32 operator-(const decimal32 &amp; <i>lhs</i>);

        // <i>3.2.12 binary arithmetic operators:</i>
        template &lt;class LHS>
        <b>implementation-defined</b> operator+(const LHS &amp; <i>lhs</i>, const decimal32 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator+(const decimal32 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        template &lt;class LHS>
        <b>implementation-defined</b> operator-(const LHS &amp; <i>lhs</i>, const decimal32 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator-(const decimal32 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        template &lt;class LHS>
        <b>implementation-defined</b> operator*(const LHS &amp; <i>lhs</i>, const decimal32 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator*(const decimal32 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        template &lt;class LHS>
        <b>implementation-defined</b> operator/(const LHS &amp; <i>lhs</i>, const decimal32 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator/(const decimal32 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        // <i>3.2.13 comparison operators:</i>
        template &lt;class LHS>
        <b>implementation-defined</b> operator==(const LHS &amp; <i>lhs</i>, const decimal32 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator==(const decimal32 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        template &lt;class LHS>
        <b>implementation-defined</b> operator!=(const LHS &amp; <i>lhs</i>, const decimal32 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator!=(const decimal32 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        template &lt;class LHS>
        <b>implementation-defined</b> operator&lt;(const LHS &amp; <i>lhs</i>, const decimal32 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator&lt;(const decimal32 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        template &lt;class LHS>
        <b>implementation-defined</b> operator&lt;=(const LHS &amp; <i>lhs</i>, const decimal32 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator&lt;=(const decimal32 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        template &lt;class LHS>
        <b>implementation-defined</b> operator>(const LHS &amp; <i>lhs</i>, const decimal32 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator>(const decimal32 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        template &lt;class LHS>
        <b>implementation-defined</b> operator>=(const LHS &amp; <i>lhs</i>, const decimal32 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator>=(const decimal32 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        // <i>3.2.14 Formatted input:</i>
        template &lt;class charT, class traits>
          std::basic_istream&lt;charT, traits> &amp;
            operator>>(std::basic_istream&lt;charT, traits> &amp; <i>is</i>, const decimal32 &amp; <i>d</i>);

        // <i>3.2.15 Formatted output:</i>
        template &lt;class charT, class traits>
          std::basic_ostream&lt;charT, traits> &amp;
            operator&lt;&lt;(std::basic_ostream&lt;charT, traits> &amp; <i>os</i>, const decimal32 &amp; <i>d</i>);
      }
      }

</pre>
<h3>
3.2.2 Class <code>decimal32</code>
</h3>
<pre>
      namespace std {
      namespace dfp {
        class decimal32 {
          public:
            // <i>3.2.3 construct/copy/destroy:</i>
            decimal32();
            decimal32(const decimal32 &amp; <i>d32</i>);
            decimal32 &amp; operator=(const decimal32 &amp; <i>d32</i>);
            ~decimal32();

            // <i>3.2.4 conversion from floating-point type:</i>
            explicit decimal32(const decimal64 &amp; <i>d64</i>);
            explicit decimal32(const decimal128 &amp; <i>d128</i>);
            explicit decimal32(float <i>r</i>);
            explicit decimal32(double <i>r</i>);
            explicit decimal32(long double <i>r</i>);

            // <i>3.2.5 conversion from integral type:</i>
            decimal32(int <i>z</i>);
            decimal32(unsigned int <i>z</i>);
            decimal32(long <i>z</i>);
            decimal32(unsigned long <i>z</i>);
            decimal32(long long <i>z</i>);
            decimal32(unsigned long long <i>z</i>);

            // <i>3.2.6 conversion to integral type:</i>
            operator long long() const;

            // <i>3.2.7 increment and decrement operators:</i>
            decimal32 &amp; operator++();
            decimal32   operator++(int);
            decimal32 &amp; operator--();
            decimal32   operator--(int);

            // <i>3.2.8 compound assignment:</i>
            template &lt;class T>
            <b>implementation-defined</b> operator+=(const T &amp; <i>rhs</i>);

            template &lt;class T>
            <b>implementation-defined</b> operator-=(const T &amp; <i>rhs</i>);

            template &lt;class T>
            <b>implementation-defined</b> operator*=(const T &amp; <i>rhs</i>);

            template &lt;class T>
            <b>implementation-defined</b> operator/=(const T &amp; <i>rhs</i>);
        };
      }
      }
</pre>
<h3>
3.2.3 Construct/copy/destroy
</h3>
<pre>
        decimal32();
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an object of type decimal32 with the value 0;
</p>
</blockquote>
<pre>
        decimal32(const decimal32 &amp; <i>d32</i>);
        decimal32 &amp; operator=(const decimal32 &amp; <i>d32</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b> Copies an object of type decimal32.
</p>
</blockquote>
<pre>
        ~decimal32();
</pre>
<blockquote>
<p>
<b>Effects:</b> Destroys an object of type decimal32.
</p>
</blockquote>
<h3>
3.2.4 Conversion from floating-point type
</h3>
<pre>
        explicit decimal32(const decimal64 &amp; <i>d64</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an object of type decimal32 by converting from type decimal64.  Conversion is performed as in IEEE-754R.
</p>
</blockquote>
<pre>
        explicit decimal32(const decimal128 &amp; <i>d128</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an object of type decimal32 by converting from type decimal128.  Conversion is performed as in IEEE-754R.
</p>
</blockquote>
<pre>
        explicit decimal32(float <i>r</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an object of type decimal32 by converting from type <code>float</code>.  If <code>std::numeric_limits&lt;float>::is_iec559 == true</code> then the conversion is performed as in IEEE-754R.  Otherwise, the result of the conversion is implementation-defined.
</p>
</blockquote>
<pre>
        explicit decimal32(double <i>r</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an object of type decimal32 by converting from type <code>double</code>.  If <code>std::numeric_limits&lt;double>::is_iec559 == true</code> then the conversion is performed as in IEEE-754R.  Otherwise, the result of the conversion is implementation-defined.
</p>
</blockquote>
<pre>
        explicit decimal32(long double <i>r</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an object of type decimal32 by converting from type <code>long double</code>.  If <code>std::numeric_limits&lt;long double>::is_iec559 == true</code> then the conversion is performed as in IEEE-754R.  Otherwise, the result of the conversion is implementation-defined.
</p>
</blockquote>
<h3>
3.2.5 Conversion from integral type
</h3>
<pre>
        decimal32(int <i>z</i>);
        decimal32(unsigned int <i>z</i>);
        decimal32(long <i>z</i>);
        decimal32(unsigned long <i>z</i>);
        decimal32(long long <i>z</i>);
        decimal32(unsigned long long <i>z</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an object of type decimal32 by converting from the type of <i>z</i>.  Conversion is performed as in IEEE-754R.
</p>
</blockquote>
<h3>
3.2.6 Conversion to integral type
</h3>
<pre>
        operator long long() const;
</pre>
<blockquote>
<p>
<b>Returns:</b> Returns the result of the conversion of <code>*this</code> to the type <code>long long</code>, as if performed by the expression <code>llroundd32(*this)</code>.
</p>
</blockquote>
<h3>
3.2.7 Increment and decrement operators
</h3>
<pre>
        decimal32 &amp; operator++();
</pre>
<blockquote>
<p>
<b>Effects: </b>Adds 1 to <code>*this</code>, as in IEEE-754R, and assigns the result to <code>*this</code>.
<br/>
<b>Returns: </b><code>*this</code>
</p>
</blockquote>
<pre>
        decimal32   operator++(int);
</pre>
<blockquote>
<p>
<b>Effects:</b>
</p>
<pre>
        decimal32 tmp = *this;
        *this += 1;
        return tmp; 
</pre>
</blockquote>
<pre>
        decimal32 &amp; operator--();
</pre>
<blockquote>
<p>
<b>Effects: </b>Subtracts 1 from <code>*this</code>, as in IEEE-754R, and assigns the result to <code>*this</code>.
<br/>
<b>Returns: </b><code>*this</code>
</p>
</blockquote>
<pre>
        decimal32   operator--(int);
</pre>
<blockquote>
<p>
<b>Effects:</b>
</p>
<pre>
        decimal32 tmp = *this;
        *this -= 1;
        return tmp; 
</pre>
</blockquote>
<h3>
3.2.8 Compound assignment
</h3>
<pre>
        template &lt;class T>
        <b>implementation-defined</b> operator+=(const T &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>T</code> is one of the integral types, or one of the decimal floating-point types.
<br/>
<b>Effects:</b> Adds <i>rhs</i> to <code>*this</code>, as in IEEE-754R, and assigns the result to <code>*this</code>.
<br/>
<b>Returns:</b> <code>*this</code> 
</p>
</blockquote>

<pre>
        template &lt;class T>
        <b>implementation-defined</b> operator-=(const T &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>T</code> is one of the integral types, or one of the decimal floating-point types.
<br/>
<b>Effects:</b> Subtracts <i>rhs</i> from <code>*this</code>, as in IEEE-754R, and assigns the result to <code>*this</code>.
<br/>
<b>Returns:</b> <code>*this</code> 
</p>
</blockquote>

<pre>
        template &lt;class T>
        <b>implementation-defined</b> operator*=(const T &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>T</code> is one of the integral types, or one of the decimal floating-point types.
<br/>
<b>Effects:</b> Multiplies <code>*this</code> by <i>rhs</i>, as in IEEE-754R, and assigns the result to <code>*this</code>.
<br/>
<b>Returns:</b> <code>*this</code> 
</p>
</blockquote>

<pre>
        template &lt;class T>
        <b>implementation-defined</b> operator/=(const T &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>T</code> is one of the integral types, or one of the decimal floating-point types.
<br/>
<b>Effects:</b> Divides <code>*this</code> by <i>rhs</i>, as in IEEE-754R, and assigns the result to <code>*this</code>.
<br/>
<b>Returns:</b> <code>*this</code> 
</p>
</blockquote>

<h3>
3.2.9 Initialization from coefficient and exponent
</h3>
<pre>
        decimal32 make_decimal32(long long <i>coeff</i>, int <i>exponent</i>);
        decimal32 make_decimal32(unsigned long long <i>coeff</i>, int <i>exponent</i>);
</pre>
<blockquote>
<p>
<b>Returns:</b> <code>powd32(coeff, exponent)</code>
</p>
</blockquote>

<h3>
3.2.10 Conversion to generic floating-point type
</h3>
<pre>
        long double decimal32_to_long_double(decimal32 <i>d</i>);
        long double decimal_to_long_double(decimal32 <i>d</i>);
</pre>
<blockquote>
<p>
<b>Returns:</b> If <code>std::numeric_limits&lt;long double>::is_iec559 == true</code>, returns the result of the conversion of <code>*this</code> to <code>long double</code>, performed as in IEEE-754R.  Otherwise, the returned value is implementation-defined.
</p>
</blockquote>
<p>
[<i>Editor's note:</i> this notation is ugly.  A user-defined converson operator would be vastly preferable to these functions but, alas, user-defined conversion operators cannot be <code>explicit</code>.  A previous draft of this document specified a <code>decimal32</code> member function named <code>to_long_double()</code> that had the same result as these functions.  The current "free function" approach is better because it works regardless of whether the implementation of these types uses library classes or compiler builtins.  The <code>decimal32_to_long_double</code> form is provided for C programmers who want to write code that works equally well in C++.]
</p>

<h3>
3.2.11 Unary arithmetic operators
</h3>
<pre>
        decimal32 operator+(const decimal32 &amp; <i>lhs</i>);
</pre>
<blockquote>
<p>
<b>Returns:</b> Adds <i>lhs</i> to <code>0</code>, as in IEEE-754R, and returns the result.
</p>
</blockquote>
<pre>
        decimal32 operator-(const decimal32 &amp; <i>lhs</i>);
</pre>
<blockquote>
<p>
<b>Returns:</b> Subtracts <i>lhs</i> from <code>0</code>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<h3>
3.2.12 Binary arithmetic operators
</h3>
<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator+(const LHS &amp; <i>lhs</i>, const decimal32 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> Adds <i>rhs</i> to <i>lhs</i>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator+(const decimal32 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> Adds <i>rhs</i> to <i>lhs</i>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator-(const LHS &amp; <i>lhs</i>, const decimal32 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> Subtracts <i>rhs</i> to <i>lhs</i>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator-(const decimal32 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> Subtracts <i>rhs</i> from <i>lhs</i>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator*(const LHS &amp; <i>lhs</i>, const decimal32 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> Multiplies <i>lhs</i> by <i>rhs</i>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator*(const decimal32 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> Multiplies <i>lhs</i> by <i>rhs</i>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator/(const LHS &amp; <i>lhs</i>, const decimal32 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> Divides <i>lhs</i> by <i>rhs</i>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator/(const decimal32 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> Divides <i>lhs</i> by <i>rhs</i>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<h3>
3.2.13 Comparison operators
</h3>
<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator==(const LHS &amp; <i>lhs</i>, const decimal32 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is exactly equal to <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator==(const decimal32 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is exactly equal to <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator!=(const LHS &amp; <i>lhs</i>, const decimal32 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is not exactly equal to <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator!=(const decimal32 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is not exactly equal to <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator&lt;(const LHS &amp; <i>lhs</i>, const decimal32 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is less than <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator&lt;(const decimal32 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is less than <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator&lt;=(const LHS &amp; <i>lhs</i>, const decimal32 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is less than or equal to <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator&lt;=(const decimal32 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is less than or equal to <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator>(const LHS &amp; <i>lhs</i>, const decimal32 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is greater than <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator>(const decimal32 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is greater than <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator>=(const LHS &amp; <i>lhs</i>, const decimal32 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is greater than or equal to <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator>=(const decimal32 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is greater than or equal to <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<h3>
3.2.14 Formatted input
</h3>
<pre>
        template &lt;class charT, class traits>
          std::basic_istream&lt;charT, traits> &amp;
            operator>>(std::basic_istream&lt;charT, traits> &amp; <i>is</i>, const decimal32 &amp; <i>d</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b>
This function constructs an object of class <code>std::basic_istream&lt;charT, traits>::sentry</code>.  If the <code>sentry</code> object returns <code>true</code> when converted to a value of type bool, input is extracted as if by the following code fragment:
</p>
<pre>
    typedef extended_num_get&lt;charT, std::istreambuf_iterator&lt;charT, traits> > extnumget;
    std::ios_base::iostate err = 0;
    std::use_facet&lt;extnumget>(is.getloc()).get(*this, 0, *this, err, d);
    setstate(err);
</pre>
<p>
If an exception is thrown during input then <code>std::ios::badbit</code> is set in the error state of the input stream <i>is</i>.  If <code>(<i>is</i>.exceptions() &amp; std::ios_base::badbit) != 0</code> then the exception is rethrown.  In any case, the formatted input function destroys the <code>sentry</code> object.
</p>
<p>
<b>Returns:</b> <i>is</i>.
</p>
</blockquote>
<h3>
3.2.15 Formatted output
</h3>
<pre>
        template &lt;class charT, class traits>
          std::basic_ostream&lt;charT, traits> &amp;
            operator&lt;&lt;(std::basic_ostream&lt;charT, traits> &amp; <i>os</i>, const decimal32 &amp; <i>d</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b>
This function constructs an object of class <code>std::basic_ostream&lt;charT, traits>::sentry</code>.  If the <code>sentry</code> object returns <code>true</code> when converted to a value of type bool, output is generated as if by the following code fragment:

</p>
<pre>
    typedef extended_num_put&lt;charT, std::ostreambuf_iterator&lt;charT, traits> > extnumput;
    bool failed =
      std::use_facet&lt;extnumput>(os.getloc()).put(*this, *this, os.fill(), d).failed();
    if (failed)
      { os.setstate(std::ios_base::failbit); }
</pre>
<p>
If an exception is thrown during output then <code>std::ios::badbit</code> is set in the error state of the input stream <i>os</i>.  If <code>(<i>os</i>.exceptions() &amp; std::ios_base::badbit) != 0</code> then the exception is rethrown.  In any case, the formatted output function destroys the <code>sentry</code> object.
</p>
<p>
<b>Returns:</b> <i>os</i>.
</p>
</blockquote>
<h3>
3.2.16 Addition to header <code>&lt;limits></code>
</h3>
<p>
The standard template <code>std::numeric_limits</code> shall be specialized for the <code>decimal32</code> type.
</p>
<p>
[<i>Example:</i>
</p>
<pre>
      namespace std {
        template&lt;> class numeric_limits&lt;dfp::decimal32> {
          public:
            static const bool is_specialized = true;

            static dfp::decimal32 min() throw() { return DEC32_MIN; }
            static dfp::decimal32 max() throw() { return DEC32_MAX; }

            static const int digits       = 7;
            static const int digits10     = digits; 
            static const int max_digits10 = digits; 

            static const bool is_signed  = true;
            static const bool is_integer = false;
            static const bool is_exact   = false;

            static const int radix = 10;
            static dfp::decimal32 epsilon()     throw() { return DEC32_EPSILON; }
            static dfp::decimal32 round_error() throw() { return ...; }

            static const int min_exponent   = -95;
            static const int min_exponent10 = min_exponent;
            static const int max_exponent   = 96;
            static const int max_exponent10 = max_exponent; 

            static const bool has_infinity             = true;
            static const bool has_quiet_NaN            = true;
            static const bool has_signaling_NaN        = true;
            static const float_denorm_style has_denorm = denorm_present;
            static const bool has_denorm_loss          = true;

            static dfp::decimal32 infinity()      throw() { return ...; }
            static dfp::decimal32 quiet_NaN()     throw() { return ...; }
            static dfp::decimal32 signaling_NaN() throw() { return ...; }
            static dfp::decimal32 denorm_min()    throw() { return DEC32_DEN; }

            static const bool is_iec559       = false;
            static const bool is_bounded      = true;
            static const bool is_modulo       = false;
            static const bool traps           = true;
            static const bool tinyness_before = true;

            static const float_round_style round_style = round_indeterminate;
        };
      }
</pre>
<p>
--<i>end example</i>]
</p>
<h2>
3.3 64-bit Decimal type
</h2>
<h3>
3.3.1 Header <code>&lt;dec64></code> synopsis
</h3>
<pre>
      #include &lt;iosfwd>

      namespace std {
      namespace dfp {
        class decimal64;

        // <i>3.3.9 initialization from coefficient and exponent:</i>
        decimal64 make_decimal64(long long <i>coeff</i>, int <i>exponent</i>);
        decimal64 make_decimal64(unsigned long long <i>coeff</i>, int <i>exponent</i>);

        // <i>3.3.10 conversion to generic floating-point type:</i>
        long double decimal64_to_long_double(decimal64 <i>d</i>);
        long double decimal_to_long_double(decimal64 <i>d</i>);

        // <i>3.3.11 unary arithmetic operators:</i>
        decimal64 operator+(const decimal64 &amp; <i>lhs</i>);
        decimal64 operator-(const decimal64 &amp; <i>lhs</i>);

        // <i>3.3.12 binary arithmetic operators:</i>
        template &lt;class LHS>
        <b>implementation-defined</b> operator+(const LHS &amp; <i>lhs</i>, const decimal64 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator+(const decimal64 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        template &lt;class LHS>
        <b>implementation-defined</b> operator-(const LHS &amp; <i>lhs</i>, const decimal64 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator-(const decimal64 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        template &lt;class LHS>
        <b>implementation-defined</b> operator*(const LHS &amp; <i>lhs</i>, const decimal64 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator*(const decimal64 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        template &lt;class LHS>
        <b>implementation-defined</b> operator/(const LHS &amp; <i>lhs</i>, const decimal64 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator/(const decimal64 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        // <i>3.3.13 comparison operators:</i>
        template &lt;class LHS>
        <b>implementation-defined</b> operator==(const LHS &amp; <i>lhs</i>, const decimal64 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator==(const decimal64 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        template &lt;class LHS>
        <b>implementation-defined</b> operator!=(const LHS &amp; <i>lhs</i>, const decimal64 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator!=(const decimal64 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        template &lt;class LHS>
        <b>implementation-defined</b> operator&lt;(const LHS &amp; <i>lhs</i>, const decimal64 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator&lt;(const decimal64 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        template &lt;class LHS>
        <b>implementation-defined</b> operator&lt;=(const LHS &amp; <i>lhs</i>, const decimal64 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator&lt;=(const decimal64 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        template &lt;class LHS>
        <b>implementation-defined</b> operator>(const LHS &amp; <i>lhs</i>, const decimal64 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator>(const decimal64 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        template &lt;class LHS>
        <b>implementation-defined</b> operator>=(const LHS &amp; <i>lhs</i>, const decimal64 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator>=(const decimal64 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        // <i>3.3.14 Formatted input</i>
        template &lt;class charT, class traits>
          std::basic_istream&lt;charT, traits> &amp;
            operator>>(std::basic_istream&lt;charT, traits> &amp; <i>is</i>, const decimal64 &amp; <i>d</i>);

        // <i>3.3.15 Formatted output</i>
        template &lt;class charT, class traits>
          std::basic_ostream&lt;charT, traits> &amp;
            operator&lt;&lt;(std::basic_ostream&lt;charT, traits> &amp; <i>os</i>, const decimal64 &amp; <i>d</i>);
      }
      }

</pre>
<h3>
3.3.2 Class <code>decimal64</code>
</h3>
<pre>
      namespace std {
      namespace dfp {
        class decimal64 {
          public:
            // <i>3.2.3 construct/copy/destroy:</i>
            decimal64();
            decimal64(const decimal64 &amp; <i>d64</i>);
            decimal64 &amp; operator=(const decimal64 &amp; <i>d64</i>);
            ~decimal64();

            // <i>3.3.4 conversion from floating-point type:</i>
            decimal64(const decimal32 &amp; <i>d32</i>);
            explicit decimal64(const decimal128 &amp; <i>d128</i>);
            explicit decimal64(float <i>r</i>);
            explicit decimal64(double <i>r</i>);
            explicit decimal64(long double <i>r</i>);

            // <i>3.3.5 conversion from integral type:</i>
            decimal64(int <i>z</i>);
            decimal64(unsigned int <i>z</i>);
            decimal64(long <i>z</i>);
            decimal64(unsigned long <i>z</i>);
            decimal64(long long <i>z</i>);
            decimal64(unsigned long long <i>z</i>);

            // <i>3.3.6 conversion to integral type:</i>
            operator long long() const;

            // <i>3.3.7 increment and decrement operators:</i>
            decimal64 &amp; operator++();
            decimal64   operator++(int);
            decimal64 &amp; operator--();
            decimal64   operator--(int);

            // <i>3.3.8 compound assignment:</i>
            template &lt;class T>
              <b>implementation-defined</b> operator+=(T <i>rhs</i>);

            template &lt;class T>
              <b>implementation-defined</b> operator-=(T <i>rhs</i>);

            template &lt;class T>
              <b>implementation-defined</b> operator*=(T <i>rhs</i>);

            template &lt;class T>
              <b>implementation-defined</b> operator/=(T <i>rhs</i>);
        };
      }
      }
</pre>
<h3>
3.3.3 Construct/copy/destroy
</h3>
<pre>
        decimal64();
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an object of type decimal64 with the value 0;
</p>
</blockquote>
<pre>
        decimal64(const decimal64 &amp; <i>d64</i>);
        decimal64 &amp; operator=(const decimal64 &amp; <i>d64</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b> Copies an object of type decimal64.
</p>
</blockquote>
<pre>
        ~decimal64();
</pre>
<blockquote>
<p>
<b>Effects:</b> Destroys an object of type decimal64.
</p>
</blockquote>
<h3>
3.3.4 Conversion from floating-point
</h3>
<pre>
        decimal64(const decimal32 &amp; <i>d32</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an object of type decimal64 by converting from type decimal32.  Conversion is performed as in IEEE-754R.
</p>
</blockquote>
<pre>
        explicit decimal64(const decimal128 &amp; <i>d128</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an object of type decimal64 by converting from type decimal128.  Conversion is performed as in IEEE-754R.
</p>
</blockquote>
<pre>
        explicit decimal64(float <i>r</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an object of type decimal64 by converting from type <code>float</code>.  If <code>std::numeric_limits&lt;float>::is_iec559 == true</code> then the conversion is performed as in IEEE-754R.  Otherwise, the result of the conversion is implementation-defined.
</p>
</blockquote>
<pre>
        explicit decimal64(double <i>r</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an object of type decimal64 by converting from type <code>double</code>.  If <code>std::numeric_limits&lt;double>::is_iec559 == true</code> then the conversion is performed as in IEEE-754R.  Otherwise, the result of the conversion is implementation-defined.
</p>
</blockquote>
<pre>
        explicit decimal64(long double <i>r</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an object of type decimal64 by converting from type <code>long double</code>.  If <code>std::numeric_limits&lt;long double>::is_iec559 == true</code> then the conversion is performed as in IEEE-754R.  Otherwise, the result of the conversion is implementation-defined.
</p>
</blockquote>
<h3>
3.3.5 Conversion from integral type
</h3>
<pre>
        decimal64(int <i>z</i>);
        decimal64(unsigned int <i>z</i>);
        decimal64(long <i>z</i>);
        decimal64(unsigned long <i>z</i>);
        decimal64(long long <i>z</i>);
        decimal64(unsigned long long <i>z</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an object of type decimal64 by converting from the type of <i>z</i>.  Conversion is performed as in IEEE-754R.
</p>
</blockquote>

<h3>
3.3.6 Conversion to integral type
</h3>
<pre>
        operator long long() const;
</pre>
<blockquote>
<p>
<b>Returns:</b> Returns the result of the conversion of <code>*this</code> to the type <code>long long</code>, as if performed by the expression <code>llroundd64(*this)</code>.
</p>
</blockquote>

<h3>
3.3.7 Increment and decrement operators
</h3>
<pre>
        decimal64 &amp; operator++();
</pre>
<blockquote>
<p>
<b>Effects: </b>Adds 1 to <code>*this</code>, as in IEEE-754R, and assigns the result to <code>*this</code>.
<br/>
<b>Returns: </b><code>*this</code>
</p>
</blockquote>
<pre>
        decimal64   operator++(int);
</pre>
<blockquote>
<p>
<b>Effects:</b>
</p>
<pre>
        decimal64 tmp = *this;
        *this += 1;
        return tmp; 
</pre>
</blockquote>
<pre>
        decimal64 &amp; operator--();
</pre>
<blockquote>
<p>
<b>Effects: </b>Subtracts 1 from <code>*this</code>, as in IEEE-754R, and assigns the result to <code>*this</code>.
<br/>
<b>Returns: </b><code>*this</code>
</p>
</blockquote>
<pre>
        decimal64   operator--(int);
</pre>
<blockquote>
<p>
<b>Effects:</b>
</p>
<pre>
        decimal64 tmp = *this;
        *this -= 1;
        return tmp; 
</pre>
</blockquote>

<h3>
3.3.8 Compound assignment
</h3>
<pre>
        template &lt;class T>
        <b>implementation-defined</b> operator+=(const T &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>T</code> is one of the integral types, or one of the decimal floating-point types.
<br/>
<b>Effects:</b> Adds <i>rhs</i> to <code>*this</code>, as in IEEE-754R, and assigns the result to <code>*this</code>.
<br/>
<b>Returns:</b> <code>*this</code> 
</p>
</blockquote>

<pre>
        template &lt;class T>
        <b>implementation-defined</b> operator-=(const T &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>T</code> is one of the integral types, or one of the decimal floating-point types.
<br/>
<b>Effects:</b> Subtracts <i>rhs</i> from <code>*this</code>, as in IEEE-754R, and assigns the result to <code>*this</code>.
<br/>
<b>Returns:</b> <code>*this</code> 
</p>
</blockquote>

<pre>
        template &lt;class T>
        <b>implementation-defined</b> operator*=(const T &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>T</code> is one of the integral types, or one of the decimal floating-point types.
<br/>
<b>Effects:</b> Multiplies <code>*this</code> by <i>rhs</i>, as in IEEE-754R, and assigns the result to <code>*this</code>.
<br/>
<b>Returns:</b> <code>*this</code> 
</p>
</blockquote>

<pre>
        template &lt;class T>
        <b>implementation-defined</b> operator/=(const T &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>T</code> is one of the integral types, or one of the decimal floating-point types.
<br/>
<b>Effects:</b> Divides <code>*this</code> by <i>rhs</i>, as in IEEE-754R, and assigns the result to <code>*this</code>.
<br/>
<b>Returns:</b> <code>*this</code> 
</p>
</blockquote>

<h3>
3.3.9 Initialization from coefficient and exponent
</h3>
<pre>
        decimal64 make_decimal64(long long <i>coeff</i>, int <i>exponent</i>);
        decimal64 make_decimal64(unsigned long long <i>coeff</i>, int <i>exponent</i>);
</pre>
<blockquote>
<p>
<b>Returns:</b> <code>powd64(<i>coeff</i>, <i>exponent</i>)</code>
</p>
</blockquote>

<h3>
3.3.10 Conversion to generic floating-point type
</h3>
<pre>
        long double decimal64_to_long_double(decimal64 <i>d</i>);
        long double decimal_to_long_double(decimal64 <i>d</i>);
</pre>
<blockquote>
<p>
<b>Returns:</b> If <code>std::numeric_limits&lt;long double>::is_iec559 == true</code>, returns the result of the conversion of <code>*this</code> to <code>long double</code>, performed as in IEEE-754R.  Otherwise, the returned value is implementation-defined.
</p>
</blockquote>
<p>
[<i>Editor's note:</i> this notation is ugly.  A user-defined converson operator would be vastly preferable to these functions but, alas, user-defined conversion operators cannot be <code>explicit</code>.  A previous draft of this document specified a <code>decimal64</code> member function named <code>to_long_double()</code> that had the same result as these functions.  The current "free function" approach is better because it works regardless of whether the implementation of these types uses library classes or compiler builtins.  The <code>decimal64_to_long_double</code> form is provided for C programmers who want to write code that works equally well in C++.]
</p>
<h3>
3.3.11 Unary arithmetic operators
</h3>
<pre>
        decimal64 operator+(const decimal64 &amp; <i>lhs</i>);
</pre>
<blockquote>
<p>
<b>Returns:</b> Adds <i>lhs</i> to <code>0</code>, as in IEEE-754R, and returns the result.
</p>
</blockquote>
<pre>
        decimal64 operator-(const decimal64 &amp; <i>lhs</i>);
</pre>
<blockquote>
<p>
<b>Returns:</b> Subtracts <i>lhs</i> from <code>0</code>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<h3>
3.3.12 Binary arithmetic operators
</h3>
<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator+(const LHS &amp; <i>lhs</i>, const decimal64 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> Adds <i>rhs</i> to <i>lhs</i>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator+(const decimal64 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> Adds <i>rhs</i> to <i>lhs</i>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator-(const LHS &amp; <i>lhs</i>, const decimal64 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> Subtracts <i>rhs</i> to <i>lhs</i>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator-(const decimal64 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> Subtracts <i>rhs</i> from <i>lhs</i>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator*(const LHS &amp; <i>lhs</i>, const decimal64 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> Multiplies <i>lhs</i> by <i>rhs</i>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator*(const decimal64 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> Multiplies <i>lhs</i> by <i>rhs</i>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator/(const LHS &amp; <i>lhs</i>, const decimal64 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> Divides <i>lhs</i> by <i>rhs</i>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator/(const decimal64 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> Divides <i>lhs</i> by <i>rhs</i>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<h3>
3.3.13 Comparison operators
</h3>
<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator==(const LHS &amp; <i>lhs</i>, const decimal64 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is exactly equal to <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator==(const decimal64 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is exactly equal to <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator!=(const LHS &amp; <i>lhs</i>, const decimal64 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is not exactly equal to <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator!=(const decimal64 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is not exactly equal to <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator&lt;(const LHS &amp; <i>lhs</i>, const decimal64 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is less than <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator&lt;(const decimal64 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is less than <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator&lt;=(const LHS &amp; <i>lhs</i>, const decimal64 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is less than or equal to <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator&lt;=(const decimal64 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is less than or equal to <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator>(const LHS &amp; <i>lhs</i>, const decimal64 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is greater than <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator>(const decimal64 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is greater than <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator>=(const LHS &amp; <i>lhs</i>, const decimal64 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is greater than or equal to <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator>=(const decimal64 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is greater than or equal to <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<h3>
3.3.14 Formatted input
</h3>
<pre>
        template &lt;class charT, class traits>
          std::basic_istream&lt;charT, traits> &amp;
            operator>>(std::basic_istream&lt;charT, traits> &amp; <i>is</i>, const decimal64 &amp; <i>d</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b>
This function constructs an object of class <code>std::basic_istream&lt;charT, traits>::sentry</code>.  If the <code>sentry</code> object returns <code>true</code> when converted to a value of type bool, input is extracted as if by the following code fragment:
</p>
<pre>
    typedef extended_num_get&lt;charT, std::istreambuf_iterator&lt;charT, traits> > extnumget;
    std::ios_base::iostate err = 0;
    std::use_facet&lt;extnumget>(is.getloc()).get(*this, 0, *this, err, d);
    setstate(err);
</pre>
<p>
If an exception is thrown during input then <code>std::ios::badbit</code> is set in the error state of the input stream <i>is</i>.  If <code>(<i>is</i>.exceptions() &amp; std::ios_base::badbit) != 0</code> then the exception is rethrown.  In any case, the formatted input function destroys the <code>sentry</code> object.
</p>
<p>
<b>Returns:</b> <i>is</i>.
</p>
</blockquote>

<h3>
3.3.15 Formatted output
</h3>
<pre>
        template &lt;class charT, class traits>
          std::basic_ostream&lt;charT, traits> &amp;
            operator&lt;&lt;(std::basic_ostream&lt;charT, traits> &amp; <i>os</i>, const decimal64 &amp; <i>d</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b>
This function constructs an object of class <code>std::basic_ostream&lt;charT, traits>::sentry</code>.  If the <code>sentry</code> object returns <code>true</code> when converted to a value of type bool, output is generated as if by the following code fragment:

</p>
<pre>
    typedef extended_num_put&lt;charT, std::ostreambuf_iterator&lt;charT, traits> > extnumput;
    bool failed =
      std::use_facet&lt;extnumput>(os.getloc()).put(*this, *this, os.fill(), d).failed();
    if (failed)
      { os.setstate(std::ios_base::failbit); }
</pre>
<p>
If an exception is thrown during output then <code>std::ios::badbit</code> is set in the error state of the input stream <i>os</i>.  If <code>(<i>os</i>.exceptions() &amp; std::ios_base::badbit) != 0</code> then the exception is rethrown.  In any case, the formatted output function destroys the <code>sentry</code> object.
</p>
<p>
<b>Returns:</b> <i>os</i>.
</p>
</blockquote>
<h3>
3.3.16 Addition to header <code>&lt;limits></code>
</h3>
<p>
The standard template <code>std::numeric_limits</code> shall be specialized for the <code>decimal64</code> type.
</p>
<p>
[<i>Example:</i>
</p>
<pre>
      namespace std {
        template&lt;> class numeric_limits&lt;dfp::decimal64> {
          public:
            static const bool is_specialized = true;

            static dfp::decimal64 min() throw() { return DEC64_MIN; }
            static dfp::decimal64 max() throw() { return DEC64_MAX; }

            static const int digits       = 16;
            static const int digits10     = digits; 
            static const int max_digits10 = digits; 

            static const bool is_signed   = true;
            static const bool is_integer  = false;
            static const bool is_exact    = false;

            static const int radix = 10;
            static dfp::decimal64 epsilon()     throw() { return DEC64_EPSILON; }
            static dfp::decimal64 round_error() throw() { return ...; }

            static const int min_exponent   = -383;
            static const int min_exponent10 = min_exponent;
            static const int max_exponent   = 384;
            static const int max_exponent10 = max_exponent; 

            static const bool has_infinity             = true;
            static const bool has_quiet_NaN            = true;
            static const bool has_signaling_NaN        = true;
            static const float_denorm_style has_denorm = denorm_present;
            static const bool has_denorm_loss          = true;

            static dfp::decimal64 infinity()      throw() { return ...; }
            static dfp::decimal64 quiet_NaN()     throw() { return ...; }
            static dfp::decimal64 signaling_NaN() throw() { return ...; }
            static dfp::decimal64 denorm_min()    throw() { return DEC64_DEN; }

            static const bool is_iec559       = false;
            static const bool is_bounded      = true;
            static const bool is_modulo       = false;
            static const bool traps           = true;
            static const bool tinyness_before = true;

            static const float_round_style round_style = round_indeterminate;
        };
      }
</pre>
<p>
--<i>end example</i>]
</p>
<h2>
3.4 128-bit Decimal type
</h2>
<h3>
3.4.1 Header <code>&lt;dec128></code> synopsis
</h3>
<pre>
      #include &lt;iosfwd>

      namespace std {
      namespace dfp {
        class decimal128;

        // <i>3.4.9 initialization from coefficient and exponent:</i> 
        decimal128 make_decimal128(long long <i>coeff</i>, int <i>exponent</i>);
        decimal128 make_decimal128(unsigned long long <i>coeff</i>, int <i>exponent</i>);

        // <i>3.4.10 conversion functions:</i>
        long double decimal128_to_long_double(decimal128 <i>d</i>);
        long double decimal_to_long_double(decimal128 <i>d</i>);

        // <i>3.4.11 unary arithmetic operators:</i>
        decimal128 operator+(const decimal128 &amp; <i>lhs</i>);
        decimal128 operator-(const decimal128 &amp; <i>lhs</i>);

        // <i>3.4.12 binary arithmetic operators:</i>
        template &lt;class LHS>
        <b>implementation-defined</b> operator+(const LHS &amp; <i>lhs</i>, const decimal128 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator+(const decimal128 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        template &lt;class LHS>
        <b>implementation-defined</b> operator-(const LHS &amp; <i>lhs</i>, const decimal128 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator-(const decimal128 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        template &lt;class LHS>
        <b>implementation-defined</b> operator*(const LHS &amp; <i>lhs</i>, const decimal128 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator*(const decimal128 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        template &lt;class LHS>
        <b>implementation-defined</b> operator/(const LHS &amp; <i>lhs</i>, const decimal128 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator/(const decimal128 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        // <i>3.4.13 comparison operators:</i>
        template &lt;class LHS>
        <b>implementation-defined</b> operator==(const LHS &amp; <i>lhs</i>, const decimal128 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator==(const decimal128 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        template &lt;class LHS>
        <b>implementation-defined</b> operator!=(const LHS &amp; <i>lhs</i>, const decimal128 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator!=(const decimal128 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        template &lt;class LHS>
        <b>implementation-defined</b> operator&lt;(const LHS &amp; <i>lhs</i>, const decimal128 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator&lt;(const decimal128 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        template &lt;class LHS>
        <b>implementation-defined</b> operator&lt;=(const LHS &amp; <i>lhs</i>, const decimal128 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator&lt;=(const decimal128 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        template &lt;class LHS>
        <b>implementation-defined</b> operator>(const LHS &amp; <i>lhs</i>, const decimal128 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator>(const decimal128 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        template &lt;class LHS>
        <b>implementation-defined</b> operator>=(const LHS &amp; <i>lhs</i>, const decimal128 &amp; <i>rhs</i>);

        template &lt;class RHS>
        <b>implementation-defined</b> operator>=(const decimal128 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);

        // <i>3.4.14 Formatted input</i>
        template &lt;class charT, class traits>
          std::basic_istream&lt;charT, traits> &amp;
            operator>>(std::basic_istream&lt;charT, traits> &amp; <i>is</i>, const decimal128 &amp; <i>d</i>);

        // <i>3.4.15 Formatted output</i>
        template &lt;class charT, class traits>
          std::basic_ostream&lt;charT, traits> &amp;
            operator&lt;&lt;(std::basic_ostream&lt;charT, traits> &amp; <i>os</i>, const decimal128 &amp; <i>d</i>);
      }
      }
</pre>

<h3>
3.4.2 Class <code>decimal128</code>
</h3>
<pre>
      namespace std {
      namespace dfp {
        class decimal128 {
          public:
            // <i>3.4.3 construct/copy/destroy:</i>
            decimal128();
            decimal128(const decimal128 &amp; <i>d128</i>);
            decimal128 &amp; operator=(const decimal128 &amp; <i>d128</i>);
            ~decimal128();

            // <i>3.4.4 conversion from floating-point type:</i> 
            decimal128(const decimal32 &amp; <i>d32</i>);
            decimal128(const decimal64 &amp; <i>d64</i>);
            explicit decimal128(float <i>r</i>);
            explicit decimal128(double <i>r</i>);
            explicit decimal128(long double <i>r</i>);

            // <i>3.4.5 conversion from integral type:</i> 
            decimal128(int <i>z</i>);
            decimal128(unsigned int <i>z</i>);
            decimal128(long <i>z</i>);
            decimal128(unsigned long <i>z</i>);
            decimal128(long long <i>z</i>);
            decimal128(unsigned long long <i>z</i>);

            // <i>3.4.6 conversion to integral type:</i> 
            operator long long() const;

            // <i>3.4.7 increment and decrement operators:</i> 
            decimal128 &amp; operator++();
            decimal128   operator++(int);
            decimal128 &amp; operator--();
            decimal128   operator--(int);

            // <i>3.4.8 compound assignment:</i> 
            template &lt;class T>
              <b>implementation-defined</b> operator+=(T <i>rhs</i>);

            template &lt;class T>
              <b>implementation-defined</b> operator-=(T <i>rhs</i>);

            template &lt;class T>
              <b>implementation-defined</b> operator*=(T <i>rhs</i>);

            template &lt;class T>
              <b>implementation-defined</b> operator/=(T <i>rhs</i>);
        };
      }
      }
</pre>
<h3>
3.4.3 Construct/copy/destroy
</h3>
<pre>
        decimal128();
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an object of type decimal128 with the value 0;
</p>
</blockquote>
<pre>
        decimal128(const decimal128 &amp; <i>d128</i>);
        decimal128 &amp; operator=(const decimal128 &amp; <i>d128</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b> Copies an object of type decimal128.
</p>
</blockquote>
<pre>
       ~decimal128();
</pre>
<blockquote>
<p>
<b>Effects:</b> Destroys an object of type decimal128.
</p>
</blockquote>
<h3>
3.4.4 Conversion from floating-point type
</h3>

<pre>
        decimal128(const decimal32 &amp; <i>d32</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an object of type decimal32 by converting from type decimal32.  Conversion is performed as in IEEE-754R.
</p>
</blockquote>
<pre>
        decimal128(const decimal64 &amp; <i>d64</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an object of type decimal128 by converting from type decimal64.  Conversion is performed as in IEEE-754R.
</p>
</blockquote>

<pre>
        explicit decimal128(float <i>r</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an object of type decimal128 by converting from type <code>float</code>.  If <code>std::numeric_limits&lt;float>::is_iec559 == true</code> then the conversion is performed as in IEEE-754R.  Otherwise, the result of the conversion is implementation-defined.
</p>
</blockquote>
<pre>
        explicit decimal128(double <i>r</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an object of type decimal128 by converting from type <code>double</code>.  If <code>std::numeric_limits&lt;float>::is_iec559 == true</code> then the conversion is performed as in IEEE-754R.  Otherwise, the result of the conversion is implementation-defined.
</p>
</blockquote>
<pre>
        explicit decimal128(long double <i>r</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an object of type decimal128 by converting from type <code>long double</code>.  If <code>std::numeric_limits&lt;float>::is_iec559 == true</code> then the conversion is performed as in IEEE-754R.  Otherwise, the result of the conversion is implementation-defined.
</p>
</blockquote>
<h3>
3.4.5 Conversion from integral type
</h3>
<pre>
        decimal128(int <i>z</i>);
        decimal128(unsigned int <i>z</i>);
        decimal128(long <i>z</i>);
        decimal128(unsigned long <i>z</i>);
        decimal128(long long <i>z</i>);
        decimal128(unsigned long long <i>z</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an object of type decimal128 by converting from the type of <i>z</i>.  Conversion is performed as in IEEE-754R.
</p>
</blockquote>

<h3>
3.4.6 Conversion to integral type
</h3>
<pre>
        operator long long() const;
</pre>
<blockquote>
<p>
<b>Returns:</b> Returns the result of the conversion of <code>*this</code> to the type <code>long long</code>, as if performed by the expression <code>llroundd128(*this)</code>.
</p>
</blockquote>

<h3>
3.4.7 Increment and decrement operators
</h3>
<pre>
        decimal128 &amp; operator++();
</pre>
<blockquote>
<p>
<b>Effects: </b>Adds 1 to <code>*this</code>, as in IEEE-754R, and assigns the result to <code>*this</code>.
<br/>
<b>Returns: </b><code>*this</code>
</p>
</blockquote>
<pre>
        decimal128   operator++(int);
</pre>
<blockquote>
<p>
<b>Effects:</b>
</p>
<pre>
        decimal128 tmp = *this;
        *this += 1;
        return tmp; 
</pre>
</blockquote>
<pre>
        decimal128 &amp; operator--();
</pre>
<blockquote>
<p>
<b>Effects: </b>Subtracts 1 from <code>*this</code>, as in IEEE-754R, and assigns the result to <code>*this</code>.
<br/>
<b>Returns: </b><code>*this</code>
</p>
</blockquote>
<pre>
        decimal64   operator--(int);
</pre>
<blockquote>
<p>
<b>Effects:</b>
</p>
<pre>
        decimal128 tmp = *this;
        *this -= 1;
        return tmp; 
</pre>
</blockquote>

<h3>
3.4.8 Compound assignment
</h3>
<pre>
        template &lt;class T>
        <b>implementation-defined</b> operator+=(const T &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>T</code> is one of the integral types, or one of the decimal floating-point types.
<br/>
<b>Effects:</b> Adds <i>rhs</i> to <code>*this</code>, as in IEEE-754R, and assigns the result to <code>*this</code>.
<br/>
<b>Returns:</b> <code>*this</code> 
</p>
</blockquote>

<pre>
        template &lt;class T>
        <b>implementation-defined</b> operator-=(const T &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>T</code> is one of the integral types, or one of the decimal floating-point types.
<br/>
<b>Effects:</b> Subtracts <i>rhs</i> from <code>*this</code>, as in IEEE-754R, and assigns the result to <code>*this</code>.
<br/>
<b>Returns:</b> <code>*this</code> 
</p>
</blockquote>

<pre>
        template &lt;class T>
        <b>implementation-defined</b> operator*=(const T &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>T</code> is one of the integral types, or one of the decimal floating-point types.
<br/>
<b>Effects:</b> Multiplies <code>*this</code> by <i>rhs</i>, as in IEEE-754R, and assigns the result to <code>*this</code>.
<br/>
<b>Returns:</b> <code>*this</code> 
</p>
</blockquote>

<pre>
        template &lt;class T>
        <b>implementation-defined</b> operator/=(const T &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>T</code> is one of the integral types, or one of the decimal floating-point types.
<br/>
<b>Effects:</b> Divides <code>*this</code> by <i>rhs</i>, as in IEEE-754R, and assigns the result to <code>*this</code>.
<br/>
<b>Returns:</b> <code>*this</code> 
</p>
</blockquote>

<h3>
3.4.9 Initialization from coefficient and exponent
</h3>
<pre>
        decimal128 make_decimal128(long long <i>coeff</i>, int <i>exponent</i>);
        decimal128 make_decimal128(unsigned long long <i>coeff</i>, int <i>exponent</i>);
</pre>
<blockquote>
<p>
<b>Returns:</b> <code>powd128(<i>coeff</i>, <i>exponent</i>)</code>
</p>
</blockquote>

<h3>
3.4.10 Conversion to generic floating-point type
</h3>
<pre>
        long double decimal128_to_long_double(decimal128 <i>d</i>);
        long double decimal_to_long_double(decimal128 <i>d</i>);
</pre>
<blockquote>
<p>
<b>Returns:</b> If <code>std::numeric_limits&lt;long double>::is_iec559 == true</code>, returns the result of the conversion of <code>*this</code> to <code>long double</code>, performed as in IEEE-754R.  Otherwise, the returned value is implementation-defined.
</p>
</blockquote>
<p>
[<i>Editor's note:</i> this notation is ugly.  A user-defined converson operator would be vastly preferable to these functions but, alas, user-defined conversion operators cannot be <code>explicit</code>.  A previous draft of this document specified a <code>decimal128</code> member function named <code>to_long_double()</code> that had the same result as these functions.  The current "free function" approach is better because it works regardless of whether the implementation of these types uses library classes or compiler builtins.  The <code>decimal128_to_long_double</code> form is provided for C programmers who want to write code that works equally well in C++.]
</p>

<h3>
3.4.11 Unary arithmetic operators
</h3>
<pre>
        decimal128 operator+(const decimal128 &amp; <i>lhs</i>);
</pre>
<blockquote>
<p>
<b>Returns:</b> Adds <i>lhs</i> to <code>0</code>, as in IEEE-754R, and returns the result.
</p>
</blockquote>
<pre>
        decimal128 operator-(const decimal128 &amp; <i>lhs</i>);
</pre>
<blockquote>
<p>
<b>Returns:</b> Subtracts <i>lhs</i> from <code>0</code>, as in IEEE-754R, and returns the result.
</p>
</blockquote>
<h3>

3.4.12 Binary arithmetic operators
</h3>
<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator+(const LHS &amp; <i>lhs</i>, const decimal128 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> Adds <i>rhs</i> to <i>lhs</i>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator+(const decimal128 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> Adds <i>rhs</i> to <i>lhs</i>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator-(const LHS &amp; <i>lhs</i>, const decimal128 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> Subtracts <i>rhs</i> to <i>lhs</i>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator-(const decimal128 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> Subtracts <i>rhs</i> from <i>lhs</i>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator*(const LHS &amp; <i>lhs</i>, const decimal128 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> Multiplies <i>lhs</i> by <i>rhs</i>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator*(const decimal128 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> Multiplies <i>lhs</i> by <i>rhs</i>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator/(const LHS &amp; <i>lhs</i>, const decimal128 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> Divides <i>lhs</i> by <i>rhs</i>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator/(const decimal128 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> Divides <i>lhs</i> by <i>rhs</i>, as in IEEE-754R, and returns the result.
</p>
</blockquote>

<h3>
3.4.13 Comparison operators
</h3>
<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator==(const LHS &amp; <i>lhs</i>, const decimal128 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is exactly equal to <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator==(const decimal128 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is exactly equal to <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator!=(const LHS &amp; <i>lhs</i>, const decimal128 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is not exactly equal to <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator!=(const decimal128 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is not exactly equal to <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator&lt;(const LHS &amp; <i>lhs</i>, const decimal128 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is less than <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator&lt;(const decimal128 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is less than <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator&lt;=(const LHS &amp; <i>lhs</i>, const decimal128 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is less than or equal to <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator&lt;=(const decimal128 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is less than or equal to <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator>(const LHS &amp; <i>lhs</i>, const decimal128 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is greater than <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator>(const decimal128 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is greater than <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class LHS>
        <b>implementation-defined</b> operator>=(const LHS &amp; <i>lhs</i>, const decimal128 &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>LHS</code> is one of the integral types
or one of the decimal floating-point types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is greater than or equal to <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<pre>
        template &lt;class RHS>
        <b>implementation-defined</b> operator>=(const decimal128 &amp; <i>lhs</i>, const RHS &amp; <i>rhs</i>);
</pre>
<blockquote>
<p>
<b>Constraints:</b> <code>RHS</code> is one of the integral types.
<br/>
<b>Returns:</b> <code>true</code> if <i>lhs</i> is greater than or equal to <i>rhs</i> according to IEEE-754R, <code>false</code> otherwise.
</p>
</blockquote>

<h3>
3.4.14 Formatted input
</h3>
<pre>
        template &lt;class charT, class traits>
          std::basic_istream&lt;charT, traits> &amp;
            operator>>(std::basic_istream&lt;charT, traits> &amp; <i>is</i>, const decimal128 &amp; <i>d</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b>
This function constructs an object of class <code>std::basic_istream&lt;charT, traits>::sentry</code>.  If the <code>sentry</code> object returns <code>true</code> when converted to a value of type bool, input is extracted as if by the following code fragment:
</p>
<pre>
    typedef extended_num_get&lt;charT, std::istreambuf_iterator&lt;charT, traits> > extnumget;
    std::ios_base::iostate err = 0;
    std::use_facet&lt;extnumget>(is.getloc()).get(*this, 0, *this, err, d);
    setstate(err);
</pre>
<p>
If an exception is thrown during input then <code>std::ios::badbit</code> is set in the error state of the input stream <i>is</i>.  If <code>(<i>is</i>.exceptions() &amp; std::ios_base::badbit) != 0</code> then the exception is rethrown.  In any case, the formatted input function destroys the <code>sentry</code> object.
</p>
<p>
<b>Returns:</b> <i>is</i>.
</p>
</blockquote>

<h3>
3.4.15 Formatted output
</h3>
<pre>
        template &lt;class charT, class traits>
          std::basic_ostream&lt;charT, traits> &amp;
            operator&lt;&lt;(std::basic_ostream&lt;charT, traits> &amp; <i>os</i>, const decimal128 &amp; <i>d</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b>
This function constructs an object of class <code>std::basic_ostream&lt;charT, traits>::sentry</code>.  If the <code>sentry</code> object returns <code>true</code> when converted to a value of type bool, output is generated as if by the following code fragment:

</p>
<pre>
    typedef extended_num_put&lt;charT, std::ostreambuf_iterator&lt;charT, traits> > extnumput;
    bool failed =
      std::use_facet&lt;extnumput>(os.getloc()).put(*this, *this, os.fill(), d).failed();
    if (failed)
      { os.setstate(std::ios_base::failbit); }
</pre>
<p>
If an exception is thrown during output then <code>std::ios::badbit</code> is set in the error state of the input stream <i>os</i>.  If <code>(<i>os</i>.exceptions() &amp; std::ios_base::badbit) != 0</code> then the exception is rethrown.  In any case, the formatted output function destroys the <code>sentry</code> object.
</p>
<p>
<b>Returns:</b> <i>os</i>.
</p>
</blockquote>

<h3>
3.4.16 Addition to header <code>&lt;limits></code>
</h3>
<p>
The standard template <code>std::numeric_limits</code> shall be specialized for the <code>decimal128</code> type.
</p>
<p>
[<i>Example:</i>
</p>
<pre>
      namespace std {
        template&lt;> class numeric_limits&lt;dfp::decimal128> {
          public:
            static const bool is_specialized = true;

            static dfp::decimal128 min() throw() { return DEC128_MIN; }
            static dfp::decimal128 max() throw() { return DEC128_MIN; }

            static const int digits       = 384;
            static const int digits10     = digits; 
            static const int max_digits10 = digits; 

            static const bool is_signed  = true;
            static const bool is_integer = false;
            static const bool is_exact   = false;

            static const int radix = 10;
            static dfp::decimal128 epsilon()     throw() { return DEC128_EPSILON; }
            static dfp::decimal128 round_error() throw() { return ...; }

            static const int min_exponent   = -6143;
            static const int min_exponent10 = min_exponent;
            static const int max_exponent   = 6144;
            static const int max_exponent10 = max_exponent; 

            static const bool has_infinity             = true;
            static const bool has_quiet_NaN            = true;
            static const bool has_signaling_NaN        = true;
            static const float_denorm_style has_denorm = denorm_present;
            static const bool has_denorm_loss          = true;

            static dfp::decimal128 infinity()      throw() { return ...; }
            static dfp::decimal128 quiet_NaN()     throw() { return ...; }
            static dfp::decimal128 signaling_NaN() throw() { return ...; }
            static dfp::decimal128 denorm_min()    throw() { return DEC128_DEN; }

            static const bool is_iec559       = false;
            static const bool is_bounded      = true;
            static const bool is_modulo       = false;
            static const bool traps           = true;
            static const bool tinyness_before = true;

            static const float_round_style round_style = round_indeterminate;
        };
      }
</pre>
<p>
--<i>end example</i>]
</p>

<h2>
3.5 Headers <code>&lt;cdecfloat></code> and <code>&lt;decfloat.h></code>
</h2>
<p>
The standard C++ headers <code>&lt;cfloat></code> and <code>&lt;float.h></code> define characteristics of the floating-point types <code>float</code>, <code>double</code>, and <code>long double</code>.  Their contents remain unchanged by this Technical Report.
</p>
<p>
Headers <code>&lt;cdecfloat></code> and <code>&lt;decfloat.h></code> define characteristics of the decimal floating-point types <code>decimal32</code>, <code>decimal64</code>, and <code>decimal128</code>.  As well, <code>&lt;decfloat.h></code> defines the convenience typedefs <code>_Decimal32</code>, <code>_Decimal64</code>, and <code>_Decimal128</code>, for compatibilty with the C programming language.
</p>
<h3>
3.5.1 Header <code>&lt;cdecfloat></code> synopsis
</h3>
<pre>
      #include &lt;dec32>
      #include &lt;dec64>
      #include &lt;dec128>

      // <i>number of digits in the coefficient:</i>
      #define DEC32_MANT_DIG  7
      #define DEC64_MANT_DIG 16
      #define DEC64_MANT_DIG 34

      // <i>minimum exponent:</i>
      #define DEC32_MIN_EXP    -95
      #define DEC64_MIN_EXP   -383
      #define DEC128_MIN_EXP -6143

      // <i>maximum exponent:</i>
      #define DEC32_MIN_EXP    96
      #define DEC64_MIN_EXP   384
      #define DEC128_MIN_EXP 6144

      // <i>3.5.3 maximum finite value:</i>
      #define DEC32_MAX       <b>implementation-defined</b>
      #define DEC64_MAX       <b>implementation-defined</b>
      #define DEC128_MAX      <b>implementation-defined</b>

      // <i>3.5.4 epsilon:</i>
      #define DEC32_EPSILON   <b>implementation-defined</b>
      #define DEC64_EPSILON   <b>implementation-defined</b>
      #define DEC128_EPSILON  <b>implementation-defined</b>

      // <i>3.5.5 minimum positive normal value:</i>
      #define DEC32_MIN       <b>implementation-defined</b>
      #define DEC64_MIN       <b>implementation-defined</b>
      #define DEC128_MIN      <b>implementation-defined</b>

      // <i>3.5.6 minimum positive subnormal value:</i>
      #define DEC32_DEN       <b>implementation-defined</b>
      #define DEC64_DEN       <b>implementation-defined</b>
      #define DEC128_DEN      <b>implementation-defined</b>
      
      // <i>3.5.7 evaluation format:</i>
      #define DEC_EVAL_METHOD <b>implementation-defined</b>
</pre>
<h3>
3.5.2 Header <code>&lt;decfloat.h></code> synopsis
</h3>
<pre>
      #include &lt;cdecfloat>

      // <i>C-compatibility convenience typedefs:</i>
      typedef std::dfp::decimal32  _Decimal32;
      typedef std::dfp::decimal64  _Decimal64;
      typedef std::dfp::decimal128 _Decimal128;
</pre>
<p>
</p>
<h3>
3.5.3 Maximum finite value
</h3>
<pre>        #define DEC32_MAX  <b>implementation-defined</b></pre>
<blockquote>
<p>
<b>Expansion:</b> an lvalue of type <code>decimal32</code> equal to the maximum finite number that can be represented by an object of type <code>decimal32</code>; exactly equal to 9.999999 x 10<sup>96</sup> (there are six 9's after the decimal point)
</p>
</blockquote>
<pre>        #define DEC64_MAX  <b>implementation-defined</b></pre>
<blockquote>
<p>
<b>Expansion:</b> an lvalue of type <code>decimal64</code> equal to the maximum finite number that can be represented by an object of type <code>decimal64</code>; exactly equal to 9.999999999999999 x 10<sup>384</sup> (there are fifteen 9's after the decimal point)
</p>
</blockquote>
<pre>        #define DEC128_MAX <b>implementation-defined</b></pre>
<blockquote>
<p>
<b>Expansion:</b> an lvalue of type <code>decimal128</code> equal to the maximum finite number that can be represented by an object of type <code>decimal128</code>; exactly equal to 9.999999999999999999999999999999999 x 10<sup>6144</sup> (there are thirty-three 9's after the decimal point)
</p>
</blockquote>
<h3>
3.5.4 Epsilon 
</h3>
<pre>        #define DEC32_EPSILON  <b>implementation-defined</b></pre>
<blockquote>
<p>
<b>Expansion:</b> an lvalue of type <code>decimal32</code> equal to the difference between 1 and the least value greater than 1 that can be represented by an object of type <code>decimal32</code>; exactly equal to 1 x 10<sup>-6</sup>
</p>
</blockquote>
<pre>        #define DEC64_EPSILON  <b>implementation-defined</b></pre>
<blockquote>
<p>
<b>Expansion:</b> an lvalue of type <code>decimal64</code> equal to the difference between 1 and the least value greater than 1 that can be represented by an object of type <code>decimal64</code>; exactly equal to 1 x 10<sup>-15</sup>
</p>
</blockquote>
<pre>        #define DEC128_EPSILON <b>implementation-defined</b></pre>
<blockquote>
<p>
<b>Expansion:</b> an lvalue of type <code>decimal128</code> equal to the difference between 1 and the least value greater than 1 that can be represented by an object of type <code>decimal128</code>; exactly equal to 1 x 10<sup>-33</sup>
</p>
</blockquote>
<h3>
3.5.5 Minimum positive normal value
</h3>
<pre>        #define DEC32_MIN  <b>implementation-defined</b></pre>
<blockquote>
<p>
<b>Expansion:</b> an lvalue of type <code>decimal32</code> equal to the minimum positive normal number that can be represented by an object of type <code>decimal32</code>; exactly equal to 1 x 10<sup>-95</sup>
</p>
</blockquote>
<pre>        #define DEC64_MIN  <b>implementation-defined</b></pre>
<blockquote>
<p>
<b>Expansion:</b> an lvalue of type <code>decimal64</code> equal to the minimum positive normal number that can be represented by an object of type <code>decimal64</code>; exactly equal to 1 x 10<sup>-383</sup>
</p>
</blockquote>
<pre>        #define DEC128_MIN <b>implementation-defined</b></pre>
<blockquote>
<p>
<b>Expansion:</b> an lvalue of type <code>decimal128</code> equal to the minimum positive normal number that can be represented by an object of type <code>decimal128</code>; exactly equal to 1 x 10<sup>-6143</sup>
</p>
</blockquote>
<h3>
3.5.6 Minimum positive subnormal value
</h3>
<pre>        #define DEC32_DEN  <b>implementation-defined</b></pre>
<blockquote>
<p>
<b>Expansion:</b> an lvalue of type <code>decimal32</code> equal to the minimum positive finite number that can be represented by an object of type <code>decimal32</code>; exactly equal to 1 x 10<sup>-101</sup>
</p>
</blockquote>
<pre>        #define DEC64_DEN  <b>implementation-defined</b></pre>
<blockquote>
<p>
<b>Expansion:</b> an lvalue of type <code>decimal64</code> equal to the minimum positive finite number that can be represented by an object of type <code>decimal64</code>; exactly equal to 1 x 10<sup>-398</sup>
</p>
</blockquote>
<pre>        #define DEC128_DEN <b>implementation-defined</b></pre>
<blockquote>
<p>
<b>Expansion:</b> an lvalue of type <code>decimal128</code> equal to the minimum positive finite number that can be represented by an object of type <code>decimal128</code>; exactly equal to 1 x 10<sup>-6176</sup>
</p>
</blockquote>
<h3>
3.5.7 Evaluation format
</h3>
<pre>        #define DEC_EVAL_METHOD <b>implementation-defined</b></pre>
<p>
Except for assignment and casts, the values of operations with decimal floating operands and values subject to the usual arithmetic conversions are evaluated to a format whose range and precision may be greater than required by the type.  The use of evaluation formats is characterized by the implementation-defined value of <code>DEC_EVAL_METHOD</code>:
</p>
<pre>
      -1 indeterminable;

       0 evaluate all operations and constants just to the range and precision of the
         type;

       1 evaluate operations and constants of type <code>decimal32</code> and <code>decimal64</code> to the
         range and precision of the <code>decimal64</code> type, evaluate <code>decimal128</code>
         operations and constants to the range and precision of the <code>decimal128</code>
         type;

       2 evaluate all operations and constants to the range and precision of the
         <code>decimal128</code> type.
</pre>

<p>
All other negative values for <code>DEC_EVAL_METHOD</code> characterize implementation-defined behavior.
</p>

<h2>
3.6 Additions to <code>&lt;cfenv></code> and <code>&lt;fenv.h></code>
</h2>
<p>
The header <code>&lt;cfenv></code> is described in [tr.c99.cfenv].  The header <code>&lt;fenv.h></code> is described in [tr.c99.fenv].  The floating point environment specified in these clauses is extended by this Technical Report to apply to decimal floating-point types.
</p>

<h3>
3.6.1 Additions to <code>&lt;cfenv></code> synopsis
</h3>
<pre>
      // <i>3.6.2</i> rounding direction macros:
      #define FE_DEC_DOWNWARD          <b>implementation-defined</b>
      #define FE_DEC_TONEAREST         <b>implementation-defined</b>
      #define FE_DEC_TONEARESTFROMZERO <b>implementation-defined</b>
      #define FE_DEC_TOWARD_ZERO       <b>implementation-defined</b>
      #define FE_DEC_UPWARD            <b>implementation-defined</b>

      namespace std {
      namespace dfp {

        // <i>3.6.3 fe_dec_getround function:</i>
        int fe_dec_getround();
            
        // <i>3.6.4 fe_dec_setround function:</i>
        int fe_dec_setround(int <i>round</i>);
      }
      }
</pre>

<h3>
3.6.2 Rounding modes
</h3>
<p>
Macros are added to <code>&lt;cfenv></code> and <code>&lt;fenv.h></code>:
</p>
<h4>Table 2 -- DFP rounding direction macros</h4>
<table border="1">
<tr>
<th>
Additional DFP rounding direction macros <br/> introduced by this Technical Report
</th>
<th>
Equivalent TR1 macro <br/> for generic floating types
</th>
<th>
IEEE-754
</th>
</tr>
<tr>
<td>
FE_DEC_DOWNWARD
</td>
<td>
FE_DOWNWARD
</td>
<td>
Towards minus infinity
</td>
</tr>
<tr>
<td>
FE_DEC_TONEAREST
</td>
<td>
FE_TONEAREST
</td>
<td>
To nearest, ties even
</td>
</tr>
<tr>
<td>
FE_DEC_TONEARESTFROMZERO
</td>
<td>
n/a
</td>
<td>
To nearest, ties away from zero
</td>
</tr>
<tr>
<td>
FE_DEC_TOWARD_ZERO
</td>
<td>
FE_TOWARD_ZERO
</td>
<td>
Toward zero
</td>
</tr>
<tr>
<td>
FE_DEC_UPWARD
</td>
<td>
FE_UPWARD
</td>
<td>
Toward plus infinity
</td>
</tr>
</table>
<p>
These macros are used by the <code>fegetround</code> and <code>fesetround</code> functions for getting and setting the rounding mode to be used in decimal floating-point operations.
</p>

<h3>
3.6.3 The <code>fe_dec_getround</code> function 
</h3>
<pre>
        int fe_dec_getround();
</pre>
<blockquote>
<p>
<b>Effects:</b> gets the current rounding direction for decimal floating-point operations.
</p>
<p>
<b>Returns:</b> the value of the rounding direction macro representing the current rounding direction for decimal floating-point operations, or a negative value if there is no such rounding macro or the current rounding direction is not determinable.
</p>
</blockquote>

<h3>
3.6.4 The <code>fe_dec_setround</code> function 
</h3>
<pre>
        int fe_dec_setround(int <i>round</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b> establishes <i>round</i> as the rounding direction for decimal floating-point operations.  If <i>round</i> is not equal to the value of a DFP rounding direction macro, the rounding direction is not changed.
</p>
<p>
<b>Returns:</b> a zero value if and only if the argument is equal to one of the rounding direction macros introduced in 3.6.2.
</p>
</blockquote>

<h3>
3.6.5 Changes to <code>&lt;fenv.h></code>
</h3>
<p>
Each name placed into the namespace <code>dfp</code> by <code>&lt;cfenv></code> is placed into both the namespace <code>dfp</code> and the global namespace by <code>&lt;fenv.h></code>.
</p>

<h2>
3.7 Additions to <code>&lt;cmath></code> and <code>&lt;math.h></code>
</h2>
<p>
The elementary mathematical functions declared in the standard C++ header <code>&lt;cmath></code> are overloaded by this Technical Report to support the decimal floating-point types.  The macros <code>HUGE_VAL_D32</code>, <code>HUGE_VAL_D64</code>, <code>HUGE_VAL_D128</code>, <code>DEC_INFINITY</code>, and <code>DEC_NAN</code> are defined for use with these functions.  With the exception of <code>sqrt</code>, <code>fmax</code>, and <code>fmin</code>, the accuracy of the result of a call to one of these functions is implementation-defined.  The implementation may state that the accuracy is unknown.  The TR1 function templates <code>signbit</code>, <code>fpclassify</code>, <code>isinfinite</code>, <code>isinf</code>, <code>isnan</code>, <code>isnormal</code>, <code>isgreater</code>, <code>isgreaterequal</code>, <code>isless</code>, <code>islessequal</code>, <code>islessgreater</code>, and <code>isunordered</code> are also extended by this Technical Report to handle the decimal floating-point types.
</p>
<h3>
3.7.1 Additions to header <code>&lt;cmath></code> synopsis
</h3>
<pre>

      // <i>3.7.2 macros:</i>
      #define HUGE_VAL_D32    <b>implementation-defined</b>
      #define HUGE_VAL_D64    <b>implementation-defined</b>
      #define HUGE_VAL_D128   <b>implementation-defined</b>
      #define DEC_INFINITY    <b>implementation-defined</b>
      #define DEC_NAN         <b>implementation-defined</b>
      #define FP_FAST_FMAD32  <b>implementation-defined</b>
      #define FP_FAST_FMAD64  <b>implementation-defined</b>
      #define FP_FAST_FMAD128 <b>implementation-defined</b>
     
      namespace std {
      namespace dfp {

        // <i>3.7.3 evaluation formats:</i>
        typedef <i>decimal-floating-type</i> decimal32_t;
        typedef <i>decimal-floating-type</i> decimal64_t;

        // <i>3.7.4 samequantum functions:</i>
        bool samequantum     (decimal32 <i>x</i>,  decimal32 <i>y</i>);
        bool samequantumd32  (decimal32 <i>x</i>,  decimal32 <i>y</i>);

        bool samequantum     (decimal64 <i>x</i>,  decimal64 <i>y</i>);
        bool samequantumd64  (decimal64 <i>x</i>,  decimal64 <i>y</i>);

        bool samequantum     (decimal128 <i>x</i>, decimal128 <i>y</i>);
        bool samequantumd128 (decimal128 <i>x</i>, decimal128 <i>y</i>);

        // <i>3.7.5 quantize functions:</i>
        decimal32  quantize     (decimal32 <i>x</i>,  decimal32 <i>y</i>);
        decimal32  quantized32  (decimal32 <i>x</i>,  decimal32 <i>y</i>);

        decimal64  quantize     (decimal64 <i>x</i>,  decimal64 <i>y</i>);
        decimal64  quantized64  (decimal64 <i>x</i>,  decimal64 <i>y</i>);

        decimal128 quantize     (decimal128 <i>x</i>, decimal128 <i>y</i>);
        decimal128 quantized128 (decimal128 <i>x</i>, decimal128 <i>y</i>);

        // <i>3.7.6 elementary functions:</i>

        // <i>trigonometric functions:</i>
        decimal32  acosd32  (decimal32  <i>x</i>);
        decimal64  acosd64  (decimal64  <i>x</i>);
        decimal128 acosd128 (decimal128 <i>x</i>);

        decimal32  asind32  (decimal32  <i>x</i>);
        decimal64  asind64  (decimal64  <i>x</i>);
        decimal128 asind128 (decimal128 <i>x</i>);

        decimal32  atand32  (decimal32  <i>x</i>);
        decimal64  atand64  (decimal64  <i>x</i>);
        decimal128 atand128 (decimal128 <i>x</i>);

        decimal32  atan2d32  (decimal32  <i>x</i>, decimal32  <i>y</i>);
        decimal64  atan2d64  (decimal64  <i>x</i>, decimal64  <i>y</i>);
        decimal128 atan2d128 (decimal128 <i>x</i>, decimal128 <i>y</i>);

        decimal32  cosd32  (decimal32  <i>x</i>);
        decimal64  cosd64  (decimal64  <i>x</i>);
        decimal128 cosd128 (decimal128 <i>x</i>);

        decimal32  sind32  (decimal32  <i>x</i>);
        decimal64  sind64  (decimal64  <i>x</i>);
        decimal128 sind128 (decimal128 <i>x</i>);

        decimal32  tand32  (decimal32  <i>x</i>);
        decimal64  tand64  (decimal64  <i>x</i>);
        decimal128 tand128 (decimal128 <i>x</i>);

        // <i>hyperbolic functions:</i>
        decimal32  acoshd32  (decimal32  <i>x</i>);
        decimal64  acoshd64  (decimal64  <i>x</i>);
        decimal128 acoshd128 (decimal128 <i>x</i>);

        decimal32  asinhd32  (decimal32  <i>x</i>);
        decimal64  asinhd64  (decimal64  <i>x</i>);
        decimal128 asinhd128 (decimal128 <i>x</i>);

        decimal32  atanhd32  (decimal32  <i>x</i>);
        decimal64  atanhd64  (decimal64  <i>x</i>);
        decimal128 atanhd128 (decimal128 <i>x</i>);

        decimal32  coshd32  (decimal32  <i>x</i>);
        decimal64  coshd64  (decimal64  <i>x</i>);
        decimal128 coshd128 (decimal128 <i>x</i>);

        decimal32  sinhd32  (decimal32  <i>x</i>);
        decimal64  sinhd64  (decimal64  <i>x</i>);
        decimal128 sinhd128 (decimal128 <i>x</i>);

        decimal32  tanhd32  (decimal32  <i>x</i>);
        decimal64  tanhd64  (decimal64  <i>x</i>);
        decimal128 tanhd128 (decimal128 <i>x</i>);

        // <i>exponential and logarithmic functions:</i>
        decimal32  expd32  (decimal32  <i>x</i>);
        decimal64  expd64  (decimal64  <i>x</i>);
        decimal128 expd128 (decimal128 <i>x</i>);

        decimal32  exp2d32  (decimal32  <i>x</i>);
        decimal64  exp2d64  (decimal64  <i>x</i>);
        decimal128 exp2d128 (decimal128 <i>x</i>);

        decimal32  expm1d32  (decimal32  <i>x</i>);
        decimal64  expm1d64  (decimal64  <i>x</i>);
        decimal128 expm1d128 (decimal128 <i>x</i>);

        decimal32  frexpd32  (decimal32  <i>value</i>, int * <i>exp</i>);
        decimal64  frexpd64  (decimal64  <i>value</i>, int * <i>exp</i>);
        decimal128 frexpd128 (decimal128 <i>value</i>, int * <i>exp</i>);

        int ilogbd32  (decimal32  <i>x</i>);
        int ilogbd64  (decimal64  <i>x</i>);
        int ilogbd128 (decimal128 <i>x</i>);

        decimal32  ldexpd32  (decimal32  <i>x</i>, int <i>exp</i>);
        decimal64  ldexpd64  (decimal64  <i>x</i>, int <i>exp</i>);
        decimal128 ldexpd128 (decimal128 <i>x</i>, int <i>exp</i>);

        decimal32  logd32  (decimal32  <i>x</i>);
        decimal64  logd64  (decimal64  <i>x</i>);
        decimal128 logd128 (decimal128 <i>x</i>);

        decimal32  log10d32  (decimal32  <i>x</i>);
        decimal64  log10d64  (decimal64  <i>x</i>);
        decimal128 log10d128 (decimal128 <i>x</i>);

        decimal32  log1pd32  (decimal32  <i>x</i>);
        decimal64  log1pd64  (decimal64  <i>x</i>);
        decimal128 log1pd128 (decimal128 <i>x</i>);

        decimal32  log2d32  (decimal32  <i>x</i>);
        decimal64  log2d64  (decimal64  <i>x</i>);
        decimal128 log2d128 (decimal128 <i>x</i>);

        decimal32  logbd32  (decimal32  <i>x</i>);
        decimal64  logbd64  (decimal64  <i>x</i>);
        decimal128 logbd128 (decimal128 <i>x</i>);

        decimal32  modfd32  (decimal32  <i>value</i>, decimal32  * <i>iptr</i>);
        decimal64  modfd64  (decimal64  <i>value</i>, decimal64  * <i>iptr</i>);
        decimal32  modfd128 (decimal128 <i>value</i>, decimal128 * <i>iptr</i>);

        decimal32  scalbnd32  (decimal32  <i>x</i>, int <i>n</i>);
        decimal64  scalbnd64  (decimal64  <i>x</i>, int <i>n</i>);
        decimal128 scalbnd128 (decimal128 <i>x</i>, int <i>n</i>);

        decimal32  scalblnd32  (decimal32  <i>x</i>, long int <i>n</i>);
        decimal64  scalblnd64  (decimal64  <i>x</i>, long int <i>n</i>);
        decimal128 scalblnd128 (decimal128 <i>x</i>, long int <i>n</i>);

        // <i>power and absolute-value functions:</i>
        decimal32  cbrtd32  (decimal32  <i>x</i>);
        decimal64  cbrtd64  (decimal64  <i>x</i>);
        decimal128 cbrtd128 (decimal128 <i>x</i>);

        decimal32  fabsd32  (decimal32  <i>x</i>);
        decimal64  fabsd64  (decimal64  <i>x</i>);
        decimal128 fabsd128 (decimal128 <i>x</i>);

        decimal32  hypotd32  (decimal32  <i>x</i>, decimal32  <i>y</i>);
        decimal64  hypotd64  (decimal64  <i>x</i>, decimal64  <i>y</i>);
        decimal128 hypotd128 (decimal128 <i>x</i>, decimal128 <i>y</i>);

        decimal32  powd32  (decimal32  <i>x</i>, decimal32  <i>y</i>);
        decimal64  powd64  (decimal64  <i>x</i>, decimal64  <i>y</i>);
        decimal128 powd128 (decimal128 <i>x</i>, decimal128 <i>y</i>);

        decimal32  sqrtd32  (decimal32  <i>x</i>);
        decimal64  sqrtd64  (decimal64  <i>x</i>);
        decimal128 sqrtd128 (decimal128 <i>x</i>);

        // <i>error and gamma functions:</i>
        decimal32  erfd32  (decimal32  <i>x</i>);
        decimal64  erfd64  (decimal64  <i>x</i>);
        decimal128 erfd128 (decimal128 <i>x</i>);

        decimal32  erfcd32  (decimal32  <i>x</i>);
        decimal64  erfcd64  (decimal64  <i>x</i>);
        decimal128 erfcd128 (decimal128 <i>x</i>);

        decimal32  lgammad32  (decimal32  <i>x</i>);
        decimal64  lgammad64  (decimal64  <i>x</i>);
        decimal128 lgammad128 (decimal128 <i>x</i>);

        decimal32  tgammad32  (decimal32  <i>x</i>);
        decimal64  tgammad64  (decimal64  <i>x</i>);
        decimal128 tgammad128 (decimal128 <i>x</i>);

        // <i>nearest integer functions:</i>
        decimal32  ceild32  (decimal32  <i>x</i>);
        decimal64  ceild64  (decimal64  <i>x</i>);
        decimal128 ceild128 (decimal128 <i>x</i>);

        decimal32  floord32  (decimal32  <i>x</i>);
        decimal64  floord64  (decimal64  <i>x</i>);
        decimal128 floord128 (decimal128 <i>x</i>);

        decimal32  nearbyintd32  (decimal32  <i>x</i>);
        decimal64  nearbyintd64  (decimal64  <i>x</i>);
        decimal128 nearbyintd128 (decimal128 <i>x</i>);

        decimal32  rintd32  (decimal32  <i>x</i>);
        decimal64  rintd64  (decimal64  <i>x</i>);
        decimal128 rintd128 (decimal128 <i>x</i>);

        long int lrintd32  (decimal32  <i>x</i>);
        long int lrintd64  (decimal64  <i>x</i>);
        long int lrintd128 (decimal128 <i>x</i>);

        long long int llrintd32  (decimal32  <i>x</i>);
        long long int llrintd64  (decimal64  <i>x</i>);
        long long int llrintd128 (decimal128 <i>x</i>);

        decimal32  roundd32  (decimal32  <i>x</i>);
        decimal64  roundd64  (decimal64  <i>x</i>);
        decimal128 roundd128 (decimal128 <i>x</i>);

        long int lroundd32  (decimal32  <i>x</i>);
        long int lroundd64  (decimal64  <i>x</i>);
        long int lroundd128 (decimal128 <i>x</i>);

        long long int llroundd32  (decimal32  <i>x</i>);
        long long int llroundd64  (decimal64  <i>x</i>);
        long long int llroundd128 (decimal128 <i>x</i>);

        decimal32  truncd32  (decimal32  <i>x</i>);
        decimal64  truncd64  (decimal64  <i>x</i>);
        decimal128 truncd128 (decimal128 <i>x</i>);

        // <i>remainder functions:</i>
        decimal32  fmodd32  (decimal32  <i>x</i>, decimal32  <i>y</i>);
        decimal64  fmodd64  (decimal64  <i>x</i>, decimal64  <i>y</i>);
        decimal128 fmodd128 (decimal128 <i>x</i>, decimal128 <i>y</i>);

        decimal32  remainderd32  (decimal32  <i>x</i>, decimal32  <i>y</i>);
        decimal64  remainderd64  (decimal64  <i>x</i>, decimal64  <i>y</i>);
        decimal128 remainderd128 (decimal128 <i>x</i>, decimal128 <i>y</i>);

        decimal32  remquod32  (decimal32  <i>x</i>, decimal32  <i>y</i>, int * <i>quo</i>);
        decimal64  remquod64  (decimal64  <i>x</i>, decimal64  <i>y</i>, int * <i>quo</i>);
        decimal128 remquod128 (decimal128 <i>x</i>, decimal128 <i>y</i>, int * <i>quo</i>);

        // <i>manipulation functions:</i>
        decimal32  copysignd32  (decimal32  <i>x</i>, decimal32  <i>y</i>);
        decimal64  copysignd64  (decimal64  <i>x</i>, decimal64  <i>y</i>);
        decimal128 copysignd128 (decimal128 <i>x</i>, decimal128 <i>y</i>);

        decimal32  nand32  (const char * <i>tagp</i>);
        decimal64  nand64  (const char * <i>tagp</i>);
        decimal128 nand128 (const char * <i>tagp</i>);

        decimal32  nextafterd32  (decimal32  <i>x</i>, decimal32  <i>y</i>);
        decimal64  nextafterd64  (decimal64  <i>x</i>, decimal64  <i>y</i>);
        decimal128 nextafterd128 (decimal128 <i>x</i>, decimal128 <i>y</i>);

        decimal32  nexttowardd32  (decimal32  <i>x</i>, decimal32  <i>y</i>);
        decimal64  nexttowardd64  (decimal64  <i>x</i>, decimal64  <i>y</i>);
        decimal128 nexttowardd128 (decimal128 <i>x</i>, decimal128 <i>y</i>);

        // <i>maximum, minimum, and positive difference functions:</i>
        decimal32  fdimd32  (decimal32  <i>x</i>, decimal32  <i>y</i>);
        decimal64  fdimd64  (decimal64  <i>x</i>, decimal64  <i>y</i>);
        decimal128 fdimd128 (decimal128 <i>x</i>, decimal128 <i>y</i>);

        decimal32  fmaxd32  (decimal32  <i>x</i>, decimal32  <i>y</i>);
        decimal64  fmaxd64  (decimal64  <i>x</i>, decimal64  <i>y</i>);
        decimal128 fmaxd128 (decimal128 <i>x</i>, decimal128 <i>y</i>);

        decimal32  fmind32  (decimal32  <i>x</i>, decimal32  <i>y</i>);
        decimal64  fmind64  (decimal64  <i>x</i>, decimal64  <i>y</i>);
        decimal128 fmind128 (decimal128 <i>x</i>, decimal128 <i>y</i>);

        // <i>floating multiply-add:</i>
        decimal32  fmad32  (decimal32  <i>x</i>, decimal32  <i>y</i>, decimal32  <i>z</i>);
        decimal64  fmad64  (decimal64  <i>x</i>, decimal64  <i>y</i>, decimal64  <i>z</i>);
        decimal128 fmad128 (decimal128 <i>x</i>, decimal128 <i>y</i>, decimal128  <i>z</i>);

        // <i>3.7.6.1</i> abs function overloads
        decimal32  abs(decimal32  <i>d</i>);
        decimal64  abs(decimal64  <i>d</i>);
        decimal128 abs(decimal128 <i>d</i>);
      } 
      }
</pre>

<h3>
3.7.2 <code>&lt;cmath></code> macros
</h3>
<pre>
        #define HUGE_VAL_D32       <b>implementation-defined</b>
</pre>
<blockquote>
<p>
<b>Expansion:</b> a positive lvalue of type <code>decimal32</code>.
</p>
</blockquote>
<pre>
        #define HUGE_VAL_D64       <b>implementation-defined</b>
</pre>
<blockquote>
<p>
<b>Expansion:</b> a positive lvalue of type <code>decimal64</code>, not necessarily representable as a <code>decimal32</code>.
</p>
</blockquote>
<pre>
        #define HUGE_VAL_128       <b>implementation-defined</b>
</pre>
<blockquote>
<p>
<b>Expansion:</b> a positive lvalue of type <code>decimal128</code>, not necessarily representable as a <code>decimal64</code>.
</p>
</blockquote>
<pre>
        #define DEC_INFINITY       <b>implementation-defined</b>
</pre>
<blockquote>
<p>
<b>Expansion:</b> an lvalue of type <code>decimal32</code> representing infinity.
</p>
</blockquote>
<pre>
        #define DEC_NAN            <b>implementation-defined</b>
</pre>
<blockquote>
<p>
<b>Expansion:</b> an lvalue of type <code>decimal32</code> representing quiet NaN.
</p>
</blockquote>
<pre>
        #define FP_FAST_FMAD32     <b>implementation-defined</b>
        #define FP_FAST_FMAD64     <b>implementation-defined</b>
        #define FP_FAST_FMAD128    <b>implementation-defined</b>
</pre>
<blockquote>
<p>
<b>Effects:</b> these macros are, respectively, <code>decimal32</code>, <code>decimal64</code>, and <code>decimal128</code> analogs of <code>FP_FAST_FMA</code> in C99, subclause 7.12.
</p>
</blockquote>

<h3>
3.7.3 Evaluation formats
</h3>
<pre>
        typedef <i>decimal-floating-type</i> decimal32_t;
        typedef <i>decimal-floating-type</i> decimal64_t;
</pre>
<p>
The types <code>decimal32_t</code> and <code>decimal64_t</code> are decimal floating types at least as wide as <code>decimal32</code> and <code>decimal64</code>, respectively, and such that <code>decimal64_t</code> is at least as wide as <code>decimal32_t</code>.  If <code>DEC_EVAL_METHOD</code> equals 0, <code>decimal32_t</code> and <code>decimal64_t</code> are <code>decimal32</code> and <code>decimal64</code>, respectively; if <code>DEC_EVAL_METHOD</code> equals 1, they are both <code>decimal64</code>; if <code>DEC_EVAL_METHOD</code> equals 2, they are both <code>decimal128</code>; and for other values of <code>DEC_EVAL_METHOD</code>, they are otherwise implementation-defined.
</p>

<h3>
3.7.4 <code>samequantum</code> functions
</h3>
<pre>
        bool samequantumd32  (decimal32 <i>x</i>, decimal32 <i>y</i>);
        bool samequantumd64  (decimal64 <i>x</i>, decimal64 <i>y</i>);
        bool samequantumd128 (decimal128 <i>x</i>, decimal128 <i>y</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b> determines if the representation exponents of <i>x</i> and <i>y</i> are the same. If both <i>x</i> and <i>y</i> is NaN, or infinity, they have the same representation exponents; if exactly one operand is infinity or exactly one operand is NaN, they do not have the same representation exponents. The samequantum functions raise no exception.
</p>
<p>
<b>Returns:</b> <code>true</code> when <i>x</i> and <i>y</i> have the same representation exponents, <code>false</code> otherwise.
</p>
</blockquote>
<pre>
        bool samequantum (decimal32 <i>x</i>, decimal32 <i>y</i>);
</pre>
<blockquote>
<p>
<b>Returns:</b> <code>samequantumd32(<i>x</i>, <i>y</i>)</code>
</p>
</blockquote>
<pre>
        bool samequantum (decimal64 <i>x</i>, decimal64 <i>y</i>);
</pre>
<blockquote>
<p>
<b>Returns:</b> <code>samequantumd64(<i>x</i>, <i>y</i>)</code>
</p>
</blockquote>
<pre>
        bool samequantum (decimal128 <i>x</i>, decimal128 <i>y</i>);
</pre>
<blockquote>
<p>
<b>Returns:</b> <code>samequantumd128(<i>x</i>, <i>y</i>)</code>
</p>
</blockquote>

<h3>
3.7.5 <code>quantize</code> functions
</h3>
<pre>
        decimal32  quantized32  (decimal32 <i>x</i>, decimal32 <i>y</i>);
        decimal64  quantized64  (decimal64 <i>x</i>, decimal64 <i>y</i>);
        decimal128 quantized128 (decimal128 <i>x</i>, decimal128 <i>y</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b> sets the exponent of argument <i>x</i> to the exponent of argument <i>y</i>. If the exponent is being increased, the value is correctly rounded according to the current rounding mode; if the result does not have the same value as <i>x</i>, the "inexact" floating-point exception is raised. If the exponent is being decreased and the significand of the result has more digits than the type would allow, the "invalid" floating-point exception is raised and the result is NaN. If one or both operands are NaN the result is NaN. Otherwise if only one operand is infinity, the "invalid" floating-point exception is raised and the result is NaN. If both operands are infinity, the result is DEC_INFINITY. The quantize functions do not signal underflow. Whether the quantize functions signal overflow is implementation-defined.
</p>
<p>
<b>Returns:</b> the number which is equal in value (except for any rounding) and sign to <i>x</i>, and which has an exponent set to be equal to the exponent of <i>y</i>.
</p>
</blockquote>
<pre>
        decimal32  quantize (decimal32 <i>x</i>, decimal32 <i>y</i>);
</pre>
<blockquote>
<p>
<b>Returns:</b> <code>quantized32(<i>x</i>, <i>y</i>)</code>
</p>
</blockquote>
<pre>
        decimal64  quantize (decimal64 <i>x</i>, decimal64 <i>y</i>);
</pre>
<blockquote>
<p>
<b>Returns:</b> <code>quantized64(<i>x</i>, <i>y</i>)</code>
</p>
</blockquote>
<pre>
        decimal128 quantize (decimal128 <i>x</i>, decimal128 <i>y</i>);
</pre>
<blockquote>
<p>
<b>Returns:</b> <code>quantized128(<i>x</i>, <i>y</i>)</code>
</p>
</blockquote>

<h3>
3.7.6 Elementary functions
</h3> 
<p>
For each of the following standard elementary functions from <code>&lt;cmath></code>,
</p>
<pre>
   acos    ceil   floor   log     sin    tanh
   asin    cos    fmod    log10   sinh 
   atan    cosh   frexp   modf    sqrt
   atan2   fabs   ldexp   pow     tan
</pre>
<p>
and for each of the following TR1 elementary functions from <code>&lt;cmath></code>:
</p>
<pre>
   acosh      expm1    llround     nexttoward
   asinh      fdim     lrint       remainder
   atanh      fma      lround      remquo
   cbrt       fmax     log1p       rint
   copysign   fmin     log2        round
   erf        hypot    logb        scalbn
   erfc       ilogb    nan         scalbln
   exp        lgamma   nearbyint   tgamma
   exp2       llrint   nextafter   trunc
</pre>

<ul>
<li>an additional function is introduced to the namespace <code>std::dfp</code> with the name <i>func</i><code>d32</code>, where <i>func</i> is the name of the original function; all parameters of type <code>double</code> in the original are replaced with type <code>decimal32</code> in the new function; all parameters of type <code>double *</code> are replaced with type <code>decimal32 *</code>; if the return type of the original function is <code>double</code>, the return type of the new function is <code>decimal32</code>; the specification of the behavior of the new function is otherwise equivalent to that of the original function</li>

<li>an additional overload of the original function <i>func</i> is introduced to the namespace in which the original is declared; apart from its name and nearest enclosing namespace, this function has the same signature, return type, and behavior as the function <i>func</i><code>d32</code>, described above</li>

<li>an additional function is introduced to the namespace <code>std::dfp</code> with the name <i>func</i><code>d64</code>, where <i>func</i> is the name of the original function; all parameters of type <code>double</code> in the original are replaced with type <code>decimal64</code> in the new function; all parameters of type <code>double *</code> are replaced with type <code>decimal64 *</code>; if the return type of the original function is <code>double</code>, the return type of the new function is <code>decimal64</code>; the specification of the behavior of the new function is otherwise equivalent to that of the original function</li>

<li>an additional overload of the original function <i>func</i> is introduced to the namespace in which the original is declared; apart from its name and nearest enclosing namespace, this function has the same signature, return type, and behavior as the function <i>func</i><code>d64</code>, described above</li>

<li>an additional function is introduced to the namespace <code>std::dfp</code> with the name <i>func</i><code>d128</code>, where <i>func</i> is the name of the original function; all parameters of type <code>double</code> in the original are replaced with type <code>decimal128</code> in the new function; all parameters of type <code>double *</code> are replaced with type <code>decimal128 *</code>; if the return type of the original function is <code>double</code>, the return type of the new function is <code>decimal128</code>; the specification of the behavior of the new function is otherwise equivalent to that of the original function</li>

<li>an additional overload of the original function <i>func</i> is introduced to the namespace in which the original is declared; apart from its name and nearest enclosing namespace, this function has the same signature, return type, and behavior as the function <i>func</i><code>d128</code>, described above</li>
</ul>

<p>Moreover, there shall be additional overloads of the original function <i>func</i>, declared in <i>func</i>'s namespace, sufficient to ensure:</p>
<ol>
<li>If any argument corresponding to a <code>decimal64</code> parameter has type <code>decimal128</code>, then all arguments of decimal floating-point type or integer type corresponding to <code>decimal64</code> parameters are effectively cast to <code>decimal128</code>.</li>

<li>Otherwise, if any argument corresponding to a <code>decimal64</code> parameter has type <code>decimal64</code>, then all other arguments of decimal floating-type or integer-type corresponding to <code>decimal64</code> parameters are effectively cast to <code>decimal64</code>.</li>

<li>Otherwise, if any argument corresponding to a <code>decimal64</code> parameter has type <code>decimal32</code>, then all other arguments of decimal floating-type or integer-type corresponding to <code>decimal64</code> parameters are effectively cast to <code>decimal32</code>.</li>
</ol>

<p>
[<i>Editor's note</i>:  The combination of TR1 8.16.4/4 and the above dictates that the first argument to the following function call should be converted to type <code>double</code>: <code>pow(decimal64(), double())</code>.  However, there is no implicit conversion from <code>decimal64</code> to <code>double</code>, so the function call will be ill-formed.  I view this as a good thing.]
</p>

<h3>
3.7.6.1 <code>abs</code> function overloads
</h3>
<pre>
        decimal32  abs(decimal32  <i>d</i>);
        decimal64  abs(decimal64  <i>d</i>);
        decimal128 abs(decimal128 <i>d</i>);
</pre>
<blockquote>
<p>
<b>Returns:</b> <code>fabs(<i>d</i>)</code>
</p>
</blockquote>

<h3>
3.7.7 Changes to <code>&lt;math.h></code>
</h3> 
<p>
The header behaves as if it includes the header <code>&lt;cmath></code>, and provides sufficient additional <i>using</i> declarations to declare in the global namespace all the additional function and type names introduced by this Technical Report to the header <code>&lt;cmath></code>.
</p>
<h3>
3.7.7.1 Additions to header <code>&lt;math.h></code> synopsis
</h3>
<pre>
      // <i>C-compatibility convenience macros:</i>
      #define _Decimal32_t std::dfp::decimal32_t
      #define _Decimal64_t std::dfp::decimal64_t
</pre>

<h2>
3.8 Additions to <code>&lt;cstdio></code> and <code>&lt;stdio.h></code>
</h2>
<p>
This Technical Report introduces the following formatted input/output specifiers for <code>fprintf</code>, <code>fscanf</code>, and related functions declared in <code>&lt;cstdio></code> and <code>&lt;stdio.h></code>:
</p>
<pre>
      H  Specifies that any following e, E, f, F, g, or G conversions specifier applies to a decimal32 argument.
      D  Specifies that any following e, E, f, F, g, or G conversions specifier applies to a decimal64 argument.
      DD Specifies that any following e, E, f, F, g, or G conversions specifier applies to a decimal128 argument.
</pre>

<h2>
3.9 Additions to <code>&lt;cstdlib></code> and <code>&lt;stdlib.h></code>
</h2>
<h3>
3.9.1 Additions to header <code>&lt;cstdlib></code> synopsis
</h3>
<pre>
      namespace std {
      namespace dfp {
        // <i>3.9.2 strtod functions:</i>
        decimal32  strtod32  (const char * <i>nptr</i>, char ** <i>endptr</i>);
        decimal64  strtod64  (const char * <i>nptr</i>, char ** <i>endptr</i>);
        decimal128 strtod128 (const char * <i>nptr</i>, char ** <i>endptr</i>);
      }
      }
</pre>
<h3>
3.9.2 <code>strtod</code> functions
</h3>
<p>
These functions behave as specified in subclause 9.4 of ISO/IEC TR 24732.
</p>
<h3>
3.9.3 Changes to <code>&lt;stdlib.h></code>
</h3> 
<p>
Each name placed into the namespace <code>dfp</code> by <code>&lt;cstdlib></code> is placed into both the namespace <code>dfp</code> and the global namespace by <code>&lt;stdlib.h></code>.
</p>
<h2>
3.10 Additions to <code>&lt;cwchar></code> and <code>&lt;wchar.h></code>
</h2>
<h3>
3.10.1 Additions to <code>&lt;cwchar></code> synopsis
</h3>
<pre>
      namespace std {
      namespace dfp {
        // <i>3.10.2 wcstod functions:</i>
        decimal32  wcstod32  (const char * <i>nptr</i>, char ** <i>endptr</i>);
        decimal64  wcstod64  (const char * <i>nptr</i>, char ** <i>endptr</i>);
        decimal128 wcstod128 (const char * <i>nptr</i>, char ** <i>endptr</i>);
      }
      }
</pre>
<h3>
3.10.2 <code>wcstod</code> functions
</h3>
<p>
These functions behave as specified in subclause 9.5 of ISO/IEC TR 24732.
</p>
<h3>
3.10.3 Changes to <code>&lt;wchar.h></code>
</h3> 
<p>
Each name placed into the namespace <code>dfp</code> by <code>&lt;cwchar></code> is placed into both the namespace <code>dfp</code> and the global namespace by <code>&lt;wchar.h></code>.
</p>

<h2>
3.11 Facets 
</h2>
<p>
This Technical Report introduces the locale facet templates <code>extended_num_get</code> and <code>extended_num_put</code>.  For any locale <code><i>loc</i></code> either constructed, or returned by <code>locale::classic()</code>, and any facet <code><i>Facet</i></code> that is one of the required instantiations indicated in Table 3, <code>std::has_facet&lt;<i>Facet</i>>(<i>loc</i>)</code> is <code>true</code>.  Each <code>std::locale</code> member function that has a parameter <code><i>cat</i></code> of type <code>std::locale::category</code> operates on the these facets when <code><i>cat</i> &amp; std::locale::numeric != 0</code>.
</p>
<h4>Table 3 -- Extended Category Facets</h4>
<table border="1">
<tr>
<td>
Category
</td>
<td>
Facets
</td>
</tr>
<tr>
<td>
<code>numeric</code>
</td>
<td>
<code>extended_num_get&lt;char></code>, <code>extended_num_get&lt;wchar_t></code><br />
<code>extended_num_get&lt;char></code>, <code>extended_num_put&lt;wchar_t></code>
</td>
</tr>
</table>

<h3>
3.11.1 Additions to header <code>&lt;locale></code> synopsis
</h3>
<pre>
      namespace std {
      namespace dfp {

        // <i>3.11.2 extended_num_get facet:</i>
        template &lt;class charT, class InputIterator>  class extended_num_get;

        // <i>3.11.3 extended_num_put facet:</i>
        template &lt;class charT, class OutputIterator> class extended_num_put;
      }
      }
</pre>
<h3>
3.11.2 Class template <code>extended_num_get</code>
</h3>
<pre>
      namespace std {
      namespace dfp {

        template &lt;class charT, class InputIterator = std::istreambuf_iterator&lt;charT, std::char_traits&lt;charT> > >
        class extended_num_get : public std::locale::facet {
          public:
            typedef charT char_type;
            typedef InputIterator iter_type;

            explicit extended_num_get(size_t <i>refs</i> = 0);
            extended_num_get(const std::num_get&lt;charT, InputIterator> &amp; <i>b</i>, size_t <i>refs</i> = 0);

            iter_type get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                          std::ios_base::iostate &amp; <i>err</i>, decimal32 &amp; <i>val</i>) const;
            iter_type get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                          std::ios_base::iostate &amp; <i>err</i>, decimal64 &amp; <i>val</i>) const;
            iter_type get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                          std::ios_base::iostate &amp; <i>err</i>, decimal128 &amp; <i>val</i>) const;

            iter_type get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                          std::ios_base::iostate &amp; <i>err</i>, bool &amp; <i>val</i>) const;
            iter_type get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                          std::ios_base::iostate &amp; <i>err</i>, long &amp; <i>val</i>) const;
            iter_type get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                          std::ios_base::iostate &amp; <i>err</i>, unsigned short &amp; <i>val</i>) const;
            iter_type get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                          std::ios_base::iostate &amp; <i>err</i>, unsigned int &amp; <i>val</i>) const;
            iter_type get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                          std::ios_base::iostate &amp; <i>err</i>, unsigned long &amp; <i>val</i>) const;
            iter_type get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                          std::ios_base::iostate &amp; <i>err</i>, float &amp; <i>val</i>) const;
            iter_type get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                          std::ios_base::iostate &amp; <i>err</i>, double &amp; <i>val</i>) const;
            iter_type get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                          std::ios_base::iostate &amp; <i>err</i>, long double &amp; <i>val</i>) const;
            iter_type get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                          std::ios_base::iostate &amp; <i>err</i>, void * &amp; <i>val</i>) const;

            static std::locale::id id;

          protected:
            ~extended_num_get(); // <i>virtual</i>

            virtual iter_type do_get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                                     std::ios_base::iostate &amp; <i>err</i>, const decimal32 &amp; <i>val</i>) const;
            virtual iter_type do_get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                                     std::ios_base::iostate &amp; <i>err</i>, const decimal64 &amp; <i>val</i>) const;
            virtual iter_type do_get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                                     std::ios_base::iostate &amp; <i>err</i>, const decimal128 &amp; <i>val</i>) const;

            // <i>const std::num_get&lt;charT, InputIterator> &amp; <b>base</b></i>;        <i><b>exposition only</b></i>
        };
      }
      }
</pre>
<h3>
3.11.2.1 <code>extended_num_get</code> members
</h3>
<pre>
      explicit extended_num_get(size_t <i>refs</i> = 0);
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an <code>extended_num_get</code> facet as if by:
</p>
<pre>
        typedef std::num_get&lt;charT, InputIterator> <i>base_type</i>;
        explicit extended_num_get(size_t <i>refs</i> = 0)
                : facet(<i>refs</i>), <i>base</i>(std::use_facet&lt;<i>base_type</i>>(std::locale())
                { /* ... */ }
</pre>
<p>
<b>Notes:</b> Care must be taken to ensure that the lifetime of the facet referenced by <i>base</i> exceeds that of the resulting <code>extended_num_get</code> facet.
</p>
</blockquote>

<pre>
        extended_num_get(std::num_get&lt;charT, InputIterator> &amp; <i>b</i>, size_t <i>refs</i> = 0);
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an <code>extended_num_get</code> facet as if by:
</p>
<pre>
        extended_num_get(const std::num_get&lt;charT, InputIterator> &amp; <i>b</i>, size_t <i>refs</i> = 0)
                : facet(<i>refs</i>), <i>base</i>(<i>b</i>)
                { /* ... */ }
</pre>
<p>
<b>Notes:</b> Care must be taken to ensure that the lifetime of the facet referenced by <i>base</i> exceeds that of the resulting <code>extended_num_get</code> facet.
</p>
</blockquote>

<pre>
      iter_type get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                    std::ios_base::iostate &amp; <i>err</i>, const decimal32 &amp; <i>val</i>) const;
      iter_type get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                    std::ios_base::iostate &amp; <i>err</i>, const decimal64 &amp; <i>val</i>) const;
      iter_type get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                    std::ios_base::iostate &amp; <i>err</i>, const decimal128 &amp; <i>val</i>) const;
</pre>
<blockquote>
<p>
<b>Returns:</b> <code>do_get(<i>in</i>, <i>end</i>, <i>str</i>, <i>err</i>, <i>val</i>)</code>.
</p>
</blockquote>

<pre>
      iter_type get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                    std::ios_base::iostate &amp; <i>err</i>, bool &amp; <i>val</i>) const;
      iter_type get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                    std::ios_base::iostate &amp; <i>err</i>, long &amp; <i>val</i>) const;
      iter_type get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                    std::ios_base::iostate &amp; <i>err</i>, unsigned short &amp; <i>val</i>) const;
      iter_type get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                    std::ios_base::iostate &amp; <i>err</i>, unsigned int &amp; <i>val</i>) const;
      iter_type get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                    std::ios_base::iostate &amp; <i>err</i>, unsigned long &amp; <i>val</i>) const;
      iter_type get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                    std::ios_base::iostate &amp; <i>err</i>, float &amp; <i>val</i>) const;
      iter_type get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                    std::ios_base::iostate &amp; <i>err</i>, double &amp; <i>val</i>) const;
      iter_type get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                    std::ios_base::iostate &amp; <i>err</i>, long double &amp; <i>val</i>) const;
      iter_type get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                    std::ios_base::iostate &amp; <i>err</i>, void * &amp; <i>val</i>) const;
</pre>
<blockquote>
<p>
<b>Returns:</b> <code><i>base</i>.get(<i>in</i>, <i>end</i>, <i>str</i>, <i>err</i>, <i>val</i>)</code>.
</p>
</blockquote>

<h3>
3.11.2.2 <code>extended_num_get</code> virtual functions 
</h3>
<pre>
      iter_type do_get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                  std::ios_base::iostate &amp; <i>err</i>, const decimal32 &amp; <i>val</i>) const;
      iter_type do_get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                  std::ios_base::iostate &amp; <i>err</i>, const decimal64 &amp; <i>val</i>) const;
      iter_type do_get(iter_type <i>in</i>, iter_type <i>end</i>, std::ios_base &amp; <i>str</i>,
                  std::ios_base::iostate &amp; <i>err</i>, const decimal128 &amp; <i>val</i>) const;
</pre>
<blockquote>
<p>
<b>Effects:</b> The input characters will be interpreted as described in [lib.facet.num.get.virtuals], and the resulting value will be stored in <i>val</i>.  For conversions to type decimal32, decimal64, and decimal128, the conversion specifiers are <code>%gHD</code>, <code>%gD</code>, and <code>%gLD</code>, respectively.
</p>
<p>
<b>Returns:</b> <i>in</i>.
</p>
</blockquote>

<h3>
3.11.3 Class template <code>extended_num_put</code>
</h3>
<pre>
      namespace std {
      namespace dfp {
        template &lt;class charT, class OutputIterator = std::ostreambuf_iterator&lt;charT, std::char_traits&lt;charT> > >
        class extended_num_put : public std::locale::facet {
          public:
            typedef charT char_type;
            typedef OutputIterator iter_type;

            explicit extended_num_put(size_t <i>refs</i> = 0);
            extended_num_put(const std::num_put&lt;charT, OutputIterator> &amp; <i>b</i>, size_t <i>refs</i> = 0);

            iter_type put(iter_type <i>s</i>, ios_base &amp; <i>f</i>, char_type <i>fill</i>, const decimal32 &amp; <i>val</i>) const;
            iter_type put(iter_type <i>s</i>, ios_base &amp; <i>f</i>, char_type <i>fill</i>, const decimal64 &amp; <i>val</i>) const;
            iter_type put(iter_type <i>s</i>, ios_base &amp; <i>f</i>, char_type <i>fill</i>, const decimal128 &amp; <i>val</i>) const;

            iter_type put(iter_type <i>s</i>, ios_base &amp; <i>f</i>, char_type <i>fill</i>, bool <i>val</i>) const;
            iter_type put(iter_type <i>s</i>, ios_base &amp; <i>f</i>, char_type <i>fill</i>, long <i>val</i>) const;
            iter_type put(iter_type <i>s</i>, ios_base &amp; <i>f</i>, char_type <i>fill</i>, unsigned long <i>val</i>) const;
            iter_type put(iter_type <i>s</i>, ios_base &amp; <i>f</i>, char_type <i>fill</i>, double <i>val</i>) const;
            iter_type put(iter_type <i>s</i>, ios_base &amp; <i>f</i>, char_type <i>fill</i>, long double <i>val</i>) const;
            iter_type put(iter_type <i>s</i>, ios_base &amp; <i>f</i>, char_type <i>fill</i>, const void * <i>val</i>) const;

            static std::locale::id id;

          protected:
            ~extended_num_put();             // <i>virtual</i>

            virtual iter_type do_put(iter_type <i>s</i>, ios_base &amp; <i>f</i>, char_type <i>fill</i>, const decimal32 &amp; <i>val</i>) const;
            virtual iter_type do_put(iter_type <i>s</i>, ios_base &amp; <i>f</i>, char_type <i>fill</i>, const decimal64 &amp; <i>val</i>) const;
            virtual iter_type do_put(iter_type <i>s</i>, ios_base &amp; <i>f</i>, char_type <i>fill</i>, const decimal128 &amp; <i>val</i>) const;

            // <i>const std::num_put&lt;charT, OutputIterator> &amp; <b>base</b></i>;       <i><b>exposition only</b></i>
        };
      }
      }
</pre>
<h3>
3.11.3.1 <code>extended_num_put</code> members
</h3>
<pre>
      explicit extended_num_put(size_t <i>refs</i> = 0);
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an <code>extended_num_put</code> facet as if by:
</p>
<pre>
        typedef std::num_put&lt;charT, OutputIterator> <i>base_type</i>;
        explicit extended_num_put(size_t <i>refs</i> = 0)
                : facet(<i>refs</i>), <i>base</i>(std::use_facet&lt;<i>base_type</i>>(std::locale())
                { /* ... */ }
</pre>
<p>
<b>Notes:</b> Care must be taken to ensure that the lifetime of the facet referenced by <i>base</i> exceeds that of the resulting <code>extended_num_put</code> facet.
</p>
</blockquote>

<pre>
        extended_num_put(std::num_put&lt;charT, InputIterator> &amp; <i>b</i>, size_t <i>refs</i> = 0);
</pre>
<blockquote>
<p>
<b>Effects:</b> Constructs an <code>extended_num_put</code> facet as if by:
</p>
<pre>
        extended_num_put(const std::num_put&lt;charT, InputIterator> &amp; <i>b</i>, size_t <i>refs</i> = 0)
                : facet(<i>refs</i>), <i>base</i>(<i>b</i>)
                { /* ... */ }
</pre>
<p>
<b>Notes:</b> Care must be taken to ensure that the lifetime of the facet referenced by <i>base</i> exceeds that of the resulting <code>extended_num_put</code> facet.
</p>
</blockquote>

<pre>
        iter_type put(iter_type <i>s</i>, ios_base &amp; <i>f</i>, char_type <i>fill</i>, const decimal32 &amp; <i>val</i>) const;
        iter_type put(iter_type <i>s</i>, ios_base &amp; <i>f</i>, char_type <i>fill</i>, const decimal64 &amp; <i>val</i>) const;
        iter_type put(iter_type <i>s</i>, ios_base &amp; <i>f</i>, char_type <i>fill</i>, const decimal128 &amp; <i>val</i>) const;
</pre>
<blockquote>
<p>
<b>Returns:</b> <code>do_put(<i>s</i>, <i>f</i>, <i>fill</i>, <i>val</i>)</code>.
</p>
</blockquote>

<pre>
        iter_type put(iter_type <i>s</i>, ios_base &amp; <i>f</i>, char_type <i>fill</i>, bool <i>val</i>) const;
        iter_type put(iter_type <i>s</i>, ios_base &amp; <i>f</i>, char_type <i>fill</i>, long <i>val</i>) const;
        iter_type put(iter_type <i>s</i>, ios_base &amp; <i>f</i>, char_type <i>fill</i>, unsigned long <i>val</i>) const;
        iter_type put(iter_type <i>s</i>, ios_base &amp; <i>f</i>, char_type <i>fill</i>, double <i>val</i>) const;
        iter_type put(iter_type <i>s</i>, ios_base &amp; <i>f</i>, char_type <i>fill</i>, long double <i>val</i>) const;
        iter_type put(iter_type <i>s</i>, ios_base &amp; <i>f</i>, char_type <i>fill</i>, const void * <i>val</i>) const;
</pre>
<blockquote>
<p>
<b>Returns:</b> <code><i>base</i>.put(<i>s</i>, <i>f</i>, <i>fill</i>, <i>val</i>)</code>.
</p>
</blockquote>

<h3>
3.11.3.2 <code>extended_num_put</code> virtual functions 
</h3>
<pre>
        virtual iter_type do_put(iter_type <i>s</i>, ios_base &amp; <i>f</i>, char_type <i>fill</i>, const decimal32 &amp; <i>val</i>) const;
        virtual iter_type do_put(iter_type <i>s</i>, ios_base &amp; <i>f</i>, char_type <i>fill</i>, const decimal64 &amp; <i>val</i>) const;
        virtual iter_type do_put(iter_type <i>s</i>, ios_base &amp; <i>f</i>, char_type <i>fill</i>, const decimal128 &amp; <i>val</i>) const;
</pre>
<blockquote>
<p>
<b>Effects:</b> The number represented by <i>val</i> will be formatted for output as described in [lib.facet.num.put.virtuals].  A length modifier is added to the conversion specifier as indicated in Table 4.
</p>

<h4>
Table 4 -- Length modifier
</h4>
<table border="1">
<tr>
<th>
type
</th>
<th>
length modifier
</th>
</tr>
<tr>
<td>
decimal32
</td>
<td>
HD
</td>
</tr>
<tr>
<td>
decimal64
</td>
<td>
D
</td>
</tr>
<tr>
<td>
decimal128
</td>
<td>
LD
</td>
</tr>
</table>

<p>
<b>Returns:</b> <i>out</i>.
</p>
</blockquote>

<h2>
3.12 Type traits
</h2>
<p>
The effect of the following type traits, when applied to any of the decimal floating-point types, is implementation-defined: 
</p>
<ul>
<li><code>std::tr1::is_arithmetic</code></li>
<li><code>std::tr1::is_fundamental</code></li>
<li><code>std::tr1::is_scalar</code></li>
<li><code>std::tr1::is_class</code></li>
</ul>
<p>
However, the following expression shall yield <code>true</code> where <i>dec</i> is one of <code>decimal32</code>, <code>decimal64</code>, or <code>decimal128</code>:
</p>
<pre>
  is_arithmetic&lt;<i>dec</i>>::value == is_fundamental&lt;<i>dec</i>>::value == is_scalar&lt;<i>dec</i>>::value == !is_class&lt;<i>dec</i>>::value
</pre>
<p>
[<em>Note:</em> The behavior of the type trait <code>std::tr1::is_floating_point</code> is not altered by this Technical Report. <em>--end note</em>]
</p>

<h3>
3.12.1 Addition to header <code>&lt;type_traits></code> synopsis
</h3>
<pre>
        namespace std {
        namespace dfp {
          // <i>3.12.2 is_decimal_floating_point type_trait:</i>
          template &lt;class T> struct is_decimal_floating_point; 
        }
        }
</pre>
<h3>
3.12.2 <code>is_decimal_floating_point</code> type_trait
</h3>
<p>
[<i>Editor's note:</i> an earlier draft of this document used the name <code>is_decimal_fp</code> for this type_trait.  Though it's longer, the current name was adopted for consistency with the TR1 <code>is_floating_point</code> type_trait.]
</p>
<p>
<code>is_decimal_floating_point</code> is a <i>UnaryTypeTrait</i> [tr.meta.rqmts] and satisfies all of the requirements of that category [tr.meta.requirements].
</p>

<h4>Table 5 -- Type Category Predicates</h4>
<table border="1">
<tr>
<th>
Template
</th>
<th>
Condition
</th>
<th>
Comments
</th>
</tr>
<tr>
<td>
<code>template &lt;class T><br/>struct is_decimal_floating_point;</code>
</td>
<td>
<code>T</code> is one of <code>decimal32</code>, <code>decimal64</code>, or <code>decimal128</code>
</td>
<td>
</td>
</tr>
</table>

<h2>
3.13 Hash functions
</h2>
<h3>
3.13.1 Additions to header <code>&lt;functional></code> synopsis
</h3>
<pre>
        namespace std {
        namespace tr1 {
          // <i>3.13.2 Hash function specializations:</i>
          template &lt;> struct hash&lt;dfp::decimal32>;
          template &lt;> struct hash&lt;dfp::decimal64>;
          template &lt;> struct hash&lt;dfp::decimal128>;
        }
        }
</pre>
<h3>
3.13.2 Hash function specializations
</h3>
<p>
In addition to the types indicated in [tr.unord.hash], the class template <code>hash</code> is required to be instantiable on the decimal floating-point types.
</p>
<h2>
3.14 Numeric conversion from strings
</h2>
<h3>
3.14.1 Additions to header <code>&lt;string></code> synopsis
</h3>
<pre>
        namespace std {
        namespace tr1 {
          // <i>3.14.2 Numeric conversions:</i>
          decimal32 stod32   (string &amp; <i>str</i>);
          decimal32 stod64   (string &amp; <i>str</i>);
          decimal32 stod128  (string &amp; <i>str</i>);
          string    to_string(const decimal128 &amp; <i>val</i>);
        }
        }
</pre>

<h3>
3.14.2 Numeric conversions
</h3>
<pre>
        decimal32 stod32  (string &amp; <i>str</i>);
        decimal32 stod64  (string &amp; <i>str</i>);
        decimal32 stod128 (string &amp; <i>str</i>);
</pre>
<blockquote>
<p>
<b>Effects:</b> the functions call <code>strtod32(str.c_str())</code>,
<code>strtod64(str.c_str())</code>, and
<code>strtod128(str.c_str())</code>, respectively.  Each function returns the converted result, if any, and erases the characters from the front of <code>str</code> that were converted to get the result. 
</p>
<p>
<b>Returns:</b> the converted result.
</p>
<p>
<b>Throws:</b> <code>invalid_argument</code> if <code>strtod32</code>, <code>strtod64</code>, or <code>strtod128</code> reports that no conversion could be performed.  Throws <code>out_of_range</code> if <code>strtod32</code>, <code>strtod64</code>, or <code>strtod128</code> sets <code>errno</code> to <code>ERANGE</code>.
</p>
</blockquote>
<pre>
        string to_string(const decimal128 &amp; <i>val</i>);
</pre>
<blockquote>
<p>
<b>Returns:</b> a <code>string</code> object holding the character representation of the value of its argument that would be generated by calling <code>sprintf(<i>buf</i>, <i>fmt</i>, <i>val</i>)</code> with a format specifier of <code>"%LD"</code>.
</p>
<p>
<b>Throws:</b> nothing.
</p>
</blockquote>

<h2>
4 Notes on C compatibility
</h2>
<p>
One of the goals of the design of the decimal floating-point types that are the subject of this Technical Report is to minimize incompatibility with the C decimal floating types; however, differences between the C and C++ languages make some incompatibilty inevitable.  Differences between the C and C++ decimal types -- and techniques for overcoming them -- are described in this section.
</p>
<h2>
4.1 Use of <code>&lt;decfloat.h></code>
</h2>
<p>
To aid portability to C++, it is recommended that C programmers <code>#include</code> the header file <code>&lt;decfloat.h></code> in those translation units that make use of the decimal floating types.  This ensures that the equivalent C++ floating-point types will be available, should the program source be ported to C++. 
</p>
<h2>
4.2 Literals
</h2>
<p>
Literals of decimal floating-point type are not introduced to the C++ language by this Technical Report, though implementations may support them as a conforming extension.  C programs that use decimal floating-point literals will not be portable to a C++ implementation that does not support this extension.
</p>
<h2>
4.3 Conversions
</h2>
<p>
In C, objects of decimal floating-point type can be converted to generic floating-point type by means of an explicit cast.  In C++ this is not possible.  Instead, the functions <code>decimal_to_long_double</code>, <code>decimal32_to_long_double</code>, <code>decimal64_to_long_double</code>, and <code>decimal128_to_long_double</code> should be used for this purpose.  C programmers who wish to maintain portability to C++ should use the <code>decimal32_to_long_double</code>, <code>decimal64_to_long_double</code>, and <code>decimal128_to_long_double</code> forms instead of the cast notation.
</p>
<p>
{<i>Editor's note:</i> there's another issue that I believe requires further discussion.  Currently, decimal values that are within the range of an <code>unsigned long long</code> but not within the range of a <code>long long</code> cannot be accurately converted to integral type in C++, though accurate conversion is possible in C.]
</p>
</body>
</html>
