[libstdc++] decimal float support (take 3)

Janis Johnson janis187@us.ibm.com
Thu Oct 1 17:21:00 GMT 2009


Here's the libstdc++ patch again, updated for suggestions from Paolo
Carlini for formatting and uglified function parameters.  It also
fixes some section references to TR 24733.

With the submission on Monday I mentioned that this patch does not
support an implicit conversion to integral types (long long) from each
of the decimal classes.  Those are in the patch, commented out and with
a comment that now says (DISABLED).  If those are not disabled then all
of the error checks in the bad-*.cc tests fail.  I can't see how to
allow implicit conversions to long long while also prohibiting bitwise
operations with decimal floating-point operands or conversions and
casts to generic floating-point types.

If the documentation says that the decimal header is supported when the
C++ compiler supports scalar decimal floating-point arithmetic via types
defined with __attribute((mode(SD|DD|TD))), is it OK if the header is
always installed?

There are several parts of TR 24733 that are not yet implemented, and I
have questions about some of those.  What's a good forum for discussing
those?

2009-10-01  Janis Johnson  <janis187@us.ibm.com>

	* doc/Makefile.am: Process new file.
	* doc/xml/manual/intro.xml: Ditto.
	* doc/xml/manual/using.xml: Document new header.
	* doc/xml/manual/status_cxxtr24733.xml: New file.
	* include/Makefile.am: Process new headers.
	* include/tr24733/decimal: New file.
	* include/tr24733/decimal.h: New file.

Index: libstdc++-v3/doc/Makefile.am
===================================================================
--- libstdc++-v3/doc/Makefile.am	(revision 152380)
+++ libstdc++-v3/doc/Makefile.am	(working copy)
@@ -106,6 +106,7 @@ xml_sources = \
 	${xml_srcdir}/manual/status_cxx1998.xml \
 	${xml_srcdir}/manual/status_cxx200x.xml \
 	${xml_srcdir}/manual/status_cxxtr1.xml \
+	${xml_srcdir}/manual/status_cxxtr24733.xml \
 	${xml_srcdir}/manual/strings.xml \
 	${xml_srcdir}/manual/support.xml \
 	${xml_srcdir}/manual/test.xml \
Index: libstdc++-v3/doc/xml/manual/intro.xml
===================================================================
--- libstdc++-v3/doc/xml/manual/intro.xml	(revision 152380)
+++ libstdc++-v3/doc/xml/manual/intro.xml	(working copy)
@@ -44,6 +44,11 @@
     <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" 
 		parse="xml" href="status_cxx200x.xml">
     </xi:include>    
+
+    <!-- Section 01.4 : Status C++ TR24733 -->
+    <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" 
+		parse="xml" href="status_cxxtr24733.xml">
+    </xi:include>
   </sect1>
 
   <!-- Section 02 : License -->
Index: libstdc++-v3/doc/xml/manual/using.xml
===================================================================
--- libstdc++-v3/doc/xml/manual/using.xml	(revision 152380)
+++ libstdc++-v3/doc/xml/manual/using.xml	(working copy)
@@ -556,6 +556,24 @@ mode, i.e. <literal>-std=c++0x</literal>
 </tgroup>
 </table>
 
+<para>Decimal floating-point arithmetic is available if the C++
+compiler supports scalar decimal floating-point types defined via
+<code>__attribute__((mode(SD|DD|LD)))</code>.
+</para>
+
+<table frame='all'>
+<title>TR 24733 Header for Decimal Floating-Point</title>
+<tgroup cols='2' align='left' colsep='1' rowsep='1'>
+<colspec colname='c1'></colspec>
+<colspec colname='c2'></colspec>
+<tbody>
+<row>
+<entry><filename class="headerfile">tr24733/decimal</filename></entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+
     </sect2>
 
     <sect2 id="manual.intro.using.headers.mixing" xreflabel="Mixing Headers">
Index: libstdc++-v3/doc/xml/manual/status_cxxtr24733.xml
===================================================================
--- libstdc++-v3/doc/xml/manual/status_cxxtr24733.xml	(revision 0)
+++ libstdc++-v3/doc/xml/manual/status_cxxtr24733.xml	(revision 0)
@@ -0,0 +1,299 @@
+<sect2 id="status.iso.tr24733" xreflabel="Status C++ TR24733">
+<?dbhtml filename="status_iso_cxxtr24733.html"?>
+ 
+<sect2info>
+  <keywordset>
+    <keyword>
+      TR 24733
+    </keyword>
+  </keywordset>
+</sect2info>
+
+<title>C++ TR 24733</title>
+
+<para>
+This table is based on the table of contents of
+ISO/IEC TR 24733 Date: 2009-08-28
+Extension for the programming language C++ to support
+decimal floating-point arithmetic
+</para>
+
+<para>
+This page describes the TR 24733 support in mainline GCC SVN, not in any
+particular release.
+</para>
+
+<!-- Status is Yes or No, Broken/Partial-->
+<!-- 
+   Yes
+
+   No 
+      <?dbhtml bgcolor="#C8B0B0" ?>
+   Broken/Partial 
+      <?dbhtml bgcolor="#B0B0B0" ?>
+-->
+<table frame='all'>
+<title>C++ TR 24733 Implementation Status</title>
+<tgroup cols='4' align='left' colsep='0' rowsep='1'>
+<colspec colname='c1'></colspec>
+<colspec colname='c2'></colspec>
+<colspec colname='c3'></colspec>
+<colspec colname='c4'></colspec>
+  <thead>
+    <row>
+      <entry>Section</entry>
+      <entry>Description</entry>
+      <entry>Status</entry>
+      <entry>Comments</entry>
+    </row>
+  </thead>
+
+  <tbody>
+    <row>
+      <entry>
+	<emphasis>0</emphasis>
+      </entry>
+      <entry namest="c2" nameend="c4" align="left">
+	<emphasis>Introduction</emphasis>
+      </entry>
+    </row>
+
+    <row>
+      <entry>
+	<emphasis>1</emphasis>
+      </entry>
+      <entry namest="c2" nameend="c4" align="left">
+	<emphasis>Normative references</emphasis>
+      </entry>
+    </row>
+
+    <row>
+      <entry>
+	<emphasis>2</emphasis>
+      </entry>
+      <entry namest="c2" nameend="c4" align="left">
+	<emphasis>Conventions</emphasis>
+      </entry>
+    </row>
+
+    <row>
+      <entry>
+	<emphasis>3</emphasis>
+      </entry>
+      <entry namest="c2" nameend="c4" align="left">
+	<emphasis>Decimal floating-point types</emphasis>
+      </entry>
+    </row>
+
+    <row>
+      <entry>3.1</entry>
+      <entry>Characteristics of decimal floating-point types</entry>
+      <entry></entry>
+      <entry></entry>
+    </row>
+    <row>
+      <entry>3.2</entry>
+      <entry>Decimal Types</entry>
+      <entry></entry>
+      <entry></entry>
+    </row>
+    <row>
+      <?dbhtml bgcolor="#B0B0B0" ?>
+      <entry>3.2.1</entry>
+      <entry>Class <code>decimal</code> synopsis</entry>
+      <entry>Partial</entry>
+      <entry>Missing declarations for formatted input/output; non-conforming extension for functions converting to integral type</entry>
+    </row>
+    <row>
+      <?dbhtml bgcolor="#B0B0B0" ?>
+      <entry>3.2.2</entry>
+      <entry>Class <code>decimal32</code></entry>
+      <entry>Partial</entry>
+      <entry>Missing 3.2.2.5 conversion to integral type; conforming extension for conversion from scalar decimal floating-point</entry>
+    </row>
+    <row>
+      <?dbhtml bgcolor="#B0B0B0" ?>
+      <entry>3.2.3</entry>
+      <entry>Class <code>decimal64</code></entry>
+      <entry>Partial</entry>
+      <entry>Missing 3.2.3.5 conversion to integral type; conforming extension for conversion from scalar decimal floating-point</entry>
+    </row>
+    <row>
+      <?dbhtml bgcolor="#B0B0B0" ?>
+      <entry>3.2.4</entry>
+      <entry>Class <code>decimal128</code></entry>
+      <entry>Partial</entry>
+      <entry>Missing 3.2.4.5 conversion to integral type; conforming extension for conversion from scalar decimal floating-point</entry>
+    </row>
+    <row>
+      <entry>3.2.5</entry>
+      <entry>Initialization from coefficient and exponent</entry>
+      <entry>Y</entry>
+      <entry></entry>
+    </row>
+    <row>
+      <entry>3.2.6</entry>
+      <entry>Conversion to generic floating-point type</entry>
+      <entry>Y</entry>
+      <entry></entry>
+    </row>
+    <row>
+      <entry>3.2.7</entry>
+      <entry>Unary arithmetic operators</entry>
+      <entry>Y</entry>
+      <entry></entry>
+    </row>
+    <row>
+      <entry>3.2.8</entry>
+      <entry>Binary arithmetic operators</entry>
+      <entry>Y</entry>
+      <entry></entry>
+    </row>
+    <row>
+      <entry>3.2.9</entry>
+      <entry>Comparison operators</entry>
+      <entry>Y</entry>
+      <entry></entry>
+    </row>
+    <row>
+      <?dbhtml bgcolor="#C8B0B0" ?>
+      <entry>3.2.10</entry>
+      <entry>Formatted input</entry>
+      <entry>N</entry>
+      <entry></entry>
+    </row>
+    <row>
+      <?dbhtml bgcolor="#C8B0B0" ?>
+      <entry>3.2.11</entry>
+      <entry>Formatted output</entry>
+      <entry>N</entry>
+      <entry></entry>
+    </row>
+    <row>
+      <?dbhtml bgcolor="#C8B0B0" ?>
+      <entry>3.3</entry>
+      <entry>Additions to header <code>limits</code></entry>
+      <entry>N</entry>
+      <entry></entry>
+    </row>
+    <row>
+      <entry>3.4</entry>
+      <entry>Headers <code>cfloat</code> and <code>float.h</code></entry>
+      <entry></entry>
+      <entry></entry>
+    </row>
+    <row>
+      <entry>3.4.2</entry>
+      <entry>Additions to header <code>cfloat</code> synopsis</entry>
+      <entry>Y</entry>
+      <entry></entry>
+    </row>
+    <row>
+      <?dbhtml bgcolor="#B0B0B0" ?>
+      <entry>3.4.3</entry>
+      <entry>Additions to header <code>float.h</code> synopsis</entry>
+      <entry>N</entry>
+      <entry></entry>
+    </row>
+    <row>
+      <entry>3.4.4</entry>
+      <entry>Maximum finite value</entry>
+      <entry>Y</entry>
+      <entry></entry>
+    </row>
+    <row>
+      <entry>3.4.5</entry>
+      <entry>Epsilon</entry>
+      <entry>Y</entry>
+      <entry></entry>
+    </row>
+    <row>
+      <entry>3.4.6</entry>
+      <entry>Minimum positive normal value</entry>
+      <entry>Y</entry>
+      <entry></entry>
+    </row>
+    <row>
+      <entry>3.4.7</entry>
+      <entry>Minimum positive subnormal value</entry>
+      <entry>Y</entry>
+      <entry></entry>
+    </row>
+    <row>
+      <entry>3.4.8</entry>
+      <entry>Evaluation format</entry>
+      <entry>Y</entry>
+      <entry></entry>
+    </row>
+    <row>
+      <?dbhtml bgcolor="#C8B0B0" ?>
+      <entry>3.5</entry>
+      <entry>Additions to <code>cfenv</code> and <code>fenv.h</code></entry>
+      <entry>Outside the scope of GCC</entry>
+      <entry></entry>
+    </row>
+    <row>
+      <?dbhtml bgcolor="#C8B0B0" ?>
+      <entry>3.6</entry>
+      <entry>Additions to <code>cmath</code> and <code>math.h</code></entry>
+      <entry>Outside the scope of GCC</entry>
+      <entry></entry>
+    </row>
+    <row>
+      <?dbhtml bgcolor="#C8B0B0" ?>
+      <entry>3.7</entry>
+      <entry>Additions to <code>cstdio</code> and <code>stdio.h</code></entry>
+      <entry>Outside the scope of GCC</entry>
+      <entry></entry>
+    </row>
+    <row>
+      <?dbhtml bgcolor="#C8B0B0" ?>
+      <entry>3.8</entry>
+      <entry>Additions to <code>cstdlib</code> and <code>stdlib.h</code></entry>
+      <entry>Outside the scope of GCC</entry>
+      <entry></entry>
+    </row>
+    <row>
+      <?dbhtml bgcolor="#C8B0B0" ?>
+      <entry>3.9</entry>
+      <entry>Additions to <code>cwchar</code> and <code>wchar.h</code></entry>
+      <entry>Outside the scope of GCC</entry>
+      <entry></entry>
+    </row>
+    <row>
+      <?dbhtml bgcolor="#C8B0B0" ?>
+      <entry>3.10</entry>
+      <entry>Facets</entry>
+      <entry>N</entry>
+      <entry></entry>
+    </row>
+    <row>
+      <?dbhtml bgcolor="#C8B0B0" ?>
+      <entry>3.11</entry>
+      <entry>Type traits</entry>
+      <entry>N</entry>
+      <entry></entry>
+    </row>
+    <row>
+      <?dbhtml bgcolor="#C8B0B0" ?>
+      <entry>3.12</entry>
+      <entry>Hash functions</entry>
+      <entry>N</entry>
+      <entry></entry>
+    </row>
+
+    <row>
+      <entry>
+	<emphasis>4</emphasis>
+      </entry>
+      <entry namest="c2" nameend="c4" align="left">
+	<emphasis>Notes on C compatibility</emphasis>
+      </entry>
+    </row>
+
+  </tbody>
+</tgroup>
+</table>
+
+
+</sect2>
Index: libstdc++-v3/include/Makefile.am
===================================================================
--- libstdc++-v3/include/Makefile.am	(revision 152380)
+++ libstdc++-v3/include/Makefile.am	(working copy)
@@ -618,6 +618,12 @@ tr1_impl_headers = \
 	${tr1_impl_srcdir}/unordered_set \
 	${tr1_impl_srcdir}/utility
 
+tr24733_srcdir = ${glibcxx_srcdir}/include/tr24733
+tr24733_builddir = ./tr24733
+tr24733_headers = \
+	${tr24733_srcdir}/decimal \
+	${tr24733_srcdir}/decimal.h \
+
 
 # This is the common subset of C++ files that all three "C" header models use.
 c_base_srcdir = $(C_INCLUDE_DIR)
@@ -865,7 +871,8 @@ endif
 allstamped = \
 	stamp-std stamp-bits stamp-c_base stamp-c_base_extra \
 	stamp-c_compatibility  stamp-backward stamp-ext stamp-pb \
-	stamp-tr1 stamp-tr1-impl stamp-debug stamp-parallel stamp-host
+	stamp-tr1 stamp-tr1-impl stamp-tr24733 stamp-debug \
+	stamp-parallel stamp-host
 
 # List of all files that are created by explicit building, editing, or
 # catenation.
@@ -979,6 +986,11 @@ stamp-tr1-impl: ${tr1_impl_headers}
 	@-cd ${tr1_impl_builddir} && $(LN_S) $? . 2>/dev/null
 	@$(STAMP) stamp-tr1-impl
 
+stamp-tr24733: ${tr24733_headers}
+	@-mkdir -p ${tr24733_builddir}
+	@-cd ${tr24733_builddir} && $(LN_S) $? . 2>/dev/null
+	@$(STAMP) stamp-tr24733
+
 stamp-debug: ${debug_headers}
 	@-mkdir -p ${debug_builddir}
 	@-cd ${debug_builddir} && $(LN_S) $? . 2>/dev/null
@@ -1197,6 +1209,9 @@ install-headers:
 	$(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${tr1_impl_builddir}
 	for file in ${tr1_impl_headers}; do \
 	  $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${tr1_impl_builddir}; done
+	$(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${tr24733_builddir}
+	for file in ${tr24733_headers}; do \
+	  $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${tr24733_builddir}; done
 	$(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${c_base_builddir}
 	for file in ${c_base_headers}; do \
 	  $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${c_base_builddir}; done
@@ -1235,9 +1250,10 @@ clean-local:
 # directory. (This is more of an example of how this kind of rule can
 # be made.)
 .PRECIOUS: $(std_headers) $(c_base_headers) $(tr1_headers) $(tr1_impl_headers)
-	   $(ext_headers)
+	   $(tr24733_headers) $(ext_headers)
 $(std_headers): ; @:
 $(c_base_headers): ; @:
 $(tr1_headers): ; @:
 $(tr1_impl_headers): ; @:
+$(tr24733_headers): ; @:
 $(ext_headers): ; @:
Index: libstdc++-v3/include/tr24733/decimal
===================================================================
--- libstdc++-v3/include/tr24733/decimal	(revision 0)
+++ libstdc++-v3/include/tr24733/decimal	(revision 0)
@@ -0,0 +1,478 @@
+// <decimal> -*- C++ -*-
+
+// Copyright (C) 2009 Free Software Foundation, Inc.
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file include/tr24733/decimal
+ *  This is a Standard C++ Library header.
+ */
+
+// ISO/IEC TR 24733 
+// Written by Janis Johnson <janis187@us.ibm.com>
+
+#ifndef _GLIBCXX_DECIMAL
+#define _GLIBCXX_DECIMAL 1
+
+#pragma GCC system_header
+
+#include <bits/c++config.h>
+
+namespace std
+{
+  /**
+    * @defgroup decimal Decimal floating-point arithmetic.
+    * @ingroup numerics
+    *
+    * Classes and functions for decimal floating-point arithmetic.
+    * @{
+    */
+
+  /** @namespace std::decimal
+    * @brief ISO/IEC TR 24733 Decimal floating-point arithmetic.
+    */
+namespace decimal
+{
+
+  class decimal32;
+  class decimal64;
+  class decimal128;
+
+  // ISO/IEC TR 24733  3.2.5  Initialization from coefficient and exponent.
+  static decimal32 make_decimal32(long long __coeff, int __exp);
+  static decimal32 make_decimal32(unsigned long long __coeff, int __exp);
+  static decimal64 make_decimal64(long long __coeff, int __exp);
+  static decimal64 make_decimal64(unsigned long long __coeff, int __exp);
+  static decimal128 make_decimal128(long long __coeff, int __exp);
+  static decimal128 make_decimal128(unsigned long long __coeff, int __exp);
+
+  /// Non-conforming extension: Conversion to integral type.
+  long long decimal32_to_long_long(decimal32 __d);
+  long long decimal64_to_long_long(decimal64 __d);
+  long long decimal128_to_long_long(decimal128 __d);
+  long long decimal_to_long_long(decimal32 __d);
+  long long decimal_to_long_long(decimal64 __d);
+  long long decimal_to_long_long(decimal128 __d);
+
+  // ISO/IEC TR 24733  3.2.6  Conversion to generic floating-point type.
+  float decimal32_to_float(decimal32 __d);
+  float decimal64_to_float(decimal64 __d);
+  float decimal128_to_float(decimal128 __d);
+  float decimal_to_float(decimal32 __d);
+  float decimal_to_float(decimal64 __d);
+  float decimal_to_float(decimal128 __d);
+
+  double decimal32_to_double(decimal32 __d);
+  double decimal64_to_double(decimal64 __d);
+  double decimal128_to_double(decimal128 __d);
+  double decimal_to_double(decimal32 __d);
+  double decimal_to_double(decimal64 __d);
+  double decimal_to_double(decimal128 __d);
+
+  long double decimal32_to_long_double(decimal32 __d);
+  long double decimal64_to_long_double(decimal64 __d);
+  long double decimal128_to_long_double(decimal128 __d);
+  long double decimal_to_long_double(decimal32 __d);
+  long double decimal_to_long_double(decimal64 __d);
+  long double decimal_to_long_double(decimal128 __d);
+
+  // ISO/IEC TR 24733  3.2.7  Unary arithmetic operators.
+  decimal32  operator+(decimal32 __rhs);
+  decimal64  operator+(decimal64 __rhs);
+  decimal128 operator+(decimal128 __rhs);
+  decimal32  operator-(decimal32 __rhs);
+  decimal64  operator-(decimal64 __rhs);
+  decimal128 operator-(decimal128 __rhs);
+
+  // ISO/IEC TR 24733  3.2.8  Binary arithmetic operators.
+#define _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(_Op, _T1, _T2, _T3)	\
+  _T1 operator _Op(_T2 lhs, _T3 __rhs);
+#define _DECLARE_DECIMAL_BINARY_OP_WITH_INT(_Op, _Tp)		\
+  _Tp operator _Op(_Tp lhs, int __rhs);				\
+  _Tp operator _Op(_Tp lhs, unsigned int __rhs);		\
+  _Tp operator _Op(_Tp lhs, long __rhs);			\
+  _Tp operator _Op(_Tp lhs, unsigned long __rhs);		\
+  _Tp operator _Op(_Tp lhs, long long __rhs);			\
+  _Tp operator _Op(_Tp lhs, unsigned long long __rhs);		\
+  _Tp operator _Op(int lhs, _Tp __rhs);				\
+  _Tp operator _Op(unsigned int lhs, _Tp __rhs);		\
+  _Tp operator _Op(long lhs, _Tp __rhs);			\
+  _Tp operator _Op(unsigned long lhs, _Tp __rhs);		\
+  _Tp operator _Op(long long lhs, _Tp __rhs);			\
+  _Tp operator _Op(unsigned long long lhs, _Tp __rhs);
+
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal32, decimal32, decimal32)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_INT(+, decimal32)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal64, decimal32, decimal64)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal64, decimal64, decimal32)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal64, decimal64, decimal64)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_INT(+, decimal64)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal32, decimal128)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal64, decimal128)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal128, decimal32)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal128, decimal64)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal128, decimal128)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_INT(+, decimal128)
+
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal32, decimal32, decimal32)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_INT(-, decimal32)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal64, decimal32, decimal64)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal64, decimal64, decimal32)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal64, decimal64, decimal64)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_INT(-, decimal64)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal32, decimal128)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal64, decimal128)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal128, decimal32)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal128, decimal64)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal128, decimal128)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_INT(-, decimal128)
+
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal32, decimal32, decimal32)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_INT(*, decimal32)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal64, decimal32, decimal64)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal64, decimal64, decimal32)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal64, decimal64, decimal64)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_INT(*, decimal64)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal32, decimal128)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal64, decimal128)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal128, decimal32)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal128, decimal64)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal128, decimal128)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_INT(*, decimal128)
+
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal32, decimal32, decimal32)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_INT(/, decimal32)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal64, decimal32, decimal64)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal64, decimal64, decimal32)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal64, decimal64, decimal64)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_INT(/, decimal64)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal32, decimal128)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal64, decimal128)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal128, decimal32)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal128, decimal64)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal128, decimal128)
+  _DECLARE_DECIMAL_BINARY_OP_WITH_INT(/, decimal128)
+
+#undef _DECLARE_DECIMAL_BINARY_OP_WITH_DEC
+#undef _DECLARE_DECIMAL_BINARY_OP_WITH_INT
+
+  // ISO/IEC TR 24733  3.2.9  Comparison operators.
+#define _DECLARE_DECIMAL_COMPARISON(_Op, _T)				\
+  bool operator _Op(_T lhs, decimal32  _rhs);				\
+  bool operator _Op(_T lhs, decimal64  _rhs);				\
+  bool operator _Op(_T lhs, decimal128  _rhs);				\
+  bool operator _Op(_T lhs, int  _rhs);					\
+  bool operator _Op(_T lhs, unsigned int  _rhs);			\
+  bool operator _Op(_T lhs, long  _rhs);				\
+  bool operator _Op(_T lhs, unsigned long  _rhs);			\
+  bool operator _Op(_T lhs, long long  _rhs);				\
+  bool operator _Op(_T lhs, unsigned long long  _rhs);			\
+  bool operator _Op(int lhs, _T  _rhs);					\
+  bool operator _Op(unsigned int lhs, _T  _rhs);			\
+  bool operator _Op(long lhs, _T  _rhs);				\
+  bool operator _Op(unsigned long lhs, _T  _rhs);			\
+  bool operator _Op(long long lhs, _T  _rhs);				\
+  bool operator _Op(unsigned long long lhs, _T  _rhs);
+
+  _DECLARE_DECIMAL_COMPARISON(==, decimal32)
+  _DECLARE_DECIMAL_COMPARISON(==, decimal64)
+  _DECLARE_DECIMAL_COMPARISON(==, decimal128)
+
+  _DECLARE_DECIMAL_COMPARISON(!=, decimal32)
+  _DECLARE_DECIMAL_COMPARISON(!=, decimal64)
+  _DECLARE_DECIMAL_COMPARISON(!=, decimal128)
+
+  _DECLARE_DECIMAL_COMPARISON(<, decimal32)
+  _DECLARE_DECIMAL_COMPARISON(<, decimal64)
+  _DECLARE_DECIMAL_COMPARISON(<, decimal128)
+
+  _DECLARE_DECIMAL_COMPARISON(>=, decimal32)
+  _DECLARE_DECIMAL_COMPARISON(>=, decimal64)
+  _DECLARE_DECIMAL_COMPARISON(>=, decimal128)
+
+  _DECLARE_DECIMAL_COMPARISON(>, decimal32)
+  _DECLARE_DECIMAL_COMPARISON(>, decimal64)
+  _DECLARE_DECIMAL_COMPARISON(>, decimal128)
+
+  _DECLARE_DECIMAL_COMPARISON(>=, decimal32)
+  _DECLARE_DECIMAL_COMPARISON(>=, decimal64)
+  _DECLARE_DECIMAL_COMPARISON(>=, decimal128)
+
+#undef _DECLARE_DECIMAL_COMPARISON
+
+  // ISO/IEC TR 24733  3.2.2  Class decimal32.
+  class decimal32
+  {
+  public:
+    typedef float __decfloat32 __attribute__((mode(SD)));
+
+    // ISO/IEC TR 24733  3.2.2.2  Construct/copy/destroy.
+    decimal32()					: __val(0.e-101DF) {}
+
+    // ISO/IEC TR 24733  3.2.2.3  Conversion from floating-point type.
+    explicit decimal32(decimal64 __d64);
+    explicit decimal32(decimal128 __d128);
+    explicit decimal32(float __r)		: __val(__r) {}
+    explicit decimal32(double __r)		: __val(__r) {}
+    explicit decimal32(long double __r)		: __val(__r) {}
+
+    // ISO/IEC TR 24733  3.2.2.4  Conversion from integral type.
+    decimal32(int __z)				: __val(__z) {}
+    decimal32(unsigned int __z)			: __val(__z) {}
+    decimal32(long __z)				: __val(__z) {}
+    decimal32(unsigned long __z)		: __val(__z) {}
+    decimal32(long long __z)			: __val(__z) {}
+    decimal32(unsigned long long __z)		: __val(__z) {}
+
+    /// Conforming extension: Conversion from scalar decimal type.
+    decimal32(__decfloat32 __z)			: __val(__z) {}
+
+    // ISO/IEC TR 24733  3.2.2.5  Conversion to integral type. (DISABLED)
+    //operator long long() const { return (long long)__val; }
+
+    // ISO/IEC TR 24733  3.2.2.6  Increment and decrement operators.
+    decimal32& operator++()
+    {
+      __val += 1;
+      return *this;
+    }
+
+    decimal32 operator++(int)
+    {
+      decimal32 __tmp = *this;
+      __val += 1;
+      return __tmp;
+    }
+
+    decimal32& operator--()
+    {
+      __val -= 1;
+      return *this;
+    }
+
+    decimal32   operator--(int)
+    {
+      decimal32 __tmp = *this;
+      __val -= 1;
+      return __tmp;
+    }
+
+    // ISO/IEC TR 24733  3.2.2.7  Compound assignment.
+#define _DECLARE_DECIMAL32_COMPOUND_ASSIGNMENT(_Op)	\
+    decimal32& operator _Op(decimal32 __rhs);		\
+    decimal32& operator _Op(decimal64 __rhs);		\
+    decimal32& operator _Op(decimal128 __rhs);		\
+    decimal32& operator _Op(int __rhs);			\
+    decimal32& operator _Op(unsigned int __rhs);	\
+    decimal32& operator _Op(long __rhs);		\
+    decimal32& operator _Op(unsigned long __rhs);	\
+    decimal32& operator _Op(long long __rhs);		\
+    decimal32& operator _Op(unsigned long long __rhs);
+
+    _DECLARE_DECIMAL32_COMPOUND_ASSIGNMENT(+=)
+    _DECLARE_DECIMAL32_COMPOUND_ASSIGNMENT(-=)
+    _DECLARE_DECIMAL32_COMPOUND_ASSIGNMENT(*=)
+    _DECLARE_DECIMAL32_COMPOUND_ASSIGNMENT(/=)
+#undef _DECLARE_DECIMAL32_COMPOUND_ASSIGNMENT
+
+  private:
+    __decfloat32 __val;
+
+  public:
+    __decfloat32 __getval(void) { return __val; }
+    void __setval(__decfloat32 __x) { __val = __x; }
+  };
+
+  // ISO/IEC TR 24733  3.2.3  Class decimal64.
+  class decimal64
+  {
+  public:
+    typedef float __decfloat64 __attribute__((mode(DD)));
+
+    // ISO/IEC TR 24733  3.2.3.2  Construct/copy/destroy.
+    decimal64()					: __val(0.e-398dd) {}
+
+    // ISO/IEC TR 24733  3.2.3.3  Conversion from floating-point type.
+	     decimal64(decimal32 d32);
+    explicit decimal64(decimal128 d128);
+    explicit decimal64(float __r)		: __val(__r) {}
+    explicit decimal64(double __r)		: __val(__r) {}
+    explicit decimal64(long double __r)		: __val(__r) {}
+
+    // ISO/IEC TR 24733  3.2.3.4  Conversion from integral type.
+    decimal64(int __z)				: __val(__z) {}
+    decimal64(unsigned int __z)			: __val(__z) {}
+    decimal64(long __z)				: __val(__z) {}
+    decimal64(unsigned long __z)		: __val(__z) {}
+    decimal64(long long __z)			: __val(__z) {}
+    decimal64(unsigned long long __z)		: __val(__z) {}
+
+    /// Conforming extension: Conversion from scalar decimal type.
+    decimal64(__decfloat64 __z)			: __val(__z) {}
+
+    // ISO/IEC TR 24733  3.2.3.5  Conversion to integral type. (DISABLED)
+    //operator long long() const { return (long long)__val; }
+
+    // ISO/IEC TR 24733  3.2.3.6  Increment and decrement operators.
+    decimal64& operator++()
+    {
+      __val += 1;
+      return *this;
+    }
+
+    decimal64 operator++(int)
+    {
+      decimal64 __tmp = *this;
+      __val += 1;
+      return __tmp;
+    }
+
+    decimal64& operator--()
+    {
+      __val -= 1;
+      return *this;
+    }
+
+    decimal64 operator--(int)
+    {
+      decimal64 __tmp = *this;
+      __val -= 1;
+      return __tmp;
+    }
+
+    // ISO/IEC TR 24733  3.2.3.7  Compound assignment.
+#define _DECLARE_DECIMAL64_COMPOUND_ASSIGNMENT(_Op)	\
+    decimal64& operator _Op(decimal32 __rhs);		\
+    decimal64& operator _Op(decimal64 __rhs);		\
+    decimal64& operator _Op(decimal128 __rhs);		\
+    decimal64& operator _Op(int __rhs);			\
+    decimal64& operator _Op(unsigned int __rhs);	\
+    decimal64& operator _Op(long __rhs);		\
+    decimal64& operator _Op(unsigned long __rhs);	\
+    decimal64& operator _Op(long long __rhs);		\
+    decimal64& operator _Op(unsigned long long __rhs);
+
+    _DECLARE_DECIMAL64_COMPOUND_ASSIGNMENT(+=)
+    _DECLARE_DECIMAL64_COMPOUND_ASSIGNMENT(-=)
+    _DECLARE_DECIMAL64_COMPOUND_ASSIGNMENT(*=)
+    _DECLARE_DECIMAL64_COMPOUND_ASSIGNMENT(/=)
+#undef _DECLARE_DECIMAL64_COMPOUND_ASSIGNMENT
+
+  private:
+    __decfloat64 __val;
+
+  public:
+    __decfloat64 __getval(void) { return __val; }
+    void __setval(__decfloat64 __x) { __val = __x; }
+  };
+
+  // ISO/IEC TR 24733  3.2.4  Class decimal128.
+  class decimal128
+  {
+  public:
+    typedef float __decfloat128 __attribute__((mode(TD)));
+
+    // ISO/IEC TR 24733  3.2.4.2  Construct/copy/destroy.
+    decimal128()				: __val(0.e-6176DL) {}
+
+    // ISO/IEC TR 24733  3.2.4.3  Conversion from floating-point type.
+	     decimal128(decimal32 d32);
+	     decimal128(decimal64 d64);
+    explicit decimal128(float __r)		: __val(__r) {}
+    explicit decimal128(double __r)		: __val(__r) {}
+    explicit decimal128(long double __r)	: __val(__r) {}
+
+
+    // ISO/IEC TR 24733  3.2.4.4  Conversion from integral type.
+    decimal128(int __z)				: __val(__z) {}
+    decimal128(unsigned int __z)		: __val(__z) {}
+    decimal128(long __z)			: __val(__z) {}
+    decimal128(unsigned long __z)		: __val(__z) {}
+    decimal128(long long __z)			: __val(__z) {}
+    decimal128(unsigned long long __z)		: __val(__z) {}
+
+    /// Conforming extension: Conversion from scalar decimal type.
+    decimal128(__decfloat128 __z)		: __val(__z) {}
+
+    // ISO/IEC TR 24733  3.2.4.5  Conversion to integral type. (DISABLED)
+    //operator long long() const { return (long long)__val; }
+
+    // ISO/IEC TR 24733  3.2.4.6  Increment and decrement operators.
+    decimal128& operator++()
+    {
+      __val += 1;
+      return *this;
+    }
+
+    decimal128 operator++(int)
+    {
+      decimal128 __tmp = *this;
+      __val += 1;
+      return __tmp;
+    }
+
+    decimal128& operator--()
+    {
+      __val -= 1;
+      return *this;
+    }
+
+    decimal128   operator--(int)
+    {
+      decimal128 __tmp = *this;
+      __val -= 1;
+      return __tmp;
+    }
+
+    // ISO/IEC TR 24733  3.2.4.7  Compound assignment.
+#define _DECLARE_DECIMAL128_COMPOUND_ASSIGNMENT(_Op)	\
+    decimal128& operator _Op(decimal32 __rhs);		\
+    decimal128& operator _Op(decimal64 __rhs);		\
+    decimal128& operator _Op(decimal128 __rhs);		\
+    decimal128& operator _Op(int __rhs);		\
+    decimal128& operator _Op(unsigned int __rhs);	\
+    decimal128& operator _Op(long __rhs);		\
+    decimal128& operator _Op(unsigned long __rhs);	\
+    decimal128& operator _Op(long long __rhs);		\
+    decimal128& operator _Op(unsigned long long __rhs);
+
+    _DECLARE_DECIMAL128_COMPOUND_ASSIGNMENT(+=)
+    _DECLARE_DECIMAL128_COMPOUND_ASSIGNMENT(-=)
+    _DECLARE_DECIMAL128_COMPOUND_ASSIGNMENT(*=)
+    _DECLARE_DECIMAL128_COMPOUND_ASSIGNMENT(/=)
+#undef _DECLARE_DECIMAL128_COMPOUND_ASSIGNMENT
+
+  private:
+    __decfloat128 __val;
+
+  public:
+    __decfloat128 __getval(void) { return __val; }
+    void __setval(__decfloat128 __x) { __val = __x; }
+  };
+
+#define _GLIBCXX_USE_DECIMAL_ 1
+
+} // namespace decimal
+  // @} group decimal
+} // namespace std
+
+#include <tr24733/decimal.h>
+
+#endif /* _GLIBCXX_DECIMAL */
Index: libstdc++-v3/include/tr24733/decimal.h
===================================================================
--- libstdc++-v3/include/tr24733/decimal.h	(revision 0)
+++ libstdc++-v3/include/tr24733/decimal.h	(revision 0)
@@ -0,0 +1,520 @@
+// decimal classes -*- C++ -*-
+
+// Copyright (C) 2009 Free Software Foundation, Inc.
+
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/decimal.h
+ *  This is an internal header file, included by other library headers.
+ *  You should not attempt to use it directly.
+ */
+
+// ISO/IEC TR 24733
+// Written by Janis Johnson <janis187@us.ibm.com>
+
+#ifndef _GLIBCXX_DECIMAL_IMPL
+#define _GLIBCXX_DECIMAL_IMPL 1
+
+#pragma GCC system_header
+
+namespace std
+{
+namespace decimal
+{
+
+  // ISO/IEC TR 24733  3.2.[234].1  Construct/copy/destroy.
+
+  inline decimal32::decimal32(decimal64 r)	: __val(r.__getval()) {}
+  inline decimal32::decimal32(decimal128 r)	: __val(r.__getval()) {}
+  inline decimal64::decimal64(decimal32 r)	: __val(r.__getval()) {}
+  inline decimal64::decimal64(decimal128 r)	: __val(r.__getval()) {}
+  inline decimal128::decimal128(decimal32 r)	: __val(r.__getval()) {}
+  inline decimal128::decimal128(decimal64 r)	: __val(r.__getval()) {}
+
+  // ISO/IEC TR 24733  3.2.[234].6  Compound assignment.
+
+#define _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_DEC(_Op1, _Op2, _T1, _T2)	\
+  inline _T1& _T1::operator _Op1(_T2 __rhs)				\
+  {									\
+    __setval(__getval() _Op2 __rhs.__getval());				\
+    return *this;							\
+  }
+
+#define _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_INT(_Op1, _Op2, _T1, _T2)	\
+  inline _T1& _T1::operator _Op1(_T2 __rhs)				\
+  {									\
+    __setval(__getval() _Op2 __rhs);					\
+    return *this;							\
+  }
+
+#define _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(_O1, _O2, _T1)		\
+  _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_DEC(_O1,_O2,_T1, decimal32)	\
+  _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_DEC(_O1,_O2,_T1, decimal64)	\
+  _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_DEC(_O1,_O2,_T1, decimal128)	\
+  _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_INT(_O1,_O2,_T1, int)		\
+  _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_INT(_O1,_O2,_T1, unsigned int)	\
+  _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_INT(_O1,_O2,_T1, long)		\
+  _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_INT(_O1,_O2,_T1, unsigned long)	\
+  _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_INT(_O1,_O2,_T1, long long)	\
+  _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_INT(_O1,_O2,_T1, unsigned long long)
+
+  _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(+=, +, decimal32)
+  _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(-=, -, decimal32)
+  _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(*=, *, decimal32)
+  _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(/=, /, decimal32)
+
+  _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(+=, +, decimal64)
+  _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(-=, -, decimal64)
+  _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(*=, *, decimal64)
+  _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(/=, /, decimal64)
+
+  _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(+=, +, decimal128)
+  _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(-=, -, decimal128)
+  _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(*=, *, decimal128)
+  _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(/=, /, decimal128)
+
+#undef _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_DEC
+#undef _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_INT
+#undef _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS
+
+  // Extension: Conversion to integral type.
+
+  inline long long decimal32_to_long_long(decimal32 __d)
+  {
+    return (long long)__d.__getval();
+  }
+
+  inline long long decimal64_to_long_long(decimal64 __d)
+  {
+    return (long long)__d.__getval();
+  }
+
+  inline long long decimal128_to_long_long(decimal128 __d)
+  {
+    return (long long)__d.__getval();
+  }
+
+  inline long long decimal_to_long_long(decimal32 __d)
+  {
+    return (long long)__d.__getval();
+  }
+
+  inline long long decimal_to_long_long(decimal64 __d)
+  {
+    return (long long)__d.__getval();
+  }
+
+  inline long long decimal_to_long_long(decimal128 __d)
+  {
+    return (long long)__d.__getval();
+  }
+
+  // ISO/IEC TR 24733  3.2.5  Initialization from coefficient and exponent.
+
+  static decimal32 make_decimal32(long long __coeff, int __exponent)
+  {
+    decimal32 __decexp = 1, __multiplier;
+
+    if (__exponent < 0)
+      {
+	__multiplier = 1.E-1DF;
+	__exponent = -__exponent;
+      }
+    else
+      __multiplier = 1.E1DF;
+
+    for (int i = 0; i < __exponent; i++)
+      __decexp *= __multiplier;
+
+    return __coeff * __decexp;
+  }
+
+  static decimal32 make_decimal32(unsigned long long __coeff, int __exponent)
+  {
+    decimal32 __decexp = 1, __multiplier;
+
+    if (__exponent < 0)
+      {
+	__multiplier = 1.E-1DF;
+	__exponent = -__exponent;
+      }
+    else
+      __multiplier = 1.E1DF;
+
+    for (int i = 0; i < __exponent; i++)
+      __decexp *= __multiplier;
+
+    return __coeff * __decexp;
+  }
+
+  static decimal64 make_decimal64(long long __coeff, int __exponent)
+  {
+    decimal64 __decexp = 1, __multiplier;
+
+    if (__exponent < 0)
+      {
+	__multiplier = 1.E-1DD;
+	__exponent = -__exponent;
+      }
+    else
+      __multiplier = 1.E1DD;
+
+    for (int i = 0; i < __exponent; i++)
+      __decexp *= __multiplier;
+
+    return __coeff * __decexp;
+  }
+
+  static decimal64 make_decimal64(unsigned long long __coeff, int __exponent)
+  {
+    decimal64 __decexp = 1, __multiplier;
+
+    if (__exponent < 0)
+      {
+	__multiplier = 1.E-1DD;
+	__exponent = -__exponent;
+      }
+    else
+      __multiplier = 1.E1DD;
+
+    for (int i = 0; i < __exponent; i++)
+      __decexp *= __multiplier;
+
+    return __coeff * __decexp;
+  }
+
+  static decimal128 make_decimal128(long long __coeff, int __exponent)
+  {
+    decimal128 __decexp = 1, __multiplier;
+
+    if (__exponent < 0)
+      {
+	__multiplier = 1.E-1DL;
+	__exponent = -__exponent;
+      }
+    else
+      __multiplier = 1.E1DL;
+
+    for (int i = 0; i < __exponent; i++)
+      __decexp *= __multiplier;
+
+    return __coeff * __decexp;
+  }
+
+  static decimal128 make_decimal128(unsigned long long __coeff, int __exponent)
+  {
+    decimal128 __decexp = 1, __multiplier;
+
+    if (__exponent < 0)
+      {
+	__multiplier = 1.E-1DL;
+	__exponent = -__exponent;
+      }
+    else
+      __multiplier = 1.E1DL;
+
+    for (int i = 0; i < __exponent; i++)
+      __decexp *= __multiplier;
+
+    return __coeff * __decexp;
+  }
+
+  // ISO/IEC TR 24733  3.2.6  Conversion to generic floating-point type.
+
+  inline float decimal32_to_float(decimal32 __d)
+  {
+    return (float)__d.__getval();
+  }
+
+  inline float decimal64_to_float(decimal64 __d)
+  {
+    return (float)__d.__getval();
+  }
+
+  inline float decimal128_to_float(decimal128 __d)
+  {
+    return (float)__d.__getval();
+  }
+
+  inline float decimal_to_float(decimal32 __d)
+  {
+    return (float)__d.__getval();
+  }
+
+  inline float decimal_to_float(decimal64 __d)
+  {
+    return (float)__d.__getval();
+  }
+
+  inline float decimal_to_float(decimal128 __d)
+  {
+    return (float)__d.__getval();
+  }
+
+  inline double decimal32_to_double(decimal32 __d)
+  {
+    return (double)__d.__getval();
+  }
+
+  inline double decimal64_to_double(decimal64 __d)
+  {
+    return (double)__d.__getval();
+  }
+
+  inline double decimal128_to_double(decimal128 __d)
+  {
+    return (double)__d.__getval();
+  }
+
+  inline double decimal_to_double(decimal32 __d)
+  {
+    return (double)__d.__getval();
+  }
+
+  inline double decimal_to_double(decimal64 __d)
+  {
+    return (double)__d.__getval();
+  }
+
+  inline double decimal_to_double(decimal128 __d)
+  {
+    return (double)__d.__getval();
+  }
+
+  inline long double decimal32_to_long_double(decimal32 __d)
+  {
+    return (long double)__d.__getval();
+  }
+
+  inline long double decimal64_to_long_double(decimal64 __d)
+  {
+    return (long double)__d.__getval();
+  }
+
+  inline long double decimal128_to_long_double(decimal128 __d)
+  {
+    return (long double)__d.__getval();
+  }
+
+  inline long double decimal_to_long_double(decimal32 __d)
+  {
+    return (long double)__d.__getval();
+  }
+
+  inline long double decimal_to_long_double(decimal64 __d)
+  {
+    return (long double)__d.__getval();
+  }
+
+  inline long double decimal_to_long_double(decimal128 __d)
+  {
+    return (long double)__d.__getval();
+  }
+
+  // ISO/IEC TR 24733  3.2.7  Unary arithmetic operators.
+
+#define _DEFINE_DECIMAL_UNARY_OP(_Op, _T)	\
+  inline _T operator _Op(_T __rhs)		\
+  {						\
+    _T __tmp;					\
+    __tmp.__setval(0 _Op __rhs.__getval());	\
+    return __tmp;				\
+  }
+
+  _DEFINE_DECIMAL_UNARY_OP(+, decimal32)
+  _DEFINE_DECIMAL_UNARY_OP(+, decimal64)
+  _DEFINE_DECIMAL_UNARY_OP(+, decimal128)
+  _DEFINE_DECIMAL_UNARY_OP(-, decimal32)
+  _DEFINE_DECIMAL_UNARY_OP(-, decimal64)
+  _DEFINE_DECIMAL_UNARY_OP(-, decimal128)
+
+#undef _DEFINE_DECIMAL_UNARY_OP
+
+  // ISO/IEC TR 24733  3.2.8  Binary arithmetic operators.
+
+#define _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(_Op, _T1, _T2, _T3)	\
+  inline _T1 operator _Op(_T2 lhs, _T3 __rhs)			\
+  {								\
+    _T1 retval;							\
+    retval.__setval(lhs.__getval() _Op __rhs.__getval());	\
+    return retval;						\
+  }
+
+#define _DEFINE_DECIMAL_BINARY_OP_BOTH(_Op, _T1, _T2, _T3)	\
+  inline _T1 operator _Op(_T2 lhs, _T3 __rhs)			\
+  {								\
+    _T1 retval;							\
+    retval.__setval(lhs.__getval() _Op __rhs.__getval());	\
+    return retval;						\
+  }
+
+#define _DEFINE_DECIMAL_BINARY_OP_LHS(_Op, _T1, _T2)		\
+  inline _T1 operator _Op(_T1 lhs, _T2 __rhs)			\
+  {								\
+    _T1 retval;							\
+    retval.__setval(lhs.__getval() _Op __rhs);			\
+    return retval;						\
+  }
+
+#define _DEFINE_DECIMAL_BINARY_OP_RHS(_Op, _T1, _T2)		\
+  inline _T1 operator _Op(_T2 lhs, _T1 __rhs)			\
+  {								\
+    _T1 retval;							\
+    retval.__setval(lhs _Op __rhs.__getval());			\
+    return retval;						\
+  }
+
+#define _DEFINE_DECIMAL_BINARY_OP_WITH_INT(_Op,_Tp)		\
+  _DEFINE_DECIMAL_BINARY_OP_LHS(_Op,_Tp, int);			\
+  _DEFINE_DECIMAL_BINARY_OP_LHS(_Op,_Tp, unsigned int);		\
+  _DEFINE_DECIMAL_BINARY_OP_LHS(_Op,_Tp, long);			\
+  _DEFINE_DECIMAL_BINARY_OP_LHS(_Op,_Tp, unsigned long);	\
+  _DEFINE_DECIMAL_BINARY_OP_LHS(_Op,_Tp, long long);		\
+  _DEFINE_DECIMAL_BINARY_OP_LHS(_Op,_Tp, unsigned long long);	\
+  _DEFINE_DECIMAL_BINARY_OP_RHS(_Op,_Tp, int);			\
+  _DEFINE_DECIMAL_BINARY_OP_RHS(_Op,_Tp, unsigned int);		\
+  _DEFINE_DECIMAL_BINARY_OP_RHS(_Op,_Tp, long);			\
+  _DEFINE_DECIMAL_BINARY_OP_RHS(_Op,_Tp, unsigned long);	\
+  _DEFINE_DECIMAL_BINARY_OP_RHS(_Op,_Tp, long long);		\
+  _DEFINE_DECIMAL_BINARY_OP_RHS(_Op,_Tp, unsigned long long);	\
+
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal32, decimal32, decimal32)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_INT(+, decimal32)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal64, decimal32, decimal64)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal64, decimal64, decimal32)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal64, decimal64, decimal64)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_INT(+, decimal64)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal32, decimal128)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal64, decimal128)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal128, decimal32)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal128, decimal64)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal128, decimal128)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_INT(+, decimal128)
+
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal32, decimal32, decimal32)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_INT(-, decimal32)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal64, decimal32, decimal64)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal64, decimal64, decimal32)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal64, decimal64, decimal64)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_INT(-, decimal64)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal32, decimal128)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal64, decimal128)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal128, decimal32)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal128, decimal64)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal128, decimal128)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_INT(-, decimal128)
+
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal32, decimal32, decimal32)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_INT(*, decimal32)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal64, decimal32, decimal64)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal64, decimal64, decimal32)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal64, decimal64, decimal64)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_INT(*, decimal64)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal32, decimal128)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal64, decimal128)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal128, decimal32)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal128, decimal64)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal128, decimal128)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_INT(*, decimal128)
+
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal32, decimal32, decimal32)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_INT(/, decimal32)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal64, decimal32, decimal64)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal64, decimal64, decimal32)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal64, decimal64, decimal64)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_INT(/, decimal64)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal32, decimal128)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal64, decimal128)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal128, decimal32)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal128, decimal64)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal128, decimal128)
+  _DEFINE_DECIMAL_BINARY_OP_WITH_INT(/, decimal128)
+
+#undef _DEFINE_DECIMAL_BINARY_OP_WITH_DEC
+#undef _DEFINE_DECIMAL_BINARY_OP_BOTH
+#undef _DEFINE_DECIMAL_BINARY_OP_LHS
+#undef _DEFINE_DECIMAL_BINARY_OP_RHS
+#undef _DEFINE_DECIMAL_BINARY_OP_WITH_INT
+
+  // ISO/IEC TR 24733  3.2.9  Comparison operators.
+
+#define _DEFINE_DECIMAL_COMPARISON_BOTH(_Op, _T1, _T2)	\
+  inline bool operator _Op(_T1 lhs, _T2 __rhs)		\
+  {							\
+    return lhs.__getval() _Op __rhs.__getval();		\
+  }
+
+#define _DEFINE_DECIMAL_COMPARISON_LHS(_Op, _T1, _T2)	\
+  inline bool operator _Op(_T1 lhs, _T2 __rhs)		\
+  {							\
+    return lhs.__getval() _Op __rhs;			\
+  }
+#define _DEFINE_DECIMAL_COMPARISON_RHS(_Op, _T1, _T2)	\
+  inline bool operator _Op(_T1 lhs, _T2 __rhs)		\
+  {							\
+    return lhs _Op __rhs.__getval();			\
+  }
+
+#define _DEFINE_DECIMAL_COMPARISONS(_Op, _Tp)			\
+  _DEFINE_DECIMAL_COMPARISON_BOTH(_Op, _Tp, decimal32)		\
+  _DEFINE_DECIMAL_COMPARISON_BOTH(_Op, _Tp, decimal64)		\
+  _DEFINE_DECIMAL_COMPARISON_BOTH(_Op, _Tp, decimal128)		\
+  _DEFINE_DECIMAL_COMPARISON_LHS(_Op, _Tp, int)			\
+  _DEFINE_DECIMAL_COMPARISON_LHS(_Op, _Tp, unsigned int)	\
+  _DEFINE_DECIMAL_COMPARISON_LHS(_Op, _Tp, long)		\
+  _DEFINE_DECIMAL_COMPARISON_LHS(_Op, _Tp, unsigned long)	\
+  _DEFINE_DECIMAL_COMPARISON_LHS(_Op, _Tp, long long)		\
+  _DEFINE_DECIMAL_COMPARISON_LHS(_Op, _Tp, unsigned long long)	\
+  _DEFINE_DECIMAL_COMPARISON_RHS(_Op, int, _Tp)			\
+  _DEFINE_DECIMAL_COMPARISON_RHS(_Op, unsigned int, _Tp)	\
+  _DEFINE_DECIMAL_COMPARISON_RHS(_Op, long, _Tp)		\
+  _DEFINE_DECIMAL_COMPARISON_RHS(_Op, unsigned long, _Tp)	\
+  _DEFINE_DECIMAL_COMPARISON_RHS(_Op, long long, _Tp)		\
+  _DEFINE_DECIMAL_COMPARISON_RHS(_Op, unsigned long long, _Tp)
+
+  _DEFINE_DECIMAL_COMPARISONS(==, decimal32)
+  _DEFINE_DECIMAL_COMPARISONS(==, decimal64)
+  _DEFINE_DECIMAL_COMPARISONS(==, decimal128)
+  _DEFINE_DECIMAL_COMPARISONS(!=, decimal32)
+  _DEFINE_DECIMAL_COMPARISONS(!=, decimal64)
+  _DEFINE_DECIMAL_COMPARISONS(!=, decimal128)
+  _DEFINE_DECIMAL_COMPARISONS(<,  decimal32)
+  _DEFINE_DECIMAL_COMPARISONS(<,  decimal64)
+  _DEFINE_DECIMAL_COMPARISONS(<,  decimal128)
+  _DEFINE_DECIMAL_COMPARISONS(<=, decimal32)
+  _DEFINE_DECIMAL_COMPARISONS(<=, decimal64)
+  _DEFINE_DECIMAL_COMPARISONS(<=, decimal128)
+  _DEFINE_DECIMAL_COMPARISONS(>,  decimal32)
+  _DEFINE_DECIMAL_COMPARISONS(>,  decimal64)
+  _DEFINE_DECIMAL_COMPARISONS(>,  decimal128)
+  _DEFINE_DECIMAL_COMPARISONS(>=, decimal32)
+  _DEFINE_DECIMAL_COMPARISONS(>=, decimal64)
+  _DEFINE_DECIMAL_COMPARISONS(>=, decimal128)
+
+#undef _DEFINE_DECIMAL_COMPARISON_BOTH
+#undef _DEFINE_DECIMAL_COMPARISON_LHS
+#undef _DEFINE_DECIMAL_COMPARISON_RHS
+#undef _DEFINE_DECIMAL_COMPARISONS
+
+} // namespace decimal
+} // namespace std
+
+#endif /* _GLIBCXX_DECIMAL_IMPL */




More information about the Gcc-patches mailing list