[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