This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[libstdc++] decimal float support (take 2)
- From: Janis Johnson <janis187 at us dot ibm dot com>
- To: libstdc++ at gcc dot gnu dot org, bkoz at redhat dot com
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Wed, 30 Sep 2009 16:00:06 -0700
- Subject: [libstdc++] decimal float support (take 2)
- Reply-to: janis187 at us dot ibm dot com
Here's an updated version of the C++ support for decimal floating-point
arithmetic as defined in ISO/IEC TR 24733. There aren't many changes
from the version I sent out Monday except that the files have moved,
both in the source and the install tree, to include/tr24733 and there
is now documentation. The documentation isn't yet fully tested since
I'm still strugging with the generation tools, and I haven't done a
full build and test run with the new headers.
As shown in the status chart this only covers basic functionality in
the decimal header file, not formatted input/output or support for
facets, type traits, hash functions, and numeric_limits.
Tests are coming in a separate patch. I'd like to get this in for 4.5.
What changes are needed (with full testing) before it can go in as an
experimental feature?
2009-09-30 Janis Johnson <janis187@us.ibm.com>
* doc/Makefile.am: Process new file.
* doc/Makefile.in: Regenerate.
* 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/Makefile.in: Regenerate.
* include/tr24733/decimal: New file.
* include/tr24733/decimal.h: New file.
Index: libstdc++-v3/doc/Makefile.am
===================================================================
--- libstdc++-v3/doc/Makefile.am (revision 152344)
+++ 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 152344)
+++ 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 152344)
+++ 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 152344)
+++ 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,473 @@
+// <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 exponent);
+ static decimal32 make_decimal32 (unsigned long long coeff, int exponent);
+ static decimal64 make_decimal64 (long long coeff, int exponent);
+ static decimal64 make_decimal64 (unsigned long long coeff, int exponent);
+ static decimal128 make_decimal128 (long long coeff, int exponent);
+ static decimal128 make_decimal128 (unsigned long long coeff, int exponent);
+
+ /// 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.1 Construct/copy/destroy.
+ decimal32() : __val(0.e-101DF) {}
+
+ // ISO/IEC TR 24733 3.2.2.2 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.3 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.4 Conversion to integral type.
+ //operator long long () const { return (long long)__val; }
+
+ // ISO/IEC TR 24733 3.2.2.5 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.6 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.1 Construct/copy/destroy.
+ decimal64() : __val(0.e-398dd) {}
+
+ // ISO/IEC TR 24733 3.2.3.2 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.3 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.4 Conversion to integral type.
+ //operator long long() const { return (long long)__val; }
+
+ // ISO/IEC TR 24733 3.2.3.5 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.6 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.1 Construct/copy/destroy.
+ decimal128() : __val(0.e-6176DL) {}
+
+ // ISO/IEC TR 24733 3.2.4.2 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.3 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.4 Conversion to integral type.
+ //operator long long() const { return (long long)__val; }
+
+ // ISO/IEC TR 24733 3.2.4.5 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.6 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,518 @@
+// 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 */