Commit 2533577f by Janis Johnson Committed by Janis Johnson

Makefile.in (libdecnumber_a_OBJS): Remove decUtility.o

2007-09-10  Janis Johnson  <janis187@us.ibm.com>
	    Ben Elliston  <bje@au.ibm.com>

libdecnumber/
	* Makefile.in (libdecnumber_a_OBJS): Remove decUtility.o
	(dependencies): Add Symbols headers.
	* decContext.c: Upgrade to decNumber 3.53.
	* decContext.h: Ditto.
	* decDPD.h: Ditto.
	* decNumber.c: Ditto.
	* decNumber.h: Ditto.
	* decNumberLocal.h: Ditto.
	* decBasic.c: New file from decNumber 3.53.
	* decCommon.c: Ditto.
	* decDouble.c: Ditto.
	* decDouble.h: Ditto.
	* decQuad.c: Ditto.
	* decQuad.h: Ditto.
	* decSingle.c: Ditto.
	* decSingle.h: Ditto.
	* decPacked.c: Ditto.
	* decPacked.h: Ditto.
	* dpd/decimal128.c: Upgrade to decNumber 3.53.
	* dpd/decimal128.h: Ditto.
	* dpd/decimal32.c: Ditto.
	* dpd/decimal32.h: Ditto.
	* dpd/decimal64.c: Ditto.
	* dpd/decimal64.h: Ditto.
	* decLibrary.c (__dec_byte_swap): Remove.
	* decContextSymbols.h: New file.
	* decDoubleSymbols.h: New file.
	* decNumberSymbols.h: New file.
	* decPackedSymbols.h: New file.
	* decQuadSymbols.h: New file.
	* decSingleSymbols.h: New file.
	* decUtility.c: Delete file.
	* decUtility.h: Delete file.
	* bid/decimal128Symbols.h: New file.
	* bid/decimal128Local.h: New file.
	* bid/decimal32Symbols.h: New file.
	* bid/decimal64Symbols.h: New file.
	* bid/host-ieee128.c (__swap128): Remove.
	(__host_to_ieee_128, __ieee_to_host_128): Don't handle endianness.
	* bid/host-ieee32.c (__dec_type_swap): Remove.
	(__host_to_ieee_32, __ieee_to_host_32): Don't handle endianness.
	* bid/host-ieee64.c (__swap64): Remove.
	(__host_to_ieee_64, __ieee_to_host_64): Don't handle endianness.
	* dpd/decimal32Symbols.h: New file.
	* dpd/decimal64Symbols.h: New file.
	* dpd/decimal128Symbols.h: New file.
	* dpd/decimal128Local.h: New file.

libgcc/
	* Makefile.in (dfp-filenames): Remove decUtility, add
	decDouble, decPacked, decQuad, decSingle.

gcc/
	* dfp.c: Include decimal128Local.h; 
	(dfp_byte_swap): Remove.
	(encode_decimal32, decode_decimal32): Don't handle endianness.
	(encode_decimal64, decode_decimal64): Ditto.
	(encode_decimal128, decode_decimal128): Ditto.
	* config/dfp-bit.c (host_to_ieee32, ieee_to_host_32): Ditto.
	(__swap64): Remove.
	(host_to_ieee_64, ieee_to_host_64): Don't handle endianness.
         (__swap128): Remove
	(host_to_ieee_128, ieee_to_host_128): Don't handle endianness.
	* Makefile.in (DECNUM_H): Add decimal128Local.h.

Co-Authored-By: Ben Elliston <bje@au.ibm.com>

From-SVN: r128350
parent bfd9cff5
2007-09-10 Janis Johnson <janis187@us.ibm.com>
Ben Elliston <bje@au.ibm.com>
* dfp.c: Include decimal128Local.h;
(dfp_byte_swap): Remove.
(encode_decimal32, decode_decimal32): Don't handle endianness.
(encode_decimal64, decode_decimal64): Ditto.
(encode_decimal128, decode_decimal128): Ditto.
* config/dfp-bit.c (host_to_ieee32, ieee_to_host_32): Ditto.
(__swap64): Remove.
(host_to_ieee_64, ieee_to_host_64): Don't handle endianness.
(__swap128): Remove
(host_to_ieee_128, ieee_to_host_128): Don't handle endianness.
* Makefile.in (DECNUM_H): Add decimal128Local.h.
2007-09-10 David Daney <ddaney@avtrex.com> 2007-09-10 David Daney <ddaney@avtrex.com>
* config/mips/mips.md (UNSPEC_MEMORY_BARRIER): New entry in * config/mips/mips.md (UNSPEC_MEMORY_BARRIER): New entry in
...@@ -815,7 +815,8 @@ PREDICT_H = predict.h predict.def ...@@ -815,7 +815,8 @@ PREDICT_H = predict.h predict.def
CPPLIB_H = $(srcdir)/../libcpp/include/line-map.h \ CPPLIB_H = $(srcdir)/../libcpp/include/line-map.h \
$(srcdir)/../libcpp/include/cpplib.h $(srcdir)/../libcpp/include/cpplib.h
DECNUM_H = $(DECNUM)/decContext.h $(DECNUM)/decDPD.h $(DECNUM)/decNumber.h \ DECNUM_H = $(DECNUM)/decContext.h $(DECNUM)/decDPD.h $(DECNUM)/decNumber.h \
$(DECNUMFMT)/decimal32.h $(DECNUMFMT)/decimal64.h $(DECNUMFMT)/decimal128.h $(DECNUMFMT)/decimal32.h $(DECNUMFMT)/decimal64.h \
$(DECNUMFMT)/decimal128.h $(DECNUMFMT)/decimal128Local.h
MKDEPS_H = $(srcdir)/../libcpp/include/mkdeps.h MKDEPS_H = $(srcdir)/../libcpp/include/mkdeps.h
SYMTAB_H = $(srcdir)/../libcpp/include/symtab.h SYMTAB_H = $(srcdir)/../libcpp/include/symtab.h
CPP_ID_DATA_H = $(CPPLIB_H) $(srcdir)/../libcpp/include/cpp-id-data.h CPP_ID_DATA_H = $(CPPLIB_H) $(srcdir)/../libcpp/include/cpp-id-data.h
......
...@@ -71,8 +71,6 @@ typedef decNumber* (*dfp_unary_func) ...@@ -71,8 +71,6 @@ typedef decNumber* (*dfp_unary_func)
typedef decNumber* (*dfp_binary_func) typedef decNumber* (*dfp_binary_func)
(decNumber *, const decNumber *, const decNumber *, decContext *); (decNumber *, const decNumber *, const decNumber *, decContext *);
extern uint32_t __dec_byte_swap (uint32_t);
/* Unary operations. */ /* Unary operations. */
static inline DFP_C_TYPE static inline DFP_C_TYPE
...@@ -190,101 +188,41 @@ dfp_compare_op (dfp_binary_func op, DFP_C_TYPE arg_a, DFP_C_TYPE arg_b) ...@@ -190,101 +188,41 @@ dfp_compare_op (dfp_binary_func op, DFP_C_TYPE arg_a, DFP_C_TYPE arg_b)
void void
__host_to_ieee_32 (_Decimal32 in, decimal32 *out) __host_to_ieee_32 (_Decimal32 in, decimal32 *out)
{ {
uint32_t t;
if (!LIBGCC2_FLOAT_WORDS_BIG_ENDIAN)
{
memcpy (&t, &in, 4);
t = __dec_byte_swap (t);
memcpy (out, &t, 4);
}
else
memcpy (out, &in, 4); memcpy (out, &in, 4);
} }
void void
__ieee_to_host_32 (decimal32 in, _Decimal32 *out) __ieee_to_host_32 (decimal32 in, _Decimal32 *out)
{ {
uint32_t t;
if (!LIBGCC2_FLOAT_WORDS_BIG_ENDIAN)
{
memcpy (&t, &in, 4);
t = __dec_byte_swap (t);
memcpy (out, &t, 4);
}
else
memcpy (out, &in, 4); memcpy (out, &in, 4);
} }
#endif /* L_conv_sd */ #endif /* L_conv_sd */
#if defined(L_conv_dd) #if defined(L_conv_dd)
static void
__swap64 (char *src, char *dst)
{
uint32_t t1, t2;
if (!LIBGCC2_FLOAT_WORDS_BIG_ENDIAN)
{
memcpy (&t1, src, 4);
memcpy (&t2, src + 4, 4);
t1 = __dec_byte_swap (t1);
t2 = __dec_byte_swap (t2);
memcpy (dst, &t2, 4);
memcpy (dst + 4, &t1, 4);
}
else
memcpy (dst, src, 8);
}
void void
__host_to_ieee_64 (_Decimal64 in, decimal64 *out) __host_to_ieee_64 (_Decimal64 in, decimal64 *out)
{ {
__swap64 ((char *) &in, (char *) out); memcpy (out, &in, 8);
} }
void void
__ieee_to_host_64 (decimal64 in, _Decimal64 *out) __ieee_to_host_64 (decimal64 in, _Decimal64 *out)
{ {
__swap64 ((char *) &in, (char *) out); memcpy (out, &in, 8);
} }
#endif /* L_conv_dd */ #endif /* L_conv_dd */
#if defined(L_conv_td) #if defined(L_conv_td)
static void
__swap128 (char *src, char *dst)
{
uint32_t t1, t2, t3, t4;
if (!LIBGCC2_FLOAT_WORDS_BIG_ENDIAN)
{
memcpy (&t1, src, 4);
memcpy (&t2, src + 4, 4);
memcpy (&t3, src + 8, 4);
memcpy (&t4, src + 12, 4);
t1 = __dec_byte_swap (t1);
t2 = __dec_byte_swap (t2);
t3 = __dec_byte_swap (t3);
t4 = __dec_byte_swap (t4);
memcpy (dst, &t4, 4);
memcpy (dst + 4, &t3, 4);
memcpy (dst + 8, &t2, 4);
memcpy (dst + 12, &t1, 4);
}
else
memcpy (dst, src, 16);
}
void void
__host_to_ieee_128 (_Decimal128 in, decimal128 *out) __host_to_ieee_128 (_Decimal128 in, decimal128 *out)
{ {
__swap128 ((char *) &in, (char *) out); memcpy (out, &in, 16);
} }
void void
__ieee_to_host_128 (decimal128 in, _Decimal128 *out) __ieee_to_host_128 (decimal128 in, _Decimal128 *out)
{ {
__swap128 ((char *) &in, (char *) out); memcpy (out, &in, 16);
} }
#endif /* L_conv_td */ #endif /* L_conv_td */
......
...@@ -31,29 +31,11 @@ along with GCC; see the file COPYING3. If not see ...@@ -31,29 +31,11 @@ along with GCC; see the file COPYING3. If not see
decNumber structure is large enough to hold decimal128 digits. */ decNumber structure is large enough to hold decimal128 digits. */
#include "decimal128.h" #include "decimal128.h"
#include "decimal128Local.h"
#include "decimal64.h" #include "decimal64.h"
#include "decimal32.h" #include "decimal32.h"
#include "decNumber.h" #include "decNumber.h"
static uint32_t
dfp_byte_swap (uint32_t in)
{
uint32_t out = 0;
unsigned char *p = (unsigned char *) &out;
union {
uint32_t i;
unsigned char b[4];
} u;
u.i = in;
p[0] = u.b[3];
p[1] = u.b[2];
p[2] = u.b[1];
p[3] = u.b[0];
return out;
}
/* Initialize R (a real with the decimal flag set) from DN. Can /* Initialize R (a real with the decimal flag set) from DN. Can
utilize status passed in via CONTEXT, if a previous operation had utilize status passed in via CONTEXT, if a previous operation had
interesting status. */ interesting status. */
...@@ -155,10 +137,7 @@ encode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED, ...@@ -155,10 +137,7 @@ encode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
decimal_to_decnumber (r, &dn); decimal_to_decnumber (r, &dn);
decimal32FromNumber (&d32, &dn, &set); decimal32FromNumber (&d32, &dn, &set);
if (FLOAT_WORDS_BIG_ENDIAN)
buf[0] = *(uint32_t *) d32.bytes; buf[0] = *(uint32_t *) d32.bytes;
else
buf[0] = dfp_byte_swap (*(uint32_t *) d32.bytes);
} }
/* Decode an IEEE 754R decimal32 type into a real. */ /* Decode an IEEE 754R decimal32 type into a real. */
...@@ -174,10 +153,7 @@ decode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED, ...@@ -174,10 +153,7 @@ decode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
decContextDefault (&set, DEC_INIT_DECIMAL128); decContextDefault (&set, DEC_INIT_DECIMAL128);
set.traps = 0; set.traps = 0;
if (FLOAT_WORDS_BIG_ENDIAN)
*((uint32_t *) d32.bytes) = (uint32_t) buf[0]; *((uint32_t *) d32.bytes) = (uint32_t) buf[0];
else
*((uint32_t *) d32.bytes) = dfp_byte_swap ((uint32_t) buf[0]);
decimal32ToNumber (&d32, &dn); decimal32ToNumber (&d32, &dn);
decimal_from_decnumber (r, &dn, &set); decimal_from_decnumber (r, &dn, &set);
...@@ -199,16 +175,8 @@ encode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED, ...@@ -199,16 +175,8 @@ encode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
decimal_to_decnumber (r, &dn); decimal_to_decnumber (r, &dn);
decimal64FromNumber (&d64, &dn, &set); decimal64FromNumber (&d64, &dn, &set);
if (FLOAT_WORDS_BIG_ENDIAN)
{
buf[0] = *(uint32_t *) &d64.bytes[0]; buf[0] = *(uint32_t *) &d64.bytes[0];
buf[1] = *(uint32_t *) &d64.bytes[4]; buf[1] = *(uint32_t *) &d64.bytes[4];
}
else
{
buf[1] = dfp_byte_swap (*(uint32_t *) &d64.bytes[0]);
buf[0] = dfp_byte_swap (*(uint32_t *) &d64.bytes[4]);
}
} }
/* Decode an IEEE 754R decimal64 type into a real. */ /* Decode an IEEE 754R decimal64 type into a real. */
...@@ -224,16 +192,8 @@ decode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED, ...@@ -224,16 +192,8 @@ decode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
decContextDefault (&set, DEC_INIT_DECIMAL128); decContextDefault (&set, DEC_INIT_DECIMAL128);
set.traps = 0; set.traps = 0;
if (FLOAT_WORDS_BIG_ENDIAN)
{
*((uint32_t *) &d64.bytes[0]) = (uint32_t) buf[0]; *((uint32_t *) &d64.bytes[0]) = (uint32_t) buf[0];
*((uint32_t *) &d64.bytes[4]) = (uint32_t) buf[1]; *((uint32_t *) &d64.bytes[4]) = (uint32_t) buf[1];
}
else
{
*((uint32_t *) &d64.bytes[0]) = dfp_byte_swap ((uint32_t) buf[1]);
*((uint32_t *) &d64.bytes[4]) = dfp_byte_swap ((uint32_t) buf[0]);
}
decimal64ToNumber (&d64, &dn); decimal64ToNumber (&d64, &dn);
decimal_from_decnumber (r, &dn, &set); decimal_from_decnumber (r, &dn, &set);
...@@ -255,20 +215,10 @@ encode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED, ...@@ -255,20 +215,10 @@ encode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
decimal_to_decnumber (r, &dn); decimal_to_decnumber (r, &dn);
decimal128FromNumber (&d128, &dn, &set); decimal128FromNumber (&d128, &dn, &set);
if (FLOAT_WORDS_BIG_ENDIAN)
{
buf[0] = *(uint32_t *) &d128.bytes[0]; buf[0] = *(uint32_t *) &d128.bytes[0];
buf[1] = *(uint32_t *) &d128.bytes[4]; buf[1] = *(uint32_t *) &d128.bytes[4];
buf[2] = *(uint32_t *) &d128.bytes[8]; buf[2] = *(uint32_t *) &d128.bytes[8];
buf[3] = *(uint32_t *) &d128.bytes[12]; buf[3] = *(uint32_t *) &d128.bytes[12];
}
else
{
buf[0] = dfp_byte_swap (*(uint32_t *) &d128.bytes[12]);
buf[1] = dfp_byte_swap (*(uint32_t *) &d128.bytes[8]);
buf[2] = dfp_byte_swap (*(uint32_t *) &d128.bytes[4]);
buf[3] = dfp_byte_swap (*(uint32_t *) &d128.bytes[0]);
}
} }
/* Decode an IEEE 754R decimal128 type into a real. */ /* Decode an IEEE 754R decimal128 type into a real. */
...@@ -284,20 +234,10 @@ decode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED, ...@@ -284,20 +234,10 @@ decode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
decContextDefault (&set, DEC_INIT_DECIMAL128); decContextDefault (&set, DEC_INIT_DECIMAL128);
set.traps = 0; set.traps = 0;
if (FLOAT_WORDS_BIG_ENDIAN)
{
*((uint32_t *) &d128.bytes[0]) = (uint32_t) buf[0]; *((uint32_t *) &d128.bytes[0]) = (uint32_t) buf[0];
*((uint32_t *) &d128.bytes[4]) = (uint32_t) buf[1]; *((uint32_t *) &d128.bytes[4]) = (uint32_t) buf[1];
*((uint32_t *) &d128.bytes[8]) = (uint32_t) buf[2]; *((uint32_t *) &d128.bytes[8]) = (uint32_t) buf[2];
*((uint32_t *) &d128.bytes[12]) = (uint32_t) buf[3]; *((uint32_t *) &d128.bytes[12]) = (uint32_t) buf[3];
}
else
{
*((uint32_t *) &d128.bytes[0]) = dfp_byte_swap ((uint32_t) buf[3]);
*((uint32_t *) &d128.bytes[4]) = dfp_byte_swap ((uint32_t) buf[2]);
*((uint32_t *) &d128.bytes[8]) = dfp_byte_swap ((uint32_t) buf[1]);
*((uint32_t *) &d128.bytes[12]) = dfp_byte_swap ((uint32_t) buf[0]);
}
decimal128ToNumber (&d128, &dn); decimal128ToNumber (&d128, &dn);
decimal_from_decnumber (r, &dn, &set); decimal_from_decnumber (r, &dn, &set);
......
2007-09-10 Janis Johnson <janis187@us.ibm.com>
Ben Elliston <bje@au.ibm.com>
* Makefile.in (libdecnumber_a_OBJS): Remove decUtility.o
(dependencies): Add Symbols headers.
* decContext.c: Upgrade to decNumber 3.53.
* decContext.h: Ditto.
* decDPD.h: Ditto.
* decNumber.c: Ditto.
* decNumber.h: Ditto.
* decNumberLocal.h: Ditto.
* decBasic.c: New file from decNumber 3.53.
* decCommon.c: Ditto.
* decDouble.c: Ditto.
* decDouble.h: Ditto.
* decQuad.c: Ditto.
* decQuad.h: Ditto.
* decSingle.c: Ditto.
* decSingle.h: Ditto.
* decPacked.c: Ditto.
* decPacked.h: Ditto.
* dpd/decimal128.c: Upgrade to decNumber 3.53.
* dpd/decimal128.h: Ditto.
* dpd/decimal32.c: Ditto.
* dpd/decimal32.h: Ditto.
* dpd/decimal64.c: Ditto.
* dpd/decimal64.h: Ditto.
* decLibrary.c (__dec_byte_swap): Remove.
* decContextSymbols.h: New file.
* decDoubleSymbols.h: New file.
* decNumberSymbols.h: New file.
* decPackedSymbols.h: New file.
* decQuadSymbols.h: New file.
* decSingleSymbols.h: New file.
* decUtility.c: Delete file.
* decUtility.h: Delete file.
* bid/decimal128Symbols.h: New file.
* bid/decimal128Local.h: New file.
* bid/decimal32Symbols.h: New file.
* bid/decimal64Symbols.h: New file.
* bid/host-ieee128.c (__swap128): Remove.
(__host_to_ieee_128, __ieee_to_host_128): Don't handle endianness.
* bid/host-ieee32.c (__dec_type_swap): Remove.
(__host_to_ieee_32, __ieee_to_host_32): Don't handle endianness.
* bid/host-ieee64.c (__swap64): Remove.
(__host_to_ieee_64, __ieee_to_host_64): Don't handle endianness.
* dpd/decimal32Symbols.h: New file.
* dpd/decimal64Symbols.h: New file.
* dpd/decimal128Symbols.h: New file.
* dpd/decimal128Local.h: New file.
2007-06-18 Martin Michlmayr <tbm@cyrius.com> 2007-06-18 Martin Michlmayr <tbm@cyrius.com>
H.J. Lu <hongjiu.lu@intel.com> H.J. Lu <hongjiu.lu@intel.com>
......
...@@ -56,7 +56,7 @@ INCLUDES = -I$(srcdir) -I. ...@@ -56,7 +56,7 @@ INCLUDES = -I$(srcdir) -I.
ALL_CFLAGS = $(CFLAGS) $(WARN_CFLAGS) $(INCLUDES) $(CPPFLAGS) ALL_CFLAGS = $(CFLAGS) $(WARN_CFLAGS) $(INCLUDES) $(CPPFLAGS)
libdecnumber_a_OBJS = decNumber.o decContext.o decUtility.o \ libdecnumber_a_OBJS = decNumber.o decContext.o \
decimal32.o decimal64.o decimal128.o decimal32.o decimal64.o decimal128.o
ifeq ($(enable_decimal_float),bid) ifeq ($(enable_decimal_float),bid)
...@@ -66,7 +66,6 @@ endif ...@@ -66,7 +66,6 @@ endif
libdecnumber_a_SOURCES = decContext.c decContext.h decDPD.h \ libdecnumber_a_SOURCES = decContext.c decContext.h decDPD.h \
decNumber.c decNumber.h decNumberLocal.h \ decNumber.c decNumber.h decNumberLocal.h \
decUtility.c decUtility.h \
dpd/decimal128.c dpd/decimal128.h \ dpd/decimal128.c dpd/decimal128.h \
dpd/decimal32.c dpd/decimal32.h \ dpd/decimal32.c dpd/decimal32.h \
dpd/decimal64.c dpd/decimal64.h \ dpd/decimal64.c dpd/decimal64.h \
...@@ -113,19 +112,25 @@ $(srcdir)/config.in: @MAINT@ $(srcdir)/configure ...@@ -113,19 +112,25 @@ $(srcdir)/config.in: @MAINT@ $(srcdir)/configure
# Dependencies. # Dependencies.
decContext.o: decContext.c decContext.h decNumberLocal.h decContext.o: decContext.c decContext.h decNumberLocal.h \
decNumber.o: decNumber.c decNumber.h decContext.h decNumberLocal.h decContextSymbols.h
decNumber.o: decNumber.c decNumber.h decContext.h decNumberLocal.h \
decNumberSymbols.h
decimal32.o: $(enable_decimal_float)/decimal32.c \ decimal32.o: $(enable_decimal_float)/decimal32.c \
$(enable_decimal_float)/decimal32.h \ $(enable_decimal_float)/decimal32.h \
decNumber.h decContext.h decNumberLocal.h decUtility.h $(enable_decimal_float)/decimal32Symbols.h \
decNumber.h decContext.h decNumberLocal.h
$(COMPILE) $< $(COMPILE) $<
decimal64.o: $(enable_decimal_float)/decimal64.c \ decimal64.o: $(enable_decimal_float)/decimal64.c \
$(enable_decimal_float)/decimal64.h \ $(enable_decimal_float)/decimal64.h \
decNumber.h decContext.h decNumberLocal.h decUtility.h $(enable_decimal_float)/decimal64Symbols.h \
decNumber.h decContext.h decNumberLocal.h
$(COMPILE) $< $(COMPILE) $<
decimal128.o: $(enable_decimal_float)/decimal128.c \ decimal128.o: $(enable_decimal_float)/decimal128.c \
$(enable_decimal_float)/decimal128.h \ $(enable_decimal_float)/decimal128.h \
decNumber.h decContext.h decNumberLocal.h decUtility.h $(enable_decimal_float)/decimal128Symbols.h\
$(enable_decimal_float)/decimal128Local.h\
decNumber.h decContext.h decNumberLocal.h
$(COMPILE) $< $(COMPILE) $<
bid2dpd_dpd2bid.o : bid/bid2dpd_dpd2bid.c bid/bid2dpd_dpd2bid.h bid2dpd_dpd2bid.o : bid/bid2dpd_dpd2bid.c bid/bid2dpd_dpd2bid.h
$(COMPILE) $< $(COMPILE) $<
......
#include "dpd/decimal128Local.h"
#include "dpd/decimal128Symbols.h"
#include "dpd/decimal32Symbols.h"
#include "dpd/decimal64Symbols.h"
...@@ -27,56 +27,22 @@ along with GCC; see the file COPYING. If not, write to the Free ...@@ -27,56 +27,22 @@ along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */ 02110-1301, USA. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <limits.h>
#include "config.h"
#include "gstdint.h"
#include "bid-dpd.h" #include "bid-dpd.h"
#include "decimal128.h" #include "decimal128.h"
extern uint32_t __dec_byte_swap (uint32_t);
void __host_to_ieee_128 (_Decimal128 in, decimal128 *out); void __host_to_ieee_128 (_Decimal128 in, decimal128 *out);
void __ieee_to_host_128 (decimal128 in, _Decimal128 *out); void __ieee_to_host_128 (decimal128 in, _Decimal128 *out);
#ifndef WORDS_BIGENDIAN
#define WORDS_BIGENDIAN 0
#endif
static void
__swap128 (char *src, char *dst)
{
uint32_t t1, t2, t3, t4;
if (!WORDS_BIGENDIAN)
{
memcpy (&t1, src, 4);
memcpy (&t2, src + 4, 4);
memcpy (&t3, src + 8, 4);
memcpy (&t4, src + 12, 4);
t1 = __dec_byte_swap (t1);
t2 = __dec_byte_swap (t2);
t3 = __dec_byte_swap (t3);
t4 = __dec_byte_swap (t4);
memcpy (dst, &t4, 4);
memcpy (dst + 4, &t3, 4);
memcpy (dst + 8, &t2, 4);
memcpy (dst + 12, &t1, 4);
}
else
memcpy (dst, src, 16);
}
void void
__host_to_ieee_128 (_Decimal128 in, decimal128 *out) __host_to_ieee_128 (_Decimal128 in, decimal128 *out)
{ {
__swap128 ((char *) &in, (char *) out); memcpy ((char *) out, (char *) &in, 16);
} }
void void
__ieee_to_host_128 (decimal128 in, _Decimal128 *out) __ieee_to_host_128 (decimal128 in, _Decimal128 *out)
{ {
__swap128 ((char *) &in, (char *) out); memcpy ((char *) out, (char *) &in, 16);
} }
...@@ -37,69 +37,21 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA ...@@ -37,69 +37,21 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
/* The intended way to use this file is to make two copies, add `#define ' /* The intended way to use this file is to make two copies, add `#define '
to one copy, then compile both copies and add them to libgcc.a. */ to one copy, then compile both copies and add them to libgcc.a. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <limits.h>
#include "config.h"
#include "gstdint.h"
#include "bid-dpd.h" #include "bid-dpd.h"
#include "decimal32.h" #include "decimal32.h"
uint32_t __dec_byte_swap (uint32_t);
void __host_to_ieee_32 (_Decimal32 in, decimal32 *out); void __host_to_ieee_32 (_Decimal32 in, decimal32 *out);
void __ieee_to_host_32 (decimal32 in, _Decimal32 *out); void __ieee_to_host_32 (decimal32 in, _Decimal32 *out);
#ifndef WORDS_BIGENDIAN
#define WORDS_BIGENDIAN 0
#endif
uint32_t
__dec_byte_swap (uint32_t in)
{
uint32_t out = 0;
unsigned char *p = (unsigned char *) &out;
union {
uint32_t i;
unsigned char b[4];
} u;
u.i = in;
p[0] = u.b[3];
p[1] = u.b[2];
p[2] = u.b[1];
p[3] = u.b[0];
return out;
}
void void
__host_to_ieee_32 (_Decimal32 in, decimal32 *out) __host_to_ieee_32 (_Decimal32 in, decimal32 *out)
{ {
uint32_t t; memcpy ((char *) out, (char *) &in, 4);
if (!WORDS_BIGENDIAN)
{
memcpy (&t, &in, 4);
t = __dec_byte_swap (t);
memcpy (out, &t, 4);
}
else
memcpy (out, &in, 4);
} }
void void
__ieee_to_host_32 (decimal32 in, _Decimal32 *out) __ieee_to_host_32 (decimal32 in, _Decimal32 *out)
{ {
uint32_t t; memcpy ((char *) out, (char *) &in, 4);
if (!WORDS_BIGENDIAN)
{
memcpy (&t, &in, 4);
t = __dec_byte_swap (t);
memcpy (out, &t, 4);
}
else
memcpy (out, &in, 4);
} }
...@@ -37,50 +37,21 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA ...@@ -37,50 +37,21 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
/* The intended way to use this file is to make two copies, add `#define ' /* The intended way to use this file is to make two copies, add `#define '
to one copy, then compile both copies and add them to libgcc.a. */ to one copy, then compile both copies and add them to libgcc.a. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <limits.h>
#include "config.h"
#include "gstdint.h"
#include "bid-dpd.h" #include "bid-dpd.h"
#include "decimal64.h" #include "decimal64.h"
uint32_t __dec_byte_swap (uint32_t);
void __host_to_ieee_64 (_Decimal64 in, decimal64 *out); void __host_to_ieee_64 (_Decimal64 in, decimal64 *out);
void __ieee_to_host_64 (decimal64 in, _Decimal64 *out); void __ieee_to_host_64 (decimal64 in, _Decimal64 *out);
#ifndef WORDS_BIGENDIAN
#define WORDS_BIGENDIAN 0
#endif
static void
__swap64 (char *src, char *dst)
{
uint32_t t1, t2;
if (!WORDS_BIGENDIAN)
{
memcpy (&t1, src, 4);
memcpy (&t2, src + 4, 4);
t1 = __dec_byte_swap (t1);
t2 = __dec_byte_swap (t2);
memcpy (dst, &t2, 4);
memcpy (dst + 4, &t1, 4);
}
else
memcpy (dst, src, 8);
}
void void
__host_to_ieee_64 (_Decimal64 in, decimal64 *out) __host_to_ieee_64 (_Decimal64 in, decimal64 *out)
{ {
__swap64 ((char *) &in, (char *) out); memcpy ((char *) out, (char *) &in, 8);
} }
void void
__ieee_to_host_64 (decimal64 in, _Decimal64 *out) __ieee_to_host_64 (decimal64 in, _Decimal64 *out)
{ {
__swap64 ((char *) &in, (char *) out); memcpy ((char *) out, (char *) &in, 8);
} }
This source diff could not be displayed because it is too large. You can view the blob instead.
/* Common code for fixed-size types in the decNumber C Library.
Copyright (C) 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
This file is part of GCC.
GCC 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 2, or (at your option) any later
version.
In addition to the permissions in the GNU General Public License,
the Free Software Foundation gives you unlimited permission to link
the compiled version of this file into combinations with other
programs, and to distribute those combinations without any
restriction coming from the use of this file. (The General Public
License restrictions do apply in other respects; for example, they
cover modification of the file, and distribution when not linked
into a combine executable.)
GCC 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.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
/* ------------------------------------------------------------------ */
/* decCommon.c -- common code for all three fixed-size types */
/* ------------------------------------------------------------------ */
/* This module comprises code that is shared between all the formats */
/* (decSingle, decDouble, and decQuad); it includes set and extract */
/* of format components, widening, narrowing, and string conversions. */
/* */
/* Unlike decNumber, parameterization takes place at compile time */
/* rather than at runtime. The parameters are set in the decDouble.c */
/* (etc.) files, which then include this one to produce the compiled */
/* code. The functions here, therefore, are code shared between */
/* multiple formats. */
/* ------------------------------------------------------------------ */
/* Names here refer to decFloat rather than to decDouble, etc., and */
/* the functions are in strict alphabetical order. */
/* Constants, tables, and debug function(s) are included only for QUAD */
/* (which will always be compiled if DOUBLE or SINGLE are used). */
/* */
/* Whenever a decContext is used, only the status may be set (using */
/* OR) or the rounding mode read; all other fields are ignored and */
/* untouched. */
/* names for simpler testing and default context */
#if DECPMAX==7
#define SINGLE 1
#define DOUBLE 0
#define QUAD 0
#define DEFCONTEXT DEC_INIT_DECIMAL32
#elif DECPMAX==16
#define SINGLE 0
#define DOUBLE 1
#define QUAD 0
#define DEFCONTEXT DEC_INIT_DECIMAL64
#elif DECPMAX==34
#define SINGLE 0
#define DOUBLE 0
#define QUAD 1
#define DEFCONTEXT DEC_INIT_DECIMAL128
#else
#error Unexpected DECPMAX value
#endif
/* Assertions */
#if DECPMAX!=7 && DECPMAX!=16 && DECPMAX!=34
#error Unexpected Pmax (DECPMAX) value for this module
#endif
/* Assert facts about digit characters, etc. */
#if ('9'&0x0f)!=9
#error This module assumes characters are of the form 0b....nnnn
/* where .... are don't care 4 bits and nnnn is 0000 through 1001 */
#endif
#if ('9'&0xf0)==('.'&0xf0)
#error This module assumes '.' has a different mask than a digit
#endif
/* Assert ToString lay-out conditions */
#if DECSTRING<DECPMAX+9
#error ToString needs at least 8 characters for lead-in and dot
#endif
#if DECPMAX+DECEMAXD+5 > DECSTRING
#error Exponent form can be too long for ToString to lay out safely
#endif
#if DECEMAXD > 4
#error Exponent form is too long for ToString to lay out
/* Note: code for up to 9 digits exists in archives [decOct] */
#endif
/* Private functions used here and possibly in decBasic.c, etc. */
static decFloat * decFinalize(decFloat *, bcdnum *, decContext *);
static Flag decBiStr(const char *, const char *, const char *);
/* Macros and private tables; those which are not format-dependent */
/* are only included if decQuad is being built. */
/* ------------------------------------------------------------------ */
/* Combination field lookup tables (uInts to save measurable work) */
/* */
/* DECCOMBEXP - 2 most-significant-bits of exponent (00, 01, or */
/* 10), shifted left for format, or DECFLOAT_Inf/NaN */
/* DECCOMBWEXP - The same, for the next-wider format (unless QUAD) */
/* DECCOMBMSD - 4-bit most-significant-digit */
/* [0 if the index is a special (Infinity or NaN)] */
/* DECCOMBFROM - 5-bit combination field from EXP top bits and MSD */
/* (placed in uInt so no shift is needed) */
/* */
/* DECCOMBEXP, DECCOMBWEXP, and DECCOMBMSD are indexed by the sign */
/* and 5-bit combination field (0-63, the second half of the table */
/* identical to the first half) */
/* DECCOMBFROM is indexed by expTopTwoBits*16 + msd */
/* */
/* DECCOMBMSD and DECCOMBFROM are not format-dependent and so are */
/* only included once, when QUAD is being built */
/* ------------------------------------------------------------------ */
static const uInt DECCOMBEXP[64]={
0, 0, 0, 0, 0, 0, 0, 0,
1<<DECECONL, 1<<DECECONL, 1<<DECECONL, 1<<DECECONL,
1<<DECECONL, 1<<DECECONL, 1<<DECECONL, 1<<DECECONL,
2<<DECECONL, 2<<DECECONL, 2<<DECECONL, 2<<DECECONL,
2<<DECECONL, 2<<DECECONL, 2<<DECECONL, 2<<DECECONL,
0, 0, 1<<DECECONL, 1<<DECECONL,
2<<DECECONL, 2<<DECECONL, DECFLOAT_Inf, DECFLOAT_NaN,
0, 0, 0, 0, 0, 0, 0, 0,
1<<DECECONL, 1<<DECECONL, 1<<DECECONL, 1<<DECECONL,
1<<DECECONL, 1<<DECECONL, 1<<DECECONL, 1<<DECECONL,
2<<DECECONL, 2<<DECECONL, 2<<DECECONL, 2<<DECECONL,
2<<DECECONL, 2<<DECECONL, 2<<DECECONL, 2<<DECECONL,
0, 0, 1<<DECECONL, 1<<DECECONL,
2<<DECECONL, 2<<DECECONL, DECFLOAT_Inf, DECFLOAT_NaN};
#if !QUAD
static const uInt DECCOMBWEXP[64]={
0, 0, 0, 0, 0, 0, 0, 0,
1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL,
1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL,
2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL,
2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL,
0, 0, 1<<DECWECONL, 1<<DECWECONL,
2<<DECWECONL, 2<<DECWECONL, DECFLOAT_Inf, DECFLOAT_NaN,
0, 0, 0, 0, 0, 0, 0, 0,
1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL,
1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL,
2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL,
2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL,
0, 0, 1<<DECWECONL, 1<<DECWECONL,
2<<DECWECONL, 2<<DECWECONL, DECFLOAT_Inf, DECFLOAT_NaN};
#endif
#if QUAD
const uInt DECCOMBMSD[64]={
0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 1,
0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 0};
const uInt DECCOMBFROM[48]={
0x00000000, 0x04000000, 0x08000000, 0x0C000000, 0x10000000, 0x14000000,
0x18000000, 0x1C000000, 0x60000000, 0x64000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x20000000, 0x24000000,
0x28000000, 0x2C000000, 0x30000000, 0x34000000, 0x38000000, 0x3C000000,
0x68000000, 0x6C000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x40000000, 0x44000000, 0x48000000, 0x4C000000,
0x50000000, 0x54000000, 0x58000000, 0x5C000000, 0x70000000, 0x74000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000};
/* ------------------------------------------------------------------ */
/* Request and include the tables to use for conversions */
/* ------------------------------------------------------------------ */
#define DEC_BCD2DPD 1 /* 0-0x999 -> DPD */
#define DEC_BIN2DPD 1 /* 0-999 -> DPD */
#define DEC_BIN2BCD8 1 /* 0-999 -> ddd, len */
#define DEC_DPD2BCD8 1 /* DPD -> ddd, len */
#define DEC_DPD2BIN 1 /* DPD -> 0-999 */
#define DEC_DPD2BINK 1 /* DPD -> 0-999000 */
#define DEC_DPD2BINM 1 /* DPD -> 0-999000000 */
#include "decDPD.h" /* source of the lookup tables */
#endif
/* ----------------------------------------------------------------- */
/* decBiStr -- compare string with pairwise options */
/* */
/* targ is the string to compare */
/* str1 is one of the strings to compare against (length may be 0) */
/* str2 is the other; it must be the same length as str1 */
/* */
/* returns 1 if strings compare equal, (that is, targ is the same */
/* length as str1 and str2, and each character of targ is in one */
/* of str1 or str2 in the corresponding position), or 0 otherwise */
/* */
/* This is used for generic caseless compare, including the awkward */
/* case of the Turkish dotted and dotless Is. Use as (for example): */
/* if (decBiStr(test, "mike", "MIKE")) ... */
/* ----------------------------------------------------------------- */
static Flag decBiStr(const char *targ, const char *str1, const char *str2) {
for (;;targ++, str1++, str2++) {
if (*targ!=*str1 && *targ!=*str2) return 0;
/* *targ has a match in one (or both, if terminator) */
if (*targ=='\0') break;
} /* forever */
return 1;
} /* decBiStr */
/* ------------------------------------------------------------------ */
/* decFinalize -- adjust and store a final result */
/* */
/* df is the decFloat format number which gets the final result */
/* num is the descriptor of the number to be checked and encoded */
/* [its values, including the coefficient, may be modified] */
/* set is the context to use */
/* returns df */
/* */
/* The num descriptor may point to a bcd8 string of any length; this */
/* string may have leading insignificant zeros. If it has more than */
/* DECPMAX digits then the final digit can be a round-for-reround */
/* digit (i.e., it may include a sticky bit residue). */
/* */
/* The exponent (q) may be one of the codes for a special value and */
/* can be up to 999999999 for conversion from string. */
/* */
/* No error is possible, but Inexact, Underflow, and/or Overflow may */
/* be set. */
/* ------------------------------------------------------------------ */
/* Constant whose size varies with format; also the check for surprises */
static uByte allnines[DECPMAX]=
#if SINGLE
{9, 9, 9, 9, 9, 9, 9};
#elif DOUBLE
{9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9};
#elif QUAD
{9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9};
#endif
static decFloat * decFinalize(decFloat *df, bcdnum *num,
decContext *set) {
uByte *ub; /* work */
uInt dpd; /* .. */
uByte *umsd=num->msd; /* local copy */
uByte *ulsd=num->lsd; /* .. */
uInt encode; /* encoding accumulator */
Int length; /* coefficient length */
#if DECCHECK
Int clen=ulsd-umsd+1;
#if QUAD
#define COEXTRA 2 /* extra-long coefficent */
#else
#define COEXTRA 0
#endif
if (clen<1 || clen>DECPMAX*3+2+COEXTRA)
printf("decFinalize: suspect coefficient [length=%ld]\n", (LI)clen);
if (num->sign!=0 && num->sign!=DECFLOAT_Sign)
printf("decFinalize: bad sign [%08lx]\n", (LI)num->sign);
if (!EXPISSPECIAL(num->exponent)
&& (num->exponent>1999999999 || num->exponent<-1999999999))
printf("decFinalize: improbable exponent [%ld]\n", (LI)num->exponent);
/* decShowNum(num, "final"); */
#endif
/* A special will have an 'exponent' which is very positive and a */
/* coefficient < DECPMAX */
length=(uInt)(ulsd-umsd+1); /* coefficient length */
if (!NUMISSPECIAL(num)) {
Int drop; /* digits to be dropped */
/* skip leading insignificant zeros to calculate an exact length */
/* [this is quite expensive] */
if (*umsd==0) {
for (; UINTAT(umsd)==0 && umsd+3<ulsd;) umsd+=4;
for (; *umsd==0 && umsd<ulsd;) umsd++;
length=ulsd-umsd+1; /* recalculate */
}
drop=MAXI(length-DECPMAX, DECQTINY-num->exponent);
/* drop can now be > digits for bottom-clamp (subnormal) cases */
if (drop>0) { /* rounding needed */
/* (decFloatQuantize has very similar code to this, so any */
/* changes may need to be made there, too) */
uByte *roundat; /* -> re-round digit */
uByte reround; /* reround value */
/* printf("Rounding; drop=%ld\n", (LI)drop); */
num->exponent+=drop; /* always update exponent */
/* Three cases here: */
/* 1. new LSD is in coefficient (almost always) */
/* 2. new LSD is digit to left of coefficient (so MSD is */
/* round-for-reround digit) */
/* 3. new LSD is to left of case 2 (whole coefficient is sticky) */
/* [duplicate check-stickies code to save a test] */
/* [by-digit check for stickies as runs of zeros are rare] */
if (drop<length) { /* NB lengths not addresses */
roundat=umsd+length-drop;
reround=*roundat;
for (ub=roundat+1; ub<=ulsd; ub++) {
if (*ub!=0) { /* non-zero to be discarded */
reround=DECSTICKYTAB[reround]; /* apply sticky bit */
break; /* [remainder don't-care] */
}
} /* check stickies */
ulsd=roundat-1; /* new LSD */
}
else { /* edge case */
if (drop==length) {
roundat=umsd;
reround=*roundat;
}
else {
roundat=umsd-1;
reround=0;
}
for (ub=roundat+1; ub<=ulsd; ub++) {
if (*ub!=0) { /* non-zero to be discarded */
reround=DECSTICKYTAB[reround]; /* apply sticky bit */
break; /* [remainder don't-care] */
}
} /* check stickies */
*umsd=0; /* coefficient is a 0 */
ulsd=umsd; /* .. */
}
if (reround!=0) { /* discarding non-zero */
uInt bump=0;
set->status|=DEC_Inexact;
/* if adjusted exponent [exp+digits-1] is < EMIN then num is */
/* subnormal -- so raise Underflow */
if (num->exponent<DECEMIN && (num->exponent+(ulsd-umsd+1)-1)<DECEMIN)
set->status|=DEC_Underflow;
/* next decide whether increment of the coefficient is needed */
if (set->round==DEC_ROUND_HALF_EVEN) { /* fastpath slowest case */
if (reround>5) bump=1; /* >0.5 goes up */
else if (reround==5) /* exactly 0.5000 .. */
bump=*ulsd & 0x01; /* .. up iff [new] lsd is odd */
} /* r-h-e */
else switch (set->round) {
case DEC_ROUND_DOWN: {
/* no change */
break;} /* r-d */
case DEC_ROUND_HALF_DOWN: {
if (reround>5) bump=1;
break;} /* r-h-d */
case DEC_ROUND_HALF_UP: {
if (reround>=5) bump=1;
break;} /* r-h-u */
case DEC_ROUND_UP: {
if (reround>0) bump=1;
break;} /* r-u */
case DEC_ROUND_CEILING: {
/* same as _UP for positive numbers, and as _DOWN for negatives */
if (!num->sign && reround>0) bump=1;
break;} /* r-c */
case DEC_ROUND_FLOOR: {
/* same as _UP for negative numbers, and as _DOWN for positive */
/* [negative reround cannot occur on 0] */
if (num->sign && reround>0) bump=1;
break;} /* r-f */
case DEC_ROUND_05UP: {
if (reround>0) { /* anything out there is 'sticky' */
/* bump iff lsd=0 or 5; this cannot carry so it could be */
/* effected immediately with no bump -- but the code */
/* is clearer if this is done the same way as the others */
if (*ulsd==0 || *ulsd==5) bump=1;
}
break;} /* r-r */
default: { /* e.g., DEC_ROUND_MAX */
set->status|=DEC_Invalid_context;
#if DECCHECK
printf("Unknown rounding mode: %ld\n", (LI)set->round);
#endif
break;}
} /* switch (not r-h-e) */
/* printf("ReRound: %ld bump: %ld\n", (LI)reround, (LI)bump); */
if (bump!=0) { /* need increment */
/* increment the coefficient; this might end up with 1000... */
/* (after the all nines case) */
ub=ulsd;
for(; ub-3>=umsd && UINTAT(ub-3)==0x09090909; ub-=4) UINTAT(ub-3)=0;
/* [note ub could now be to left of msd, and it is not safe */
/* to write to the the left of the msd] */
/* now at most 3 digits left to non-9 (usually just the one) */
for (; ub>=umsd; *ub=0, ub--) {
if (*ub==9) continue; /* carry */
*ub+=1;
break;
}
if (ub<umsd) { /* had all-nines */
*umsd=1; /* coefficient to 1000... */
/* usually the 1000... coefficient can be used as-is */
if ((ulsd-umsd+1)==DECPMAX) {
num->exponent++;
}
else {
/* if coefficient is shorter than Pmax then num is */
/* subnormal, so extend it; this is safe as drop>0 */
/* (or, if the coefficient was supplied above, it could */
/* not be 9); this may make the result normal. */
ulsd++;
*ulsd=0;
/* [exponent unchanged] */
#if DECCHECK
if (num->exponent!=DECQTINY) /* sanity check */
printf("decFinalize: bad all-nines extend [^%ld, %ld]\n",
(LI)num->exponent, (LI)(ulsd-umsd+1));
#endif
} /* subnormal extend */
} /* had all-nines */
} /* bump needed */
} /* inexact rounding */
length=ulsd-umsd+1; /* recalculate (may be <DECPMAX) */
} /* need round (drop>0) */
/* The coefficient will now fit and has final length unless overflow */
/* decShowNum(num, "rounded"); */
/* if exponent is >=emax may have to clamp, overflow, or fold-down */
if (num->exponent>DECEMAX-(DECPMAX-1)) { /* is edge case */
/* printf("overflow checks...\n"); */
if (*ulsd==0 && ulsd==umsd) { /* have zero */
num->exponent=DECEMAX-(DECPMAX-1); /* clamp to max */
}
else if ((num->exponent+length-1)>DECEMAX) { /* > Nmax */
/* Overflow -- these could go straight to encoding, here, but */
/* instead num is adjusted to keep the code cleaner */
Flag needmax=0; /* 1 for finite result */
set->status|=(DEC_Overflow | DEC_Inexact);
switch (set->round) {
case DEC_ROUND_DOWN: {
needmax=1; /* never Infinity */
break;} /* r-d */
case DEC_ROUND_05UP: {
needmax=1; /* never Infinity */
break;} /* r-05 */
case DEC_ROUND_CEILING: {
if (num->sign) needmax=1; /* Infinity iff non-negative */
break;} /* r-c */
case DEC_ROUND_FLOOR: {
if (!num->sign) needmax=1; /* Infinity iff negative */
break;} /* r-f */
default: break; /* Infinity in all other cases */
}
if (!needmax) { /* easy .. set Infinity */
num->exponent=DECFLOAT_Inf;
*umsd=0; /* be clean: coefficient to 0 */
ulsd=umsd; /* .. */
}
else { /* return Nmax */
umsd=allnines; /* use constant array */
ulsd=allnines+DECPMAX-1;
num->exponent=DECEMAX-(DECPMAX-1);
}
}
else { /* no overflow but non-zero and may have to fold-down */
Int shift=num->exponent-(DECEMAX-(DECPMAX-1));
if (shift>0) { /* fold-down needed */
/* fold down needed; must copy to buffer in order to pad */
/* with zeros safely; fortunately this is not the worst case */
/* path because cannot have had a round */
uByte buffer[ROUNDUP(DECPMAX+3, 4)]; /* [+3 allows uInt padding] */
uByte *s=umsd; /* source */
uByte *t=buffer; /* safe target */
uByte *tlsd=buffer+(ulsd-umsd)+shift; /* target LSD */
/* printf("folddown shift=%ld\n", (LI)shift); */
for (; s<=ulsd; s+=4, t+=4) UINTAT(t)=UINTAT(s);
for (t=tlsd-shift+1; t<=tlsd; t+=4) UINTAT(t)=0; /* pad */
num->exponent-=shift;
umsd=buffer;
ulsd=tlsd;
}
} /* fold-down? */
length=ulsd-umsd+1; /* recalculate length */
} /* high-end edge case */
} /* finite number */
/*------------------------------------------------------------------*/
/* At this point the result will properly fit the decFloat */
/* encoding, and it can be encoded with no possibility of error */
/*------------------------------------------------------------------*/
/* Following code does not alter coefficient (could be allnines array) */
if (length==DECPMAX) {
return decFloatFromBCD(df, num->exponent, umsd, num->sign);
}
/* Here when length is short */
if (!NUMISSPECIAL(num)) { /* is still finite */
/* encode the combination field and exponent continuation */
uInt uexp=(uInt)(num->exponent+DECBIAS); /* biased exponent */
uInt code=(uexp>>DECECONL)<<4; /* top two bits of exp */
/* [msd=0] */
/* look up the combination field and make high word */
encode=DECCOMBFROM[code]; /* indexed by (0-2)*16+msd */
encode|=(uexp<<(32-6-DECECONL)) & 0x03ffffff; /* exponent continuation */
}
else encode=num->exponent; /* special [already in word] */
/* [coefficient length here will be < DECPMAX] */
encode|=num->sign; /* add sign */
/* private macro to extract a declet, n (where 0<=n<DECLETS and 0 */
/* refers to the declet from the least significant three digits) */
/* and put the corresponding DPD code into dpd. Access to umsd and */
/* ulsd (pointers to the most and least significant digit of the */
/* variable-length coefficient) is assumed, along with use of a */
/* working pointer, uInt *ub. */
/* As not full-length then chances are there are many leading zeros */
/* [and there may be a partial triad] */
#define getDPD(dpd, n) ub=ulsd-(3*(n))-2; \
if (ub<umsd-2) dpd=0; \
else if (ub>=umsd) dpd=BCD2DPD[(*ub*256)+(*(ub+1)*16)+*(ub+2)]; \
else {dpd=*(ub+2); if (ub+1==umsd) dpd+=*(ub+1)*16; dpd=BCD2DPD[dpd];}
/* place the declets in the encoding words and copy to result (df), */
/* according to endianness; in all cases complete the sign word */
/* first */
#if DECPMAX==7
getDPD(dpd, 1);
encode|=dpd<<10;
getDPD(dpd, 0);
encode|=dpd;
DFWORD(df, 0)=encode; /* just the one word */
#elif DECPMAX==16
getDPD(dpd, 4); encode|=dpd<<8;
getDPD(dpd, 3); encode|=dpd>>2;
DFWORD(df, 0)=encode;
encode=dpd<<30;
getDPD(dpd, 2); encode|=dpd<<20;
getDPD(dpd, 1); encode|=dpd<<10;
getDPD(dpd, 0); encode|=dpd;
DFWORD(df, 1)=encode;
#elif DECPMAX==34
getDPD(dpd,10); encode|=dpd<<4;
getDPD(dpd, 9); encode|=dpd>>6;
DFWORD(df, 0)=encode;
encode=dpd<<26;
getDPD(dpd, 8); encode|=dpd<<16;
getDPD(dpd, 7); encode|=dpd<<6;
getDPD(dpd, 6); encode|=dpd>>4;
DFWORD(df, 1)=encode;
encode=dpd<<28;
getDPD(dpd, 5); encode|=dpd<<18;
getDPD(dpd, 4); encode|=dpd<<8;
getDPD(dpd, 3); encode|=dpd>>2;
DFWORD(df, 2)=encode;
encode=dpd<<30;
getDPD(dpd, 2); encode|=dpd<<20;
getDPD(dpd, 1); encode|=dpd<<10;
getDPD(dpd, 0); encode|=dpd;
DFWORD(df, 3)=encode;
#endif
/* printf("Status: %08lx\n", (LI)set->status); */
/* decFloatShow(df, "final"); */
return df;
} /* decFinalize */
/* ------------------------------------------------------------------ */
/* decFloatFromBCD -- set decFloat from exponent, BCD8, and sign */
/* */
/* df is the target decFloat */
/* exp is the in-range unbiased exponent, q, or a special value in */
/* the form returned by decFloatGetExponent */
/* bcdar holds DECPMAX digits to set the coefficient from, one */
/* digit in each byte (BCD8 encoding); the first (MSD) is ignored */
/* if df is a NaN; all are ignored if df is infinite. */
/* All bytes must be in 0-9; results undefined otherwise. */
/* sig is DECFLOAT_Sign to set the sign bit, 0 otherwise */
/* returns df, which will be canonical */
/* */
/* No error is possible, and no status will be set. */
/* ------------------------------------------------------------------ */
decFloat * decFloatFromBCD(decFloat *df, Int exp, const uByte *bcdar,
Int sig) {
uInt encode, dpd; /* work */
const uByte *ub; /* .. */
if (EXPISSPECIAL(exp)) encode=exp|sig;/* specials already encoded */
else { /* is finite */
/* encode the combination field and exponent continuation */
uInt uexp=(uInt)(exp+DECBIAS); /* biased exponent */
uInt code=(uexp>>DECECONL)<<4; /* top two bits of exp */
code+=bcdar[0]; /* add msd */
/* look up the combination field and make high word */
encode=DECCOMBFROM[code]|sig; /* indexed by (0-2)*16+msd */
encode|=(uexp<<(32-6-DECECONL)) & 0x03ffffff; /* exponent continuation */
}
/* private macro to extract a declet, n (where 0<=n<DECLETS and 0 */
/* refers to the declet from the least significant three digits) */
/* and put the corresponding DPD code into dpd. */
/* Use of a working pointer, uInt *ub, is assumed. */
#define getDPDf(dpd, n) ub=bcdar+DECPMAX-1-(3*(n))-2; \
dpd=BCD2DPD[(*ub*256)+(*(ub+1)*16)+*(ub+2)];
/* place the declets in the encoding words and copy to result (df), */
/* according to endianness; in all cases complete the sign word */
/* first */
#if DECPMAX==7
getDPDf(dpd, 1);
encode|=dpd<<10;
getDPDf(dpd, 0);
encode|=dpd;
DFWORD(df, 0)=encode; /* just the one word */
#elif DECPMAX==16
getDPDf(dpd, 4); encode|=dpd<<8;
getDPDf(dpd, 3); encode|=dpd>>2;
DFWORD(df, 0)=encode;
encode=dpd<<30;
getDPDf(dpd, 2); encode|=dpd<<20;
getDPDf(dpd, 1); encode|=dpd<<10;
getDPDf(dpd, 0); encode|=dpd;
DFWORD(df, 1)=encode;
#elif DECPMAX==34
getDPDf(dpd,10); encode|=dpd<<4;
getDPDf(dpd, 9); encode|=dpd>>6;
DFWORD(df, 0)=encode;
encode=dpd<<26;
getDPDf(dpd, 8); encode|=dpd<<16;
getDPDf(dpd, 7); encode|=dpd<<6;
getDPDf(dpd, 6); encode|=dpd>>4;
DFWORD(df, 1)=encode;
encode=dpd<<28;
getDPDf(dpd, 5); encode|=dpd<<18;
getDPDf(dpd, 4); encode|=dpd<<8;
getDPDf(dpd, 3); encode|=dpd>>2;
DFWORD(df, 2)=encode;
encode=dpd<<30;
getDPDf(dpd, 2); encode|=dpd<<20;
getDPDf(dpd, 1); encode|=dpd<<10;
getDPDf(dpd, 0); encode|=dpd;
DFWORD(df, 3)=encode;
#endif
/* decFloatShow(df, "final"); */
return df;
} /* decFloatFromBCD */
/* ------------------------------------------------------------------ */
/* decFloatFromPacked -- set decFloat from exponent and packed BCD */
/* */
/* df is the target decFloat */
/* exp is the in-range unbiased exponent, q, or a special value in */
/* the form returned by decFloatGetExponent */
/* packed holds DECPMAX packed decimal digits plus a sign nibble */
/* (all 6 codes are OK); the first (MSD) is ignored if df is a NaN */
/* and all except sign are ignored if df is infinite. For DOUBLE */
/* and QUAD the first (pad) nibble is also ignored in all cases. */
/* All coefficient nibbles must be in 0-9 and sign in A-F; results */
/* are undefined otherwise. */
/* returns df, which will be canonical */
/* */
/* No error is possible, and no status will be set. */
/* ------------------------------------------------------------------ */
decFloat * decFloatFromPacked(decFloat *df, Int exp, const uByte *packed) {
uByte bcdar[DECPMAX+2]; /* work [+1 for pad, +1 for sign] */
const uByte *ip; /* .. */
uByte *op; /* .. */
Int sig=0; /* sign */
/* expand coefficient and sign to BCDAR */
#if SINGLE
op=bcdar+1; /* no pad digit */
#else
op=bcdar; /* first (pad) digit ignored */
#endif
for (ip=packed; ip<packed+((DECPMAX+2)/2); ip++) {
*op++=*ip>>4;
*op++=(uByte)(*ip&0x0f); /* [final nibble is sign] */
}
op--; /* -> sign byte */
if (*op==DECPMINUS || *op==DECPMINUSALT) sig=DECFLOAT_Sign;
if (EXPISSPECIAL(exp)) { /* Infinity or NaN */
if (!EXPISINF(exp)) bcdar[1]=0; /* a NaN: ignore MSD */
else memset(bcdar+1, 0, DECPMAX); /* Infinite: coefficient to 0 */
}
return decFloatFromBCD(df, exp, bcdar+1, sig);
} /* decFloatFromPacked */
/* ------------------------------------------------------------------ */
/* decFloatFromString -- conversion from numeric string */
/* */
/* result is the decFloat format number which gets the result of */
/* the conversion */
/* *string is the character string which should contain a valid */
/* number (which may be a special value), \0-terminated */
/* If there are too many significant digits in the */
/* coefficient it will be rounded. */
/* set is the context */
/* returns result */
/* */
/* The length of the coefficient and the size of the exponent are */
/* checked by this routine, so the correct error (Underflow or */
/* Overflow) can be reported or rounding applied, as necessary. */
/* */
/* There is no limit to the coefficient length for finite inputs; */
/* NaN payloads must be integers with no more than DECPMAX-1 digits. */
/* Exponents may have up to nine significant digits. */
/* */
/* If bad syntax is detected, the result will be a quiet NaN. */
/* ------------------------------------------------------------------ */
decFloat * decFloatFromString(decFloat *result, const char *string,
decContext *set) {
Int digits; /* count of digits in coefficient */
const char *dotchar=NULL; /* where dot was found [NULL if none] */
const char *cfirst=string; /* -> first character of decimal part */
const char *c; /* work */
uByte *ub; /* .. */
bcdnum num; /* collects data for finishing */
uInt error=DEC_Conversion_syntax; /* assume the worst */
uByte buffer[ROUNDUP(DECSTRING+11, 8)]; /* room for most coefficents, */
/* some common rounding, +3, & pad */
#if DECTRACE
/* printf("FromString %s ...\n", string); */
#endif
for(;;) { /* once-only 'loop' */
num.sign=0; /* assume non-negative */
num.msd=buffer; /* MSD is here always */
/* detect and validate the coefficient, including any leading, */
/* trailing, or embedded '.' */
/* [could test four-at-a-time here (saving 10% for decQuads), */
/* but that risks storage violation because the position of the */
/* terminator is unknown] */
for (c=string;; c++) { /* -> input character */
if (((unsigned)(*c-'0'))<=9) continue; /* '0' through '9' is good */
if (*c=='\0') break; /* most common non-digit */
if (*c=='.') {
if (dotchar!=NULL) break; /* not first '.' */
dotchar=c; /* record offset into decimal part */
continue;}
if (c==string) { /* first in string... */
if (*c=='-') { /* valid - sign */
cfirst++;
num.sign=DECFLOAT_Sign;
continue;}
if (*c=='+') { /* valid + sign */
cfirst++;
continue;}
}
/* *c is not a digit, terminator, or a valid +, -, or '.' */
break;
} /* c loop */
digits=(uInt)(c-cfirst); /* digits (+1 if a dot) */
if (digits>0) { /* had digits and/or dot */
const char *clast=c-1; /* note last coefficient char position */
Int exp=0; /* exponent accumulator */
if (*c!='\0') { /* something follows the coefficient */
uInt edig; /* unsigned work */
/* had some digits and more to come; expect E[+|-]nnn now */
const char *firstexp; /* exponent first non-zero */
if (*c!='E' && *c!='e') break;
c++; /* to (optional) sign */
if (*c=='-' || *c=='+') c++; /* step over sign (c=clast+2) */
if (*c=='\0') break; /* no digits! (e.g., '1.2E') */
for (; *c=='0';) c++; /* skip leading zeros [even last] */
firstexp=c; /* remember start [maybe '\0'] */
/* gather exponent digits */
edig=(uInt)*c-(uInt)'0';
if (edig<=9) { /* [check not bad or terminator] */
exp+=edig; /* avoid initial X10 */
c++;
for (;; c++) {
edig=(uInt)*c-(uInt)'0';
if (edig>9) break;
exp=exp*10+edig;
}
}
/* if not now on the '\0', *c must not be a digit */
if (*c!='\0') break;
/* (this next test must be after the syntax checks) */
/* if definitely more than the possible digits for format then */
/* the exponent may have wrapped, so simply set it to a certain */
/* over/underflow value */
if (c>firstexp+DECEMAXD) exp=DECEMAX*2;
if (*(clast+2)=='-') exp=-exp; /* was negative */
} /* digits>0 */
if (dotchar!=NULL) { /* had a '.' */
digits--; /* remove from digits count */
if (digits==0) break; /* was dot alone: bad syntax */
exp-=(Int)(clast-dotchar); /* adjust exponent */
/* [the '.' can now be ignored] */
}
num.exponent=exp; /* exponent is good; store it */
/* Here when whole string has been inspected and syntax is good */
/* cfirst->first digit or dot, clast->last digit or dot */
error=0; /* no error possible now */
/* if the number of digits in the coefficient will fit in buffer */
/* then it can simply be converted to bcd8 and copied -- decFinalize */
/* will take care of leading zeros and rounding; the buffer is big */
/* enough for all canonical coefficients, including 0.00000nn... */
ub=buffer;
if (digits<=(Int)(sizeof(buffer)-3)) { /* [-3 allows by-4s copy] */
c=cfirst;
if (dotchar!=NULL) { /* a dot to worry about */
if (*(c+1)=='.') { /* common canonical case */
*ub++=(uByte)(*c-'0'); /* copy leading digit */
c+=2; /* prepare to handle rest */
}
else for (; c<=clast;) { /* '.' could be anywhere */
/* as usual, go by fours when safe; NB it has been asserted */
/* that a '.' does not have the same mask as a digit */
if (c<=clast-3 /* safe for four */
&& (UINTAT(c)&0xf0f0f0f0)==CHARMASK) { /* test four */
UINTAT(ub)=UINTAT(c)&0x0f0f0f0f; /* to BCD8 */
ub+=4;
c+=4;
continue;
}
if (*c=='.') { /* found the dot */
c++; /* step over it .. */
break; /* .. and handle the rest */
}
*ub++=(uByte)(*c++-'0');
}
} /* had dot */
/* Now no dot; do this by fours (where safe) */
for (; c<=clast-3; c+=4, ub+=4) UINTAT(ub)=UINTAT(c)&0x0f0f0f0f;
for (; c<=clast; c++, ub++) *ub=(uByte)(*c-'0');
num.lsd=buffer+digits-1; /* record new LSD */
} /* fits */
else { /* too long for buffer */
/* [This is a rare and unusual case; arbitrary-length input] */
/* strip leading zeros [but leave final 0 if all 0's] */
if (*cfirst=='.') cfirst++; /* step past dot at start */
if (*cfirst=='0') { /* [cfirst always -> digit] */
for (; cfirst<clast; cfirst++) {
if (*cfirst!='0') { /* non-zero found */
if (*cfirst=='.') continue; /* [ignore] */
break; /* done */
}
digits--; /* 0 stripped */
} /* cfirst */
} /* at least one leading 0 */
/* the coefficient is now as short as possible, but may still */
/* be too long; copy up to Pmax+1 digits to the buffer, then */
/* just record any non-zeros (set round-for-reround digit) */
for (c=cfirst; c<=clast && ub<=buffer+DECPMAX; c++) {
/* (see commentary just above) */
if (c<=clast-3 /* safe for four */
&& (UINTAT(c)&0xf0f0f0f0)==CHARMASK) { /* four digits */
UINTAT(ub)=UINTAT(c)&0x0f0f0f0f; /* to BCD8 */
ub+=4;
c+=3; /* [will become 4] */
continue;
}
if (*c=='.') continue; /* [ignore] */
*ub++=(uByte)(*c-'0');
}
ub--; /* -> LSD */
for (; c<=clast; c++) { /* inspect remaining chars */
if (*c!='0') { /* sticky bit needed */
if (*c=='.') continue; /* [ignore] */
*ub=DECSTICKYTAB[*ub]; /* update round-for-reround */
break; /* no need to look at more */
}
}
num.lsd=ub; /* record LSD */
/* adjust exponent for dropped digits */
num.exponent+=digits-(Int)(ub-buffer+1);
} /* too long for buffer */
} /* digits or dot */
else { /* no digits or dot were found */
if (*c=='\0') break; /* nothing to come is bad */
/* only Infinities and NaNs are allowed, here */
buffer[0]=0; /* default a coefficient of 0 */
num.lsd=buffer; /* .. */
if (decBiStr(c, "infinity", "INFINITY")
|| decBiStr(c, "inf", "INF")) num.exponent=DECFLOAT_Inf;
else { /* should be a NaN */
num.exponent=DECFLOAT_qNaN; /* assume quiet NaN */
if (*c=='s' || *c=='S') { /* probably an sNaN */
c++;
num.exponent=DECFLOAT_sNaN; /* assume is in fact sNaN */
}
if (*c!='N' && *c!='n') break; /* check caseless "NaN" */
c++;
if (*c!='a' && *c!='A') break; /* .. */
c++;
if (*c!='N' && *c!='n') break; /* .. */
c++;
/* now either nothing, or nnnn payload (no dots), expected */
/* -> start of integer, and skip leading 0s [including plain 0] */
for (cfirst=c; *cfirst=='0';) cfirst++;
if (*cfirst!='\0') { /* not empty or all-0, payload */
/* payload found; check all valid digits and copy to buffer as bcd8 */
ub=buffer;
for (c=cfirst;; c++, ub++) {
if ((unsigned)(*c-'0')>9) break; /* quit if not 0-9 */
if (c-cfirst==DECPMAX-1) break; /* too many digits */
*ub=(uByte)(*c-'0'); /* good bcd8 */
}
if (*c!='\0') break; /* not all digits, or too many */
num.lsd=ub-1; /* record new LSD */
}
} /* NaN or sNaN */
error=0; /* syntax is OK */
break; /* done with specials */
} /* digits=0 (special expected) */
break;
} /* [for(;;) break] */
/* decShowNum(&num, "fromStr"); */
if (error!=0) {
set->status|=error;
num.exponent=DECFLOAT_qNaN; /* set up quiet NaN */
num.sign=0; /* .. with 0 sign */
buffer[0]=0; /* .. and coefficient */
num.lsd=buffer; /* .. */
/* decShowNum(&num, "oops"); */
}
/* decShowNum(&num, "dffs"); */
decFinalize(result, &num, set); /* round, check, and lay out */
/* decFloatShow(result, "fromString"); */
return result;
} /* decFloatFromString */
/* ------------------------------------------------------------------ */
/* decFloatFromWider -- conversion from next-wider format */
/* */
/* result is the decFloat format number which gets the result of */
/* the conversion */
/* wider is the decFloatWider format number which will be narrowed */
/* set is the context */
/* returns result */
/* */
/* Narrowing can cause rounding, overflow, etc., but not Invalid */
/* operation (sNaNs are copied and do not signal). */
/* ------------------------------------------------------------------ */
/* narrow-to is not possible for decQuad format numbers; simply omit */
#if !QUAD
decFloat * decFloatFromWider(decFloat *result, const decFloatWider *wider,
decContext *set) {
bcdnum num; /* collects data for finishing */
uByte bcdar[DECWPMAX]; /* room for wider coefficient */
uInt widerhi=DFWWORD(wider, 0); /* top word */
Int exp;
GETWCOEFF(wider, bcdar);
num.msd=bcdar; /* MSD is here always */
num.lsd=bcdar+DECWPMAX-1; /* LSD is here always */
num.sign=widerhi&0x80000000; /* extract sign [DECFLOAT_Sign=Neg] */
/* decode the wider combination field to exponent */
exp=DECCOMBWEXP[widerhi>>26]; /* decode from wider combination field */
/* if it is a special there's nothing to do unless sNaN; if it's */
/* finite then add the (wider) exponent continuation and unbias */
if (EXPISSPECIAL(exp)) exp=widerhi&0x7e000000; /* include sNaN selector */
else exp+=GETWECON(wider)-DECWBIAS;
num.exponent=exp;
/* decShowNum(&num, "dffw"); */
return decFinalize(result, &num, set);/* round, check, and lay out */
} /* decFloatFromWider */
#endif
/* ------------------------------------------------------------------ */
/* decFloatGetCoefficient -- get coefficient as BCD8 */
/* */
/* df is the decFloat from which to extract the coefficient */
/* bcdar is where DECPMAX bytes will be written, one BCD digit in */
/* each byte (BCD8 encoding); if df is a NaN the first byte will */
/* be zero, and if it is infinite they will all be zero */
/* returns the sign of the coefficient (DECFLOAT_Sign if negative, */
/* 0 otherwise) */
/* */
/* No error is possible, and no status will be set. If df is a */
/* special value the array is set to zeros (for Infinity) or to the */
/* payload of a qNaN or sNaN. */
/* ------------------------------------------------------------------ */
Int decFloatGetCoefficient(const decFloat *df, uByte *bcdar) {
if (DFISINF(df)) memset(bcdar, 0, DECPMAX);
else {
GETCOEFF(df, bcdar); /* use macro */
if (DFISNAN(df)) bcdar[0]=0; /* MSD needs correcting */
}
return DFISSIGNED(df);
} /* decFloatGetCoefficient */
/* ------------------------------------------------------------------ */
/* decFloatGetExponent -- get unbiased exponent */
/* */
/* df is the decFloat from which to extract the exponent */
/* returns the exponent, q. */
/* */
/* No error is possible, and no status will be set. If df is a */
/* special value the first seven bits of the decFloat are returned, */
/* left adjusted and with the first (sign) bit set to 0 (followed by */
/* 25 0 bits). e.g., -sNaN would return 0x7e000000 (DECFLOAT_sNaN). */
/* ------------------------------------------------------------------ */
Int decFloatGetExponent(const decFloat *df) {
if (DFISSPECIAL(df)) return DFWORD(df, 0)&0x7e000000;
return GETEXPUN(df);
} /* decFloatGetExponent */
/* ------------------------------------------------------------------ */
/* decFloatSetCoefficient -- set coefficient from BCD8 */
/* */
/* df is the target decFloat (and source of exponent/special value) */
/* bcdar holds DECPMAX digits to set the coefficient from, one */
/* digit in each byte (BCD8 encoding); the first (MSD) is ignored */
/* if df is a NaN; all are ignored if df is infinite. */
/* sig is DECFLOAT_Sign to set the sign bit, 0 otherwise */
/* returns df, which will be canonical */
/* */
/* No error is possible, and no status will be set. */
/* ------------------------------------------------------------------ */
decFloat * decFloatSetCoefficient(decFloat *df, const uByte *bcdar,
Int sig) {
uInt exp; /* for exponent */
uByte bcdzero[DECPMAX]; /* for infinities */
/* Exponent/special code is extracted from df */
if (DFISSPECIAL(df)) {
exp=DFWORD(df, 0)&0x7e000000;
if (DFISINF(df)) {
memset(bcdzero, 0, DECPMAX);
return decFloatFromBCD(df, exp, bcdzero, sig);
}
}
else exp=GETEXPUN(df);
return decFloatFromBCD(df, exp, bcdar, sig);
} /* decFloatSetCoefficient */
/* ------------------------------------------------------------------ */
/* decFloatSetExponent -- set exponent or special value */
/* */
/* df is the target decFloat (and source of coefficient/payload) */
/* set is the context for reporting status */
/* exp is the unbiased exponent, q, or a special value in the form */
/* returned by decFloatGetExponent */
/* returns df, which will be canonical */
/* */
/* No error is possible, but Overflow or Underflow might occur. */
/* ------------------------------------------------------------------ */
decFloat * decFloatSetExponent(decFloat *df, decContext *set, Int exp) {
uByte bcdcopy[DECPMAX]; /* for coefficient */
bcdnum num; /* work */
num.exponent=exp;
num.sign=decFloatGetCoefficient(df, bcdcopy); /* extract coefficient */
if (DFISSPECIAL(df)) { /* MSD or more needs correcting */
if (DFISINF(df)) memset(bcdcopy, 0, DECPMAX);
bcdcopy[0]=0;
}
num.msd=bcdcopy;
num.lsd=bcdcopy+DECPMAX-1;
return decFinalize(df, &num, set);
} /* decFloatSetExponent */
/* ------------------------------------------------------------------ */
/* decFloatRadix -- returns the base (10) */
/* */
/* df is any decFloat of this format */
/* ------------------------------------------------------------------ */
uInt decFloatRadix(const decFloat *df) {
if (df) return 10; /* to placate compiler */
return 10;
} /* decFloatRadix */
/* ------------------------------------------------------------------ */
/* decFloatShow -- printf a decFloat in hexadecimal and decimal */
/* df is the decFloat to show */
/* tag is a tag string displayed with the number */
/* */
/* This is a debug aid; the precise format of the string may change. */
/* ------------------------------------------------------------------ */
void decFloatShow(const decFloat *df, const char *tag) {
char hexbuf[DECBYTES*2+DECBYTES/4+1]; /* NB blank after every fourth */
char buff[DECSTRING]; /* for value in decimal */
Int i, j=0;
for (i=0; i<DECBYTES; i++) {
#if DECLITEND
sprintf(&hexbuf[j], "%02x", df->bytes[DECBYTES-1-i]);
#else
sprintf(&hexbuf[j], "%02x", df->bytes[i]);
#endif
j+=2;
/* the next line adds blank (and terminator) after final pair, too */
if ((i+1)%4==0) {strcpy(&hexbuf[j], " "); j++;}
}
decFloatToString(df, buff);
printf(">%s> %s [big-endian] %s\n", tag, hexbuf, buff);
return;
} /* decFloatShow */
/* ------------------------------------------------------------------ */
/* decFloatToBCD -- get sign, exponent, and BCD8 from a decFloat */
/* */
/* df is the source decFloat */
/* exp will be set to the unbiased exponent, q, or to a special */
/* value in the form returned by decFloatGetExponent */
/* bcdar is where DECPMAX bytes will be written, one BCD digit in */
/* each byte (BCD8 encoding); if df is a NaN the first byte will */
/* be zero, and if it is infinite they will all be zero */
/* returns the sign of the coefficient (DECFLOAT_Sign if negative, */
/* 0 otherwise) */
/* */
/* No error is possible, and no status will be set. */
/* ------------------------------------------------------------------ */
Int decFloatToBCD(const decFloat *df, Int *exp, uByte *bcdar) {
if (DFISINF(df)) {
memset(bcdar, 0, DECPMAX);
*exp=DFWORD(df, 0)&0x7e000000;
}
else {
GETCOEFF(df, bcdar); /* use macro */
if (DFISNAN(df)) {
bcdar[0]=0; /* MSD needs correcting */
*exp=DFWORD(df, 0)&0x7e000000;
}
else { /* finite */
*exp=GETEXPUN(df);
}
}
return DFISSIGNED(df);
} /* decFloatToBCD */
/* ------------------------------------------------------------------ */
/* decFloatToEngString -- conversion to numeric string, engineering */
/* */
/* df is the decFloat format number to convert */
/* string is the string where the result will be laid out */
/* */
/* string must be at least DECPMAX+9 characters (the worst case is */
/* "-0.00000nnn...nnn\0", which is as long as the exponent form when */
/* DECEMAXD<=4); this condition is asserted above */
/* */
/* No error is possible, and no status will be set */
/* ------------------------------------------------------------------ */
char * decFloatToEngString(const decFloat *df, char *string){
uInt msd; /* coefficient MSD */
Int exp; /* exponent top two bits or full */
uInt comb; /* combination field */
char *cstart; /* coefficient start */
char *c; /* output pointer in string */
char *s, *t; /* .. (source, target) */
Int pre, e; /* work */
const uByte *u; /* .. */
/* Source words; macro handles endianness */
uInt sourhi=DFWORD(df, 0); /* word with sign */
#if DECPMAX==16
uInt sourlo=DFWORD(df, 1);
#elif DECPMAX==34
uInt sourmh=DFWORD(df, 1);
uInt sourml=DFWORD(df, 2);
uInt sourlo=DFWORD(df, 3);
#endif
c=string; /* where result will go */
if (((Int)sourhi)<0) *c++='-'; /* handle sign */
comb=sourhi>>26; /* sign+combination field */
msd=DECCOMBMSD[comb]; /* decode the combination field */
exp=DECCOMBEXP[comb]; /* .. */
if (EXPISSPECIAL(exp)) { /* special */
if (exp==DECFLOAT_Inf) { /* infinity */
strcpy(c, "Inf");
strcpy(c+3, "inity");
return string; /* easy */
}
if (sourhi&0x02000000) *c++='s'; /* sNaN */
strcpy(c, "NaN"); /* complete word */
c+=3; /* step past */
/* quick exit if the payload is zero */
#if DECPMAX==7
if ((sourhi&0x000fffff)==0) return string;
#elif DECPMAX==16
if (sourlo==0 && (sourhi&0x0003ffff)==0) return string;
#elif DECPMAX==34
if (sourlo==0 && sourml==0 && sourmh==0
&& (sourhi&0x00003fff)==0) return string;
#endif
/* otherwise drop through to add integer; set correct exp etc. */
exp=0; msd=0; /* setup for following code */
}
else { /* complete exponent; top two bits are in place */
exp+=GETECON(df)-DECBIAS; /* .. + continuation and unbias */
}
/* convert the digits of the significand to characters */
cstart=c; /* save start of coefficient */
if (msd) *c++=(char)('0'+(char)msd); /* non-zero most significant digit */
/* Decode the declets. After extracting each declet, it is */
/* decoded to a 4-uByte sequence by table lookup; the four uBytes */
/* are the three encoded BCD8 digits followed by a 1-byte length */
/* (significant digits, except that 000 has length 0). This allows */
/* us to left-align the first declet with non-zero content, then */
/* the remaining ones are full 3-char length. Fixed-length copies */
/* are used because variable-length memcpy causes a subroutine call */
/* in at least two compilers. (The copies are length 4 for speed */
/* and are safe because the last item in the array is of length */
/* three and has the length byte following.) */
#define dpd2char(dpdin) u=&DPD2BCD8[((dpdin)&0x3ff)*4]; \
if (c!=cstart) {UINTAT(c)=UINTAT(u)|CHARMASK; c+=3;} \
else if (*(u+3)) { \
UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; c+=*(u+3);}
#if DECPMAX==7
dpd2char(sourhi>>10); /* declet 1 */
dpd2char(sourhi); /* declet 2 */
#elif DECPMAX==16
dpd2char(sourhi>>8); /* declet 1 */
dpd2char((sourhi<<2) | (sourlo>>30)); /* declet 2 */
dpd2char(sourlo>>20); /* declet 3 */
dpd2char(sourlo>>10); /* declet 4 */
dpd2char(sourlo); /* declet 5 */
#elif DECPMAX==34
dpd2char(sourhi>>4); /* declet 1 */
dpd2char((sourhi<<6) | (sourmh>>26)); /* declet 2 */
dpd2char(sourmh>>16); /* declet 3 */
dpd2char(sourmh>>6); /* declet 4 */
dpd2char((sourmh<<4) | (sourml>>28)); /* declet 5 */
dpd2char(sourml>>18); /* declet 6 */
dpd2char(sourml>>8); /* declet 7 */
dpd2char((sourml<<2) | (sourlo>>30)); /* declet 8 */
dpd2char(sourlo>>20); /* declet 9 */
dpd2char(sourlo>>10); /* declet 10 */
dpd2char(sourlo); /* declet 11 */
#endif
if (c==cstart) *c++='0'; /* all zeros, empty -- make "0" */
if (exp==0) { /* integer or NaN case -- easy */
*c='\0'; /* terminate */
return string;
}
/* non-0 exponent */
e=0; /* assume no E */
pre=(Int)(c-cstart)+exp; /* length+exp [c->LSD+1] */
/* [here, pre-exp is the digits count (==1 for zero)] */
if (exp>0 || pre<-5) { /* need exponential form */
e=pre-1; /* calculate E value */
pre=1; /* assume one digit before '.' */
if (e!=0) { /* engineering: may need to adjust */
Int adj; /* adjustment */
/* The C remainder operator is undefined for negative numbers, so */
/* a positive remainder calculation must be used here */
if (e<0) {
adj=(-e)%3;
if (adj!=0) adj=3-adj;
}
else { /* e>0 */
adj=e%3;
}
e=e-adj;
/* if dealing with zero still produce an exponent which is a */
/* multiple of three, as expected, but there will only be the */
/* one zero before the E, still. Otherwise note the padding. */
if (!DFISZERO(df)) pre+=adj;
else { /* is zero */
if (adj!=0) { /* 0.00Esnn needed */
e=e+3;
pre=-(2-adj);
}
} /* zero */
} /* engineering adjustment */
} /* exponential form */
/* printf("e=%ld pre=%ld exp=%ld\n", (LI)e, (LI)pre, (LI)exp); */
/* modify the coefficient, adding 0s, '.', and E+nn as needed */
if (pre>0) { /* ddd.ddd (plain), perhaps with E */
/* or dd00 padding for engineering */
char *dotat=cstart+pre;
if (dotat<c) { /* if embedded dot needed... */
/* move by fours; there must be space for junk at the end */
/* because there is still space for exponent */
s=dotat+ROUNDDOWN4(c-dotat); /* source */
t=s+1; /* target */
/* open the gap */
for (; s>=dotat; s-=4, t-=4) UINTAT(t)=UINTAT(s);
*dotat='.';
c++; /* length increased by one */
} /* need dot? */
else for (; c<dotat; c++) *c='0'; /* pad for engineering */
} /* pre>0 */
else {
/* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (may have
E, but only for 0.00E+3 kind of case -- with plenty of spare
space in this case */
pre=-pre+2; /* gap width, including "0." */
t=cstart+ROUNDDOWN4(c-cstart)+pre; /* preferred first target point */
/* backoff if too far to the right */
if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */
/* now shift the entire coefficient to the right, being careful not */
/* to access to the left of string */
for (s=t-pre; s>=string; s-=4, t-=4) UINTAT(t)=UINTAT(s);
/* for Quads and Singles there may be a character or two left... */
s+=3; /* where next would come from */
for(; s>=cstart; s--, t--) *(t+3)=*(s);
/* now have fill 0. through 0.00000; use overlaps to avoid tests */
if (pre>=4) {
UINTAT(cstart+pre-4)=UINTAT("0000");
UINTAT(cstart)=UINTAT("0.00");
}
else { /* 2 or 3 */
*(cstart+pre-1)='0';
USHORTAT(cstart)=USHORTAT("0.");
}
c+=pre; /* to end */
}
/* finally add the E-part, if needed; it will never be 0, and has */
/* a maximum length of 3 or 4 digits (asserted above) */
if (e!=0) {
USHORTAT(c)=USHORTAT("E+"); /* starts with E, assume + */
c++;
if (e<0) {
*c='-'; /* oops, need '-' */
e=-e; /* uInt, please */
}
c++;
/* Three-character exponents are easy; 4-character a little trickier */
#if DECEMAXD<=3
u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */
/* copy fixed 4 characters [is safe], starting at non-zero */
/* and with character mask to convert BCD to char */
UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK;
c+=*(u+3); /* bump pointer appropriately */
#elif DECEMAXD==4
if (e<1000) { /* 3 (or fewer) digits case */
u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */
UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; /* [as above] */
c+=*(u+3); /* bump pointer appropriately */
}
else { /* 4-digits */
Int thou=((e>>3)*1049)>>17; /* e/1000 */
Int rem=e-(1000*thou); /* e%1000 */
*c++=(char)('0'+(char)thou); /* the thousands digit */
u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */
UINTAT(c)=UINTAT(u)|CHARMASK; /* copy fixed 3+1 characters [is safe] */
c+=3; /* bump pointer, always 3 digits */
}
#endif
}
*c='\0'; /* terminate */
/*printf("res %s\n", string); */
return string;
} /* decFloatToEngString */
/* ------------------------------------------------------------------ */
/* decFloatToPacked -- convert decFloat to Packed decimal + exponent */
/* */
/* df is the source decFloat */
/* exp will be set to the unbiased exponent, q, or to a special */
/* value in the form returned by decFloatGetExponent */
/* packed is where DECPMAX nibbles will be written with the sign as */
/* final nibble (0x0c for +, 0x0d for -); a NaN has a first nibble */
/* of zero, and an infinity is all zeros. decDouble and decQuad */
/* have a additional leading zero nibble, leading to result */
/* lengths of 4, 9, and 18 bytes. */
/* returns the sign of the coefficient (DECFLOAT_Sign if negative, */
/* 0 otherwise) */
/* */
/* No error is possible, and no status will be set. */
/* ------------------------------------------------------------------ */
Int decFloatToPacked(const decFloat *df, Int *exp, uByte *packed) {
uByte bcdar[DECPMAX+2]; /* work buffer */
uByte *ip=bcdar, *op=packed; /* work pointers */
if (DFISINF(df)) {
memset(bcdar, 0, DECPMAX+2);
*exp=DECFLOAT_Inf;
}
else {
GETCOEFF(df, bcdar+1); /* use macro */
if (DFISNAN(df)) {
bcdar[1]=0; /* MSD needs clearing */
*exp=DFWORD(df, 0)&0x7e000000;
}
else { /* finite */
*exp=GETEXPUN(df);
}
}
/* now pack; coefficient currently at bcdar+1 */
#if SINGLE
ip++; /* ignore first byte */
#else
*ip=0; /* need leading zero */
#endif
/* set final byte to Packed BCD sign value */
bcdar[DECPMAX+1]=(DFISSIGNED(df) ? DECPMINUS : DECPPLUS);
/* pack an even number of bytes... */
for (; op<packed+((DECPMAX+2)/2); op++, ip+=2) {
*op=(uByte)((*ip<<4)+*(ip+1));
}
return (bcdar[DECPMAX+1]==DECPMINUS ? DECFLOAT_Sign : 0);
} /* decFloatToPacked */
/* ------------------------------------------------------------------ */
/* decFloatToString -- conversion to numeric string */
/* */
/* df is the decFloat format number to convert */
/* string is the string where the result will be laid out */
/* */
/* string must be at least DECPMAX+9 characters (the worst case is */
/* "-0.00000nnn...nnn\0", which is as long as the exponent form when */
/* DECEMAXD<=4); this condition is asserted above */
/* */
/* No error is possible, and no status will be set */
/* ------------------------------------------------------------------ */
char * decFloatToString(const decFloat *df, char *string){
uInt msd; /* coefficient MSD */
Int exp; /* exponent top two bits or full */
uInt comb; /* combination field */
char *cstart; /* coefficient start */
char *c; /* output pointer in string */
char *s, *t; /* .. (source, target) */
Int pre, e; /* work */
const uByte *u; /* .. */
/* Source words; macro handles endianness */
uInt sourhi=DFWORD(df, 0); /* word with sign */
#if DECPMAX==16
uInt sourlo=DFWORD(df, 1);
#elif DECPMAX==34
uInt sourmh=DFWORD(df, 1);
uInt sourml=DFWORD(df, 2);
uInt sourlo=DFWORD(df, 3);
#endif
c=string; /* where result will go */
if (((Int)sourhi)<0) *c++='-'; /* handle sign */
comb=sourhi>>26; /* sign+combination field */
msd=DECCOMBMSD[comb]; /* decode the combination field */
exp=DECCOMBEXP[comb]; /* .. */
if (EXPISSPECIAL(exp)) { /* special */
if (exp==DECFLOAT_Inf) { /* infinity */
strcpy(c, "Infinity");
return string; /* easy */
}
if (sourhi&0x02000000) *c++='s'; /* sNaN */
strcpy(c, "NaN"); /* complete word */
c+=3; /* step past */
/* quick exit if the payload is zero */
#if DECPMAX==7
if ((sourhi&0x000fffff)==0) return string;
#elif DECPMAX==16
if (sourlo==0 && (sourhi&0x0003ffff)==0) return string;
#elif DECPMAX==34
if (sourlo==0 && sourml==0 && sourmh==0
&& (sourhi&0x00003fff)==0) return string;
#endif
/* otherwise drop through to add integer; set correct exp etc. */
exp=0; msd=0; /* setup for following code */
}
else { /* complete exponent; top two bits are in place */
exp+=GETECON(df)-DECBIAS; /* .. + continuation and unbias */
}
/* convert the digits of the significand to characters */
cstart=c; /* save start of coefficient */
if (msd) *c++=(char)('0'+(char)msd); /* non-zero most significant digit */
/* Decode the declets. After extracting each declet, it is */
/* decoded to a 4-uByte sequence by table lookup; the four uBytes */
/* are the three encoded BCD8 digits followed by a 1-byte length */
/* (significant digits, except that 000 has length 0). This allows */
/* us to left-align the first declet with non-zero content, then */
/* the remaining ones are full 3-char length. Fixed-length copies */
/* are used because variable-length memcpy causes a subroutine call */
/* in at least two compilers. (The copies are length 4 for speed */
/* and are safe because the last item in the array is of length */
/* three and has the length byte following.) */
#define dpd2char(dpdin) u=&DPD2BCD8[((dpdin)&0x3ff)*4]; \
if (c!=cstart) {UINTAT(c)=UINTAT(u)|CHARMASK; c+=3;} \
else if (*(u+3)) { \
UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; c+=*(u+3);}
#if DECPMAX==7
dpd2char(sourhi>>10); /* declet 1 */
dpd2char(sourhi); /* declet 2 */
#elif DECPMAX==16
dpd2char(sourhi>>8); /* declet 1 */
dpd2char((sourhi<<2) | (sourlo>>30)); /* declet 2 */
dpd2char(sourlo>>20); /* declet 3 */
dpd2char(sourlo>>10); /* declet 4 */
dpd2char(sourlo); /* declet 5 */
#elif DECPMAX==34
dpd2char(sourhi>>4); /* declet 1 */
dpd2char((sourhi<<6) | (sourmh>>26)); /* declet 2 */
dpd2char(sourmh>>16); /* declet 3 */
dpd2char(sourmh>>6); /* declet 4 */
dpd2char((sourmh<<4) | (sourml>>28)); /* declet 5 */
dpd2char(sourml>>18); /* declet 6 */
dpd2char(sourml>>8); /* declet 7 */
dpd2char((sourml<<2) | (sourlo>>30)); /* declet 8 */
dpd2char(sourlo>>20); /* declet 9 */
dpd2char(sourlo>>10); /* declet 10 */
dpd2char(sourlo); /* declet 11 */
#endif
if (c==cstart) *c++='0'; /* all zeros, empty -- make "0" */
/*[This fast path is valid but adds 3-5 cycles to worst case length] */
/*if (exp==0) { // integer or NaN case -- easy */
/* *c='\0'; // terminate */
/* return string; */
/* } */
e=0; /* assume no E */
pre=(Int)(c-cstart)+exp; /* length+exp [c->LSD+1] */
/* [here, pre-exp is the digits count (==1 for zero)] */
if (exp>0 || pre<-5) { /* need exponential form */
e=pre-1; /* calculate E value */
pre=1; /* assume one digit before '.' */
} /* exponential form */
/* modify the coefficient, adding 0s, '.', and E+nn as needed */
if (pre>0) { /* ddd.ddd (plain), perhaps with E */
char *dotat=cstart+pre;
if (dotat<c) { /* if embedded dot needed... */
/* move by fours; there must be space for junk at the end */
/* because there is still space for exponent */
s=dotat+ROUNDDOWN4(c-dotat); /* source */
t=s+1; /* target */
/* open the gap */
for (; s>=dotat; s-=4, t-=4) UINTAT(t)=UINTAT(s);
*dotat='.';
c++; /* length increased by one */
} /* need dot? */
/* finally add the E-part, if needed; it will never be 0, and has */
/* a maximum length of 3 or 4 digits (asserted above) */
if (e!=0) {
USHORTAT(c)=USHORTAT("E+"); /* starts with E, assume + */
c++;
if (e<0) {
*c='-'; /* oops, need '-' */
e=-e; /* uInt, please */
}
c++;
/* Three-character exponents are easy; 4-character a little trickier */
#if DECEMAXD<=3
u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */
/* copy fixed 4 characters [is safe], starting at non-zero */
/* and with character mask to convert BCD to char */
UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK;
c+=*(u+3); /* bump pointer appropriately */
#elif DECEMAXD==4
if (e<1000) { /* 3 (or fewer) digits case */
u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */
UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; /* [as above] */
c+=*(u+3); /* bump pointer appropriately */
}
else { /* 4-digits */
Int thou=((e>>3)*1049)>>17; /* e/1000 */
Int rem=e-(1000*thou); /* e%1000 */
*c++=(char)('0'+(char)thou); /* the thousands digit */
u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */
UINTAT(c)=UINTAT(u)|CHARMASK; /* copy fixed 3+1 characters [is safe] */
c+=3; /* bump pointer, always 3 digits */
}
#endif
}
*c='\0'; /* add terminator */
/*printf("res %s\n", string); */
return string;
} /* pre>0 */
/* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (can never have E) */
/* Surprisingly, this is close to being the worst-case path, so the */
/* shift is done by fours; this is a little tricky because the */
/* rightmost character to be written must not be beyond where the */
/* rightmost terminator could be -- so backoff to not touch */
/* terminator position if need be (this can make exact alignments */
/* for full Doubles, but in some cases needs care not to access too */
/* far to the left) */
pre=-pre+2; /* gap width, including "0." */
t=cstart+ROUNDDOWN4(c-cstart)+pre; /* preferred first target point */
/* backoff if too far to the right */
if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */
/* now shift the entire coefficient to the right, being careful not */
/* to access to the left of string */
for (s=t-pre; s>=string; s-=4, t-=4) UINTAT(t)=UINTAT(s);
/* for Quads and Singles there may be a character or two left... */
s+=3; /* where next would come from */
for(; s>=cstart; s--, t--) *(t+3)=*(s);
/* now have fill 0. through 0.00000; use overlaps to avoid tests */
if (pre>=4) {
UINTAT(cstart+pre-4)=UINTAT("0000");
UINTAT(cstart)=UINTAT("0.00");
}
else { /* 2 or 3 */
*(cstart+pre-1)='0';
USHORTAT(cstart)=USHORTAT("0.");
}
*(c+pre)='\0'; /* terminate */
return string;
} /* decFloatToString */
/* ------------------------------------------------------------------ */
/* decFloatToWider -- conversion to next-wider format */
/* */
/* source is the decFloat format number which gets the result of */
/* the conversion */
/* wider is the decFloatWider format number which will be narrowed */
/* returns wider */
/* */
/* Widening is always exact; no status is set (sNaNs are copied and */
/* do not signal). The result will be canonical if the source is, */
/* and may or may not be if the source is not. */
/* ------------------------------------------------------------------ */
/* widening is not possible for decQuad format numbers; simply omit */
#if !QUAD
decFloatWider * decFloatToWider(const decFloat *source, decFloatWider *wider) {
uInt msd;
/* Construct and copy the sign word */
if (DFISSPECIAL(source)) {
/* copy sign, combination, and first bit of exponent (sNaN selector) */
DFWWORD(wider, 0)=DFWORD(source, 0)&0xfe000000;
msd=0;
}
else { /* is finite number */
uInt exp=GETEXPUN(source)+DECWBIAS; /* get unbiased exponent and rebias */
uInt code=(exp>>DECWECONL)<<29; /* set two bits of exp [msd=0] */
code|=(exp<<(32-6-DECWECONL)) & 0x03ffffff; /* add exponent continuation */
code|=DFWORD(source, 0)&0x80000000; /* add sign */
DFWWORD(wider, 0)=code; /* .. and place top word in wider */
msd=GETMSD(source); /* get source coefficient MSD [0-9] */
}
/* Copy the coefficient and clear any 'unused' words to left */
#if SINGLE
DFWWORD(wider, 1)=(DFWORD(source, 0)&0x000fffff)|(msd<<20);
#elif DOUBLE
DFWWORD(wider, 2)=(DFWORD(source, 0)&0x0003ffff)|(msd<<18);
DFWWORD(wider, 3)=DFWORD(source, 1);
DFWWORD(wider, 1)=0;
#endif
return wider;
} /* decFloatToWider */
#endif
/* ------------------------------------------------------------------ */
/* decFloatVersion -- return package version string */
/* */
/* returns a constant string describing this package */
/* ------------------------------------------------------------------ */
const char *decFloatVersion(void) {
return DECVERSION;
} /* decFloatVersion */
/* ------------------------------------------------------------------ */
/* decFloatZero -- set to canonical (integer) zero */
/* */
/* df is the decFloat format number to integer +0 (q=0, c=+0) */
/* returns df */
/* */
/* No error is possible, and no status can be set. */
/* ------------------------------------------------------------------ */
decFloat * decFloatZero(decFloat *df){
DFWORD(df, 0)=ZEROWORD; /* set appropriate top word */
#if DOUBLE || QUAD
DFWORD(df, 1)=0;
#if QUAD
DFWORD(df, 2)=0;
DFWORD(df, 3)=0;
#endif
#endif
/* decFloatShow(df, "zero"); */
return df;
} /* decFloatZero */
/* ------------------------------------------------------------------ */
/* Private generic function (not format-specific) for development use */
/* ------------------------------------------------------------------ */
/* This is included once only, for all to use */
#if QUAD && (DECCHECK || DECTRACE)
/* ---------------------------------------------------------------- */
/* decShowNum -- display bcd8 number in debug form */
/* */
/* num is the bcdnum to display */
/* tag is a string to label the display */
/* ---------------------------------------------------------------- */
void decShowNum(const bcdnum *num, const char *tag) {
const char *csign="+"; /* sign character */
uByte *ub; /* work */
if (num->sign==DECFLOAT_Sign) csign="-";
printf(">%s> ", tag);
if (num->exponent==DECFLOAT_Inf) printf("%sInfinity", csign);
else if (num->exponent==DECFLOAT_qNaN) printf("%sqNaN", csign);
else if (num->exponent==DECFLOAT_sNaN) printf("%ssNaN", csign);
else { /* finite */
char qbuf[10]; /* for right-aligned q */
char *c; /* work */
const uByte *u; /* .. */
Int e=num->exponent; /* .. exponent */
strcpy(qbuf, "q=");
c=&qbuf[2]; /* where exponent will go */
/* lay out the exponent */
if (e<0) {
*c++='-'; /* add '-' */
e=-e; /* uInt, please */
}
#if DECEMAXD>4
#error Exponent form is too long for ShowNum to lay out
#endif
if (e==0) *c++='0'; /* 0-length case */
else if (e<1000) { /* 3 (or fewer) digits case */
u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */
UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; /* [as above] */
c+=*(u+3); /* bump pointer appropriately */
}
else { /* 4-digits */
Int thou=((e>>3)*1049)>>17; /* e/1000 */
Int rem=e-(1000*thou); /* e%1000 */
*c++=(char)('0'+(char)thou); /* the thousands digit */
u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */
UINTAT(c)=UINTAT(u)|CHARMASK; /* copy fixed 3+1 characters [is safe] */
c+=3; /* bump pointer, always 3 digits */
}
*c='\0'; /* add terminator */
printf("%7s c=%s", qbuf, csign);
}
if (!EXPISSPECIAL(num->exponent) || num->msd!=num->lsd || *num->lsd!=0) {
for (ub=num->msd; ub<=num->lsd; ub++) { /* coefficient... */
printf("%1x", *ub);
if ((num->lsd-ub)%3==0 && ub!=num->lsd) printf(" "); /* 4-space */
}
}
printf("\n");
} /* decShowNum */
#endif
/* Decimal context module for the decNumber C Library. /* Decimal context module for the decNumber C Library.
Copyright (C) 2005 Free Software Foundation, Inc. Copyright (C) 2005, 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw. Contributed by IBM Corporation. Author Mike Cowlishaw.
This file is part of GCC. This file is part of GCC.
...@@ -28,14 +28,52 @@ ...@@ -28,14 +28,52 @@
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */ 02110-1301, USA. */
/* This module compirises the routines for handling the arithmetic /* ------------------------------------------------------------------ */
context structures. */ /* Decimal Context module */
/* ------------------------------------------------------------------ */
/* This module comprises the routines for handling arithmetic */
/* context structures. */
/* ------------------------------------------------------------------ */
#include <string.h> /* for strcmp */ #include <string.h> /* for strcmp */
#include "config.h" #include <stdio.h> /* for printf if DECCHECK */
#include "config.h" /* for GCC definitions */
#include "decContext.h" /* context and base types */ #include "decContext.h" /* context and base types */
#include "decNumberLocal.h" /* decNumber local types, etc. */ #include "decNumberLocal.h" /* decNumber local types, etc. */
#if DECCHECK
/* compile-time endian tester [assumes sizeof(Int)>1] */
static const Int mfcone=1; /* constant 1 */
static const Flag *mfctop=(Flag *)&mfcone; /* -> top byte */
#define LITEND *mfctop /* named flag; 1=little-endian */
#endif
/* ------------------------------------------------------------------ */
/* round-for-reround digits */
/* ------------------------------------------------------------------ */
const uByte DECSTICKYTAB[10]={1,1,2,3,4,6,6,7,8,9}; /* used if sticky */
/* ------------------------------------------------------------------ */
/* Powers of ten (powers[n]==10**n, 0<=n<=9) */
/* ------------------------------------------------------------------ */
const uInt DECPOWERS[10]={1, 10, 100, 1000, 10000, 100000, 1000000,
10000000, 100000000, 1000000000};
/* ------------------------------------------------------------------ */
/* decContextClearStatus -- clear bits in current status */
/* */
/* context is the context structure to be queried */
/* mask indicates the bits to be cleared (the status bit that */
/* corresponds to each 1 bit in the mask is cleared) */
/* returns context */
/* */
/* No error is possible. */
/* ------------------------------------------------------------------ */
decContext *decContextClearStatus(decContext *context, uInt mask) {
context->status&=~mask;
return context;
} /* decContextClearStatus */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* decContextDefault -- initialize a context structure */ /* decContextDefault -- initialize a context structure */
/* */ /* */
...@@ -49,117 +87,163 @@ ...@@ -49,117 +87,163 @@
/* Invalid_operation set in the status field. */ /* Invalid_operation set in the status field. */
/* returns a context structure with the appropriate initial values. */ /* returns a context structure with the appropriate initial values. */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
decContext * decContext * decContextDefault(decContext *context, Int kind) {
decContextDefault (decContext * context, Int kind)
{
/* set defaults... */ /* set defaults... */
context->digits = 9; /* 9 digits */ context->digits=9; /* 9 digits */
context->emax = DEC_MAX_EMAX; /* 9-digit exponents */ context->emax=DEC_MAX_EMAX; /* 9-digit exponents */
context->emin = DEC_MIN_EMIN; /* .. balanced */ context->emin=DEC_MIN_EMIN; /* .. balanced */
context->round = DEC_ROUND_HALF_UP; /* 0.5 rises */ context->round=DEC_ROUND_HALF_UP; /* 0.5 rises */
context->traps = DEC_Errors; /* all but informational */ context->traps=DEC_Errors; /* all but informational */
context->status = 0; /* cleared */ context->status=0; /* cleared */
context->clamp = 0; /* no clamping */ context->clamp=0; /* no clamping */
#if DECSUBSET #if DECSUBSET
context->extended = 0; /* cleared */ context->extended=0; /* cleared */
#endif #endif
switch (kind) switch (kind) {
{
case DEC_INIT_BASE: case DEC_INIT_BASE:
/* [use defaults] */ /* [use defaults] */
break; break;
case DEC_INIT_DECIMAL32: case DEC_INIT_DECIMAL32:
context->digits = 7; /* digits */ context->digits=7; /* digits */
context->emax = 96; /* Emax */ context->emax=96; /* Emax */
context->emin = -95; /* Emin */ context->emin=-95; /* Emin */
context->round = DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */ context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
context->traps = 0; /* no traps set */ context->traps=0; /* no traps set */
context->clamp = 1; /* clamp exponents */ context->clamp=1; /* clamp exponents */
#if DECSUBSET #if DECSUBSET
context->extended = 1; /* set */ context->extended=1; /* set */
#endif #endif
break; break;
case DEC_INIT_DECIMAL64: case DEC_INIT_DECIMAL64:
context->digits = 16; /* digits */ context->digits=16; /* digits */
context->emax = 384; /* Emax */ context->emax=384; /* Emax */
context->emin = -383; /* Emin */ context->emin=-383; /* Emin */
context->round = DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */ context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
context->traps = 0; /* no traps set */ context->traps=0; /* no traps set */
context->clamp = 1; /* clamp exponents */ context->clamp=1; /* clamp exponents */
#if DECSUBSET #if DECSUBSET
context->extended = 1; /* set */ context->extended=1; /* set */
#endif #endif
break; break;
case DEC_INIT_DECIMAL128: case DEC_INIT_DECIMAL128:
context->digits = 34; /* digits */ context->digits=34; /* digits */
context->emax = 6144; /* Emax */ context->emax=6144; /* Emax */
context->emin = -6143; /* Emin */ context->emin=-6143; /* Emin */
context->round = DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */ context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
context->traps = 0; /* no traps set */ context->traps=0; /* no traps set */
context->clamp = 1; /* clamp exponents */ context->clamp=1; /* clamp exponents */
#if DECSUBSET #if DECSUBSET
context->extended = 1; /* set */ context->extended=1; /* set */
#endif #endif
break; break;
default: /* invalid Kind */ default: /* invalid Kind */
/* use defaults, and .. */ /* use defaults, and .. */
decContextSetStatus (context, DEC_Invalid_operation); /* trap */ decContextSetStatus(context, DEC_Invalid_operation); /* trap */
} }
#if DECCHECK
if (LITEND!=DECLITEND) {
const char *adj;
if (LITEND) adj="little";
else adj="big";
printf("Warning: DECLITEND is set to %d, but this computer appears to be %s-endian\n",
DECLITEND, adj);
}
#endif
return context;} /* decContextDefault */
/* ------------------------------------------------------------------ */
/* decContextGetRounding -- return current rounding mode */
/* */
/* context is the context structure to be queried */
/* returns the rounding mode */
/* */
/* No error is possible. */
/* ------------------------------------------------------------------ */
enum rounding decContextGetRounding(decContext *context) {
return context->round;
} /* decContextGetRounding */
/* ------------------------------------------------------------------ */
/* decContextGetStatus -- return current status */
/* */
/* context is the context structure to be queried */
/* returns status */
/* */
/* No error is possible. */
/* ------------------------------------------------------------------ */
uInt decContextGetStatus(decContext *context) {
return context->status;
} /* decContextGetStatus */
/* ------------------------------------------------------------------ */
/* decContextRestoreStatus -- restore bits in current status */
/* */
/* context is the context structure to be updated */
/* newstatus is the source for the bits to be restored */
/* mask indicates the bits to be restored (the status bit that */
/* corresponds to each 1 bit in the mask is set to the value of */
/* the correspnding bit in newstatus) */
/* returns context */
/* */
/* No error is possible. */
/* ------------------------------------------------------------------ */
decContext *decContextRestoreStatus(decContext *context,
uInt newstatus, uInt mask) {
context->status&=~mask; /* clear the selected bits */
context->status|=(mask&newstatus); /* or in the new bits */
return context; return context;
} /* decContextDefault */ } /* decContextRestoreStatus */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* decContextStatusToString -- convert status flags to a string */ /* decContextSaveStatus -- save bits in current status */
/* */ /* */
/* context is a context with valid status field */ /* context is the context structure to be queried */
/* mask indicates the bits to be saved (the status bits that */
/* correspond to each 1 bit in the mask are saved) */
/* returns the AND of the mask and the current status */
/* */ /* */
/* returns a constant string describing the condition. If multiple */ /* No error is possible. */
/* (or no) flags are set, a generic constant message is returned. */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
const char * uInt decContextSaveStatus(decContext *context, uInt mask) {
decContextStatusToString (const decContext * context) return context->status&mask;
{ } /* decContextSaveStatus */
Int status = context->status;
if (status == DEC_Conversion_syntax)
return DEC_Condition_CS;
if (status == DEC_Division_by_zero)
return DEC_Condition_DZ;
if (status == DEC_Division_impossible)
return DEC_Condition_DI;
if (status == DEC_Division_undefined)
return DEC_Condition_DU;
if (status == DEC_Inexact)
return DEC_Condition_IE;
if (status == DEC_Insufficient_storage)
return DEC_Condition_IS;
if (status == DEC_Invalid_context)
return DEC_Condition_IC;
if (status == DEC_Invalid_operation)
return DEC_Condition_IO;
#if DECSUBSET
if (status == DEC_Lost_digits)
return DEC_Condition_LD;
#endif
if (status == DEC_Overflow)
return DEC_Condition_OV;
if (status == DEC_Clamped)
return DEC_Condition_PA;
if (status == DEC_Rounded)
return DEC_Condition_RO;
if (status == DEC_Subnormal)
return DEC_Condition_SU;
if (status == DEC_Underflow)
return DEC_Condition_UN;
if (status == 0)
return DEC_Condition_ZE;
return DEC_Condition_MU; /* Multiple errors */
} /* decContextStatusToString */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* decContextSetStatusFromString -- set status from a string */ /* decContextSetRounding -- set current rounding mode */
/* */ /* */
/* context is the controlling context */ /* context is the context structure to be updated */
/* newround is the value which will replace the current mode */
/* returns context */
/* */
/* No error is possible. */
/* ------------------------------------------------------------------ */
decContext *decContextSetRounding(decContext *context,
enum rounding newround) {
context->round=newround;
return context;
} /* decContextSetRounding */
/* ------------------------------------------------------------------ */
/* decContextSetStatus -- set status and raise trap if appropriate */
/* */
/* context is the context structure to be updated */
/* status is the DEC_ exception code */
/* returns the context structure */
/* */
/* Control may never return from this routine, if there is a signal */
/* handler and it takes a long jump. */
/* ------------------------------------------------------------------ */
decContext * decContextSetStatus(decContext *context, uInt status) {
context->status|=status;
if (status & context->traps) raise(SIGFPE);
return context;} /* decContextSetStatus */
/* ------------------------------------------------------------------ */
/* decContextSetStatusFromString -- set status from a string + trap */
/* */
/* context is the context structure to be updated */
/* string is a string exactly equal to one that might be returned */ /* string is a string exactly equal to one that might be returned */
/* by decContextStatusToString */ /* by decContextStatusToString */
/* */ /* */
...@@ -170,59 +254,179 @@ decContextStatusToString (const decContext * context) ...@@ -170,59 +254,179 @@ decContextStatusToString (const decContext * context)
/* DEC_Condition_MU or is not recognized. In these cases NULL is */ /* DEC_Condition_MU or is not recognized. In these cases NULL is */
/* returned. */ /* returned. */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
decContext * decContext * decContextSetStatusFromString(decContext *context,
decContextSetStatusFromString (decContext * context, const char *string) const char *string) {
{ if (strcmp(string, DEC_Condition_CS)==0)
if (strcmp (string, DEC_Condition_CS) == 0) return decContextSetStatus(context, DEC_Conversion_syntax);
return decContextSetStatus (context, DEC_Conversion_syntax); if (strcmp(string, DEC_Condition_DZ)==0)
if (strcmp (string, DEC_Condition_DZ) == 0) return decContextSetStatus(context, DEC_Division_by_zero);
return decContextSetStatus (context, DEC_Division_by_zero); if (strcmp(string, DEC_Condition_DI)==0)
if (strcmp (string, DEC_Condition_DI) == 0) return decContextSetStatus(context, DEC_Division_impossible);
return decContextSetStatus (context, DEC_Division_impossible); if (strcmp(string, DEC_Condition_DU)==0)
if (strcmp (string, DEC_Condition_DU) == 0) return decContextSetStatus(context, DEC_Division_undefined);
return decContextSetStatus (context, DEC_Division_undefined); if (strcmp(string, DEC_Condition_IE)==0)
if (strcmp (string, DEC_Condition_IE) == 0) return decContextSetStatus(context, DEC_Inexact);
return decContextSetStatus (context, DEC_Inexact); if (strcmp(string, DEC_Condition_IS)==0)
if (strcmp (string, DEC_Condition_IS) == 0) return decContextSetStatus(context, DEC_Insufficient_storage);
return decContextSetStatus (context, DEC_Insufficient_storage); if (strcmp(string, DEC_Condition_IC)==0)
if (strcmp (string, DEC_Condition_IC) == 0) return decContextSetStatus(context, DEC_Invalid_context);
return decContextSetStatus (context, DEC_Invalid_context); if (strcmp(string, DEC_Condition_IO)==0)
if (strcmp (string, DEC_Condition_IO) == 0) return decContextSetStatus(context, DEC_Invalid_operation);
return decContextSetStatus (context, DEC_Invalid_operation); #if DECSUBSET
#if DECSUBSET if (strcmp(string, DEC_Condition_LD)==0)
if (strcmp (string, DEC_Condition_LD) == 0) return decContextSetStatus(context, DEC_Lost_digits);
return decContextSetStatus (context, DEC_Lost_digits); #endif
#endif if (strcmp(string, DEC_Condition_OV)==0)
if (strcmp (string, DEC_Condition_OV) == 0) return decContextSetStatus(context, DEC_Overflow);
return decContextSetStatus (context, DEC_Overflow); if (strcmp(string, DEC_Condition_PA)==0)
if (strcmp (string, DEC_Condition_PA) == 0) return decContextSetStatus(context, DEC_Clamped);
return decContextSetStatus (context, DEC_Clamped); if (strcmp(string, DEC_Condition_RO)==0)
if (strcmp (string, DEC_Condition_RO) == 0) return decContextSetStatus(context, DEC_Rounded);
return decContextSetStatus (context, DEC_Rounded); if (strcmp(string, DEC_Condition_SU)==0)
if (strcmp (string, DEC_Condition_SU) == 0) return decContextSetStatus(context, DEC_Subnormal);
return decContextSetStatus (context, DEC_Subnormal); if (strcmp(string, DEC_Condition_UN)==0)
if (strcmp (string, DEC_Condition_UN) == 0) return decContextSetStatus(context, DEC_Underflow);
return decContextSetStatus (context, DEC_Underflow); if (strcmp(string, DEC_Condition_ZE)==0)
if (strcmp (string, DEC_Condition_ZE) == 0)
return context; return context;
return NULL; /* Multiple status, or unknown */ return NULL; /* Multiple status, or unknown */
} /* decContextSetStatusFromString */ } /* decContextSetStatusFromString */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* decContextSetStatus -- set status and raise trap if appropriate */ /* decContextSetStatusFromStringQuiet -- set status from a string */
/* */
/* context is the context structure to be updated */
/* string is a string exactly equal to one that might be returned */
/* by decContextStatusToString */
/* */
/* The status bit corresponding to the string is set; no trap is */
/* raised. */
/* */ /* */
/* context is the controlling context */ /* returns the context structure, unless the string is equal to */
/* DEC_Condition_MU or is not recognized. In these cases NULL is */
/* returned. */
/* ------------------------------------------------------------------ */
decContext * decContextSetStatusFromStringQuiet(decContext *context,
const char *string) {
if (strcmp(string, DEC_Condition_CS)==0)
return decContextSetStatusQuiet(context, DEC_Conversion_syntax);
if (strcmp(string, DEC_Condition_DZ)==0)
return decContextSetStatusQuiet(context, DEC_Division_by_zero);
if (strcmp(string, DEC_Condition_DI)==0)
return decContextSetStatusQuiet(context, DEC_Division_impossible);
if (strcmp(string, DEC_Condition_DU)==0)
return decContextSetStatusQuiet(context, DEC_Division_undefined);
if (strcmp(string, DEC_Condition_IE)==0)
return decContextSetStatusQuiet(context, DEC_Inexact);
if (strcmp(string, DEC_Condition_IS)==0)
return decContextSetStatusQuiet(context, DEC_Insufficient_storage);
if (strcmp(string, DEC_Condition_IC)==0)
return decContextSetStatusQuiet(context, DEC_Invalid_context);
if (strcmp(string, DEC_Condition_IO)==0)
return decContextSetStatusQuiet(context, DEC_Invalid_operation);
#if DECSUBSET
if (strcmp(string, DEC_Condition_LD)==0)
return decContextSetStatusQuiet(context, DEC_Lost_digits);
#endif
if (strcmp(string, DEC_Condition_OV)==0)
return decContextSetStatusQuiet(context, DEC_Overflow);
if (strcmp(string, DEC_Condition_PA)==0)
return decContextSetStatusQuiet(context, DEC_Clamped);
if (strcmp(string, DEC_Condition_RO)==0)
return decContextSetStatusQuiet(context, DEC_Rounded);
if (strcmp(string, DEC_Condition_SU)==0)
return decContextSetStatusQuiet(context, DEC_Subnormal);
if (strcmp(string, DEC_Condition_UN)==0)
return decContextSetStatusQuiet(context, DEC_Underflow);
if (strcmp(string, DEC_Condition_ZE)==0)
return context;
return NULL; /* Multiple status, or unknown */
} /* decContextSetStatusFromStringQuiet */
/* ------------------------------------------------------------------ */
/* decContextSetStatusQuiet -- set status without trap */
/* */
/* context is the context structure to be updated */
/* status is the DEC_ exception code */ /* status is the DEC_ exception code */
/* returns the context structure */ /* returns the context structure */
/* */ /* */
/* Control may never return from this routine, if there is a signal */ /* No error is possible. */
/* handler and it takes a long jump. */ /* ------------------------------------------------------------------ */
decContext * decContextSetStatusQuiet(decContext *context, uInt status) {
context->status|=status;
return context;} /* decContextSetStatusQuiet */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
decContext * /* decContextStatusToString -- convert status flags to a string */
decContextSetStatus (decContext * context, uInt status) /* */
{ /* context is a context with valid status field */
context->status |= status; /* */
if (status & context->traps) /* returns a constant string describing the condition. If multiple */
raise (SIGFPE); /* (or no) flags are set, a generic constant message is returned. */
/* ------------------------------------------------------------------ */
const char *decContextStatusToString(const decContext *context) {
Int status=context->status;
/* test the five IEEE first, as some of the others are ambiguous when */
/* DECEXTFLAG=0 */
if (status==DEC_Invalid_operation ) return DEC_Condition_IO;
if (status==DEC_Division_by_zero ) return DEC_Condition_DZ;
if (status==DEC_Overflow ) return DEC_Condition_OV;
if (status==DEC_Underflow ) return DEC_Condition_UN;
if (status==DEC_Inexact ) return DEC_Condition_IE;
if (status==DEC_Division_impossible ) return DEC_Condition_DI;
if (status==DEC_Division_undefined ) return DEC_Condition_DU;
if (status==DEC_Rounded ) return DEC_Condition_RO;
if (status==DEC_Clamped ) return DEC_Condition_PA;
if (status==DEC_Subnormal ) return DEC_Condition_SU;
if (status==DEC_Conversion_syntax ) return DEC_Condition_CS;
if (status==DEC_Insufficient_storage ) return DEC_Condition_IS;
if (status==DEC_Invalid_context ) return DEC_Condition_IC;
#if DECSUBSET
if (status==DEC_Lost_digits ) return DEC_Condition_LD;
#endif
if (status==0 ) return DEC_Condition_ZE;
return DEC_Condition_MU; /* Multiple errors */
} /* decContextStatusToString */
/* ------------------------------------------------------------------ */
/* decContextTestSavedStatus -- test bits in saved status */
/* */
/* oldstatus is the status word to be tested */
/* mask indicates the bits to be tested (the oldstatus bits that */
/* correspond to each 1 bit in the mask are tested) */
/* returns 1 if any of the tested bits are 1, or 0 otherwise */
/* */
/* No error is possible. */
/* ------------------------------------------------------------------ */
uInt decContextTestSavedStatus(uInt oldstatus, uInt mask) {
return (oldstatus&mask)!=0;
} /* decContextTestSavedStatus */
/* ------------------------------------------------------------------ */
/* decContextTestStatus -- test bits in current status */
/* */
/* context is the context structure to be updated */
/* mask indicates the bits to be tested (the status bits that */
/* correspond to each 1 bit in the mask are tested) */
/* returns 1 if any of the tested bits are 1, or 0 otherwise */
/* */
/* No error is possible. */
/* ------------------------------------------------------------------ */
uInt decContextTestStatus(decContext *context, uInt mask) {
return (context->status&mask)!=0;
} /* decContextTestStatus */
/* ------------------------------------------------------------------ */
/* decContextZeroStatus -- clear all status bits */
/* */
/* context is the context structure to be updated */
/* returns context */
/* */
/* No error is possible. */
/* ------------------------------------------------------------------ */
decContext *decContextZeroStatus(decContext *context) {
context->status=0;
return context; return context;
} /* decContextSetStatus */ } /* decContextZeroStatus */
/* Decimal Context module header for the decNumber C Library /* Decimal context header module for the decNumber C Library.
Copyright (C) 2005, 2006 Free Software Foundation, Inc. Copyright (C) 2005, 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw. Contributed by IBM Corporation. Author Mike Cowlishaw.
This file is part of GCC. This file is part of GCC.
...@@ -29,36 +29,45 @@ ...@@ -29,36 +29,45 @@
02110-1301, USA. */ 02110-1301, USA. */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* Decimal Context module header */
/* ------------------------------------------------------------------ */
/* */
/* Context variables must always have valid values: */
/* */
/* status -- [any bits may be cleared, but not set, by user] */
/* round -- must be one of the enumerated rounding modes */
/* */ /* */
/* Context must always be set correctly: */ /* The following variables are implied for fixed size formats (i.e., */
/* they are ignored) but should still be set correctly in case used */
/* with decNumber functions: */
/* */ /* */
/* clamp -- must be either 0 or 1 */
/* digits -- must be in the range 1 through 999999999 */ /* digits -- must be in the range 1 through 999999999 */
/* emax -- must be in the range 0 through 999999999 */ /* emax -- must be in the range 0 through 999999999 */
/* emin -- must be in the range 0 through -999999999 */ /* emin -- must be in the range 0 through -999999999 */
/* round -- must be one of the enumerated rounding modes */
/* traps -- only defined bits may be set */
/* status -- [any bits may be cleared, but not set, by user] */
/* clamp -- must be either 0 or 1 */
/* extended -- must be either 0 or 1 [present only if DECSUBSET] */ /* extended -- must be either 0 or 1 [present only if DECSUBSET] */
/* traps -- only defined bits may be set */
/* */ /* */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
#if !defined(DECCONTEXT) #if !defined(DECCONTEXT)
#define DECCONTEXT #define DECCONTEXT
#define DECCNAME "decContext" /* Short name */ #define DECCNAME "decContext" /* Short name */
#define DECCFULLNAME "Decimal Context Descriptor" /* Verbose name */ #define DECCFULLNAME "Decimal Context Descriptor" /* Verbose name */
#define DECCAUTHOR "Mike Cowlishaw" /* Who to blame */ #define DECCAUTHOR "Mike Cowlishaw" /* Who to blame */
#include "gstdint.h" /* C99 standard integers */ #include "gstdint.h" /* C99 standard integers */
#include <signal.h> /* for traps */ #include <stdio.h> /* for printf, etc. */
#include <signal.h> /* for traps */
/* Extended flags setting -- set this to 0 to use only IEEE flags */
#define DECEXTFLAG 1 /* 1=enable extended flags */
/* Conditional code flag -- set this to 0 for best performance */ /* Conditional code flag -- set this to 0 for best performance */
#define DECSUBSET 0 /* 1 to enable subset arithmetic */ #define DECSUBSET 0 /* 1=enable subset arithmetic */
/* Context for operations, with associated constants */ /* Context for operations, with associated constants */
enum rounding enum rounding {
{
DEC_ROUND_CEILING, /* round towards +infinity */ DEC_ROUND_CEILING, /* round towards +infinity */
DEC_ROUND_UP, /* round away from 0 */ DEC_ROUND_UP, /* round away from 0 */
DEC_ROUND_HALF_UP, /* 0.5 rounds up */ DEC_ROUND_HALF_UP, /* 0.5 rounds up */
...@@ -66,11 +75,12 @@ enum rounding ...@@ -66,11 +75,12 @@ enum rounding
DEC_ROUND_HALF_DOWN, /* 0.5 rounds down */ DEC_ROUND_HALF_DOWN, /* 0.5 rounds down */
DEC_ROUND_DOWN, /* round towards 0 (truncate) */ DEC_ROUND_DOWN, /* round towards 0 (truncate) */
DEC_ROUND_FLOOR, /* round towards -infinity */ DEC_ROUND_FLOOR, /* round towards -infinity */
DEC_ROUND_05UP, /* round for reround */
DEC_ROUND_MAX /* enum must be less than this */ DEC_ROUND_MAX /* enum must be less than this */
}; };
#define DEC_ROUND_DEFAULT DEC_ROUND_HALF_EVEN;
typedef struct typedef struct {
{
int32_t digits; /* working precision */ int32_t digits; /* working precision */
int32_t emax; /* maximum positive exponent */ int32_t emax; /* maximum positive exponent */
int32_t emin; /* minimum negative exponent */ int32_t emin; /* minimum negative exponent */
...@@ -78,110 +88,171 @@ typedef struct ...@@ -78,110 +88,171 @@ typedef struct
uint32_t traps; /* trap-enabler flags */ uint32_t traps; /* trap-enabler flags */
uint32_t status; /* status flags */ uint32_t status; /* status flags */
uint8_t clamp; /* flag: apply IEEE exponent clamp */ uint8_t clamp; /* flag: apply IEEE exponent clamp */
#if DECSUBSET #if DECSUBSET
uint8_t extended; /* flag: special-values allowed */ uint8_t extended; /* flag: special-values allowed */
#endif #endif
} decContext; } decContext;
/* Maxima and Minima */ /* Maxima and Minima for context settings */
#define DEC_MAX_DIGITS 999999999 #define DEC_MAX_DIGITS 999999999
#define DEC_MIN_DIGITS 1 #define DEC_MIN_DIGITS 1
#define DEC_MAX_EMAX 999999999 #define DEC_MAX_EMAX 999999999
#define DEC_MIN_EMAX 0 #define DEC_MIN_EMAX 0
#define DEC_MAX_EMIN 0 #define DEC_MAX_EMIN 0
#define DEC_MIN_EMIN -999999999 #define DEC_MIN_EMIN -999999999
#define DEC_MAX_MATH 999999 /* max emax, etc., for math funcs. */
/* Trap-enabler and Status flags (exceptional conditions), and their names */
/* Top byte is reserved for internal use */ /* Classifications for decimal numbers, aligned with 754r (note */
#define DEC_Conversion_syntax 0x00000001 /* that 'normal' and 'subnormal' are meaningful only with a */
#define DEC_Division_by_zero 0x00000002 /* decContext or a fixed size format). */
#define DEC_Division_impossible 0x00000004 enum decClass {
#define DEC_Division_undefined 0x00000008 DEC_CLASS_SNAN,
#define DEC_Insufficient_storage 0x00000010 /* [used if malloc fails] */ DEC_CLASS_QNAN,
#define DEC_Inexact 0x00000020 DEC_CLASS_NEG_INF,
#define DEC_Invalid_context 0x00000040 DEC_CLASS_NEG_NORMAL,
#define DEC_Invalid_operation 0x00000080 DEC_CLASS_NEG_SUBNORMAL,
#if DECSUBSET DEC_CLASS_NEG_ZERO,
#define DEC_Lost_digits 0x00000100 DEC_CLASS_POS_ZERO,
#endif DEC_CLASS_POS_SUBNORMAL,
#define DEC_Overflow 0x00000200 DEC_CLASS_POS_NORMAL,
#define DEC_Clamped 0x00000400 DEC_CLASS_POS_INF
#define DEC_Rounded 0x00000800 };
#define DEC_Subnormal 0x00001000 /* Strings for the decClasses */
#define DEC_Underflow 0x00002000 #define DEC_ClassString_SN "sNaN"
#define DEC_ClassString_QN "NaN"
#define DEC_ClassString_NI "-Infinity"
#define DEC_ClassString_NN "-Normal"
#define DEC_ClassString_NS "-Subnormal"
#define DEC_ClassString_NZ "-Zero"
#define DEC_ClassString_PZ "+Zero"
#define DEC_ClassString_PS "+Subnormal"
#define DEC_ClassString_PN "+Normal"
#define DEC_ClassString_PI "+Infinity"
#define DEC_ClassString_UN "Invalid"
/* Trap-enabler and Status flags (exceptional conditions), and */
/* their names. The top byte is reserved for internal use */
#if DECEXTFLAG
/* Extended flags */
#define DEC_Conversion_syntax 0x00000001
#define DEC_Division_by_zero 0x00000002
#define DEC_Division_impossible 0x00000004
#define DEC_Division_undefined 0x00000008
#define DEC_Insufficient_storage 0x00000010 /* [when malloc fails] */
#define DEC_Inexact 0x00000020
#define DEC_Invalid_context 0x00000040
#define DEC_Invalid_operation 0x00000080
#if DECSUBSET
#define DEC_Lost_digits 0x00000100
#endif
#define DEC_Overflow 0x00000200
#define DEC_Clamped 0x00000400
#define DEC_Rounded 0x00000800
#define DEC_Subnormal 0x00001000
#define DEC_Underflow 0x00002000
#else
/* IEEE flags only */
#define DEC_Conversion_syntax 0x00000010
#define DEC_Division_by_zero 0x00000002
#define DEC_Division_impossible 0x00000010
#define DEC_Division_undefined 0x00000010
#define DEC_Insufficient_storage 0x00000010 /* [when malloc fails] */
#define DEC_Inexact 0x00000001
#define DEC_Invalid_context 0x00000010
#define DEC_Invalid_operation 0x00000010
#if DECSUBSET
#define DEC_Lost_digits 0x00000000
#endif
#define DEC_Overflow 0x00000008
#define DEC_Clamped 0x00000000
#define DEC_Rounded 0x00000000
#define DEC_Subnormal 0x00000000
#define DEC_Underflow 0x00000004
#endif
/* IEEE 854 groupings for the flags */ /* IEEE 854 groupings for the flags */
/* [DEC_Clamped, DEC_Lost_digits, DEC_Rounded, and DEC_Subnormal are */ /* [DEC_Clamped, DEC_Lost_digits, DEC_Rounded, and DEC_Subnormal */
/* not in IEEE 854] */ /* are not in IEEE 854] */
#define DEC_IEEE_854_Division_by_zero (DEC_Division_by_zero) #define DEC_IEEE_854_Division_by_zero (DEC_Division_by_zero)
#if DECSUBSET #if DECSUBSET
#define DEC_IEEE_854_Inexact (DEC_Inexact | DEC_Lost_digits) #define DEC_IEEE_854_Inexact (DEC_Inexact | DEC_Lost_digits)
#else #else
#define DEC_IEEE_854_Inexact (DEC_Inexact) #define DEC_IEEE_854_Inexact (DEC_Inexact)
#endif #endif
#define DEC_IEEE_854_Invalid_operation (DEC_Conversion_syntax | \ #define DEC_IEEE_854_Invalid_operation (DEC_Conversion_syntax | \
DEC_Division_impossible | \ DEC_Division_impossible | \
DEC_Division_undefined | \ DEC_Division_undefined | \
DEC_Insufficient_storage | \ DEC_Insufficient_storage | \
DEC_Invalid_context | \ DEC_Invalid_context | \
DEC_Invalid_operation) DEC_Invalid_operation)
#define DEC_IEEE_854_Overflow (DEC_Overflow) #define DEC_IEEE_854_Overflow (DEC_Overflow)
#define DEC_IEEE_854_Underflow (DEC_Underflow) #define DEC_IEEE_854_Underflow (DEC_Underflow)
/* flags which are normally errors (results are qNaN, infinite, or 0) */ /* flags which are normally errors (result is qNaN, infinite, or 0) */
#define DEC_Errors (DEC_IEEE_854_Division_by_zero | \ #define DEC_Errors (DEC_IEEE_854_Division_by_zero | \
DEC_IEEE_854_Invalid_operation | \ DEC_IEEE_854_Invalid_operation | \
DEC_IEEE_854_Overflow | DEC_IEEE_854_Underflow) DEC_IEEE_854_Overflow | DEC_IEEE_854_Underflow)
/* flags which cause a result to become qNaN */ /* flags which cause a result to become qNaN */
#define DEC_NaNs DEC_IEEE_854_Invalid_operation #define DEC_NaNs DEC_IEEE_854_Invalid_operation
/* flags which are normally for information only (have finite results) */ /* flags which are normally for information only (finite results) */
#if DECSUBSET #if DECSUBSET
#define DEC_Information (DEC_Clamped | DEC_Rounded | DEC_Inexact \ #define DEC_Information (DEC_Clamped | DEC_Rounded | DEC_Inexact \
| DEC_Lost_digits) | DEC_Lost_digits)
#else #else
#define DEC_Information (DEC_Clamped | DEC_Rounded | DEC_Inexact) #define DEC_Information (DEC_Clamped | DEC_Rounded | DEC_Inexact)
#endif #endif
/* name strings for the exceptional conditions */ /* Name strings for the exceptional conditions */
#define DEC_Condition_CS "Conversion syntax"
#define DEC_Condition_CS "Conversion syntax" #define DEC_Condition_DZ "Division by zero"
#define DEC_Condition_DZ "Division by zero" #define DEC_Condition_DI "Division impossible"
#define DEC_Condition_DI "Division impossible" #define DEC_Condition_DU "Division undefined"
#define DEC_Condition_DU "Division undefined" #define DEC_Condition_IE "Inexact"
#define DEC_Condition_IE "Inexact" #define DEC_Condition_IS "Insufficient storage"
#define DEC_Condition_IS "Insufficient storage" #define DEC_Condition_IC "Invalid context"
#define DEC_Condition_IC "Invalid context" #define DEC_Condition_IO "Invalid operation"
#define DEC_Condition_IO "Invalid operation" #if DECSUBSET
#if DECSUBSET #define DEC_Condition_LD "Lost digits"
#define DEC_Condition_LD "Lost digits" #endif
#endif #define DEC_Condition_OV "Overflow"
#define DEC_Condition_OV "Overflow" #define DEC_Condition_PA "Clamped"
#define DEC_Condition_PA "Clamped" #define DEC_Condition_RO "Rounded"
#define DEC_Condition_RO "Rounded" #define DEC_Condition_SU "Subnormal"
#define DEC_Condition_SU "Subnormal" #define DEC_Condition_UN "Underflow"
#define DEC_Condition_UN "Underflow" #define DEC_Condition_ZE "No status"
#define DEC_Condition_ZE "No status" #define DEC_Condition_MU "Multiple status"
#define DEC_Condition_MU "Multiple status" #define DEC_Condition_Length 21 /* length of the longest string, */
#define DEC_Condition_Length 21 /* length of the longest string, */
/* including terminator */ /* including terminator */
/* Initialization descriptors, used by decContextDefault */ /* Initialization descriptors, used by decContextDefault */
#define DEC_INIT_BASE 0 #define DEC_INIT_BASE 0
#define DEC_INIT_DECIMAL32 32 #define DEC_INIT_DECIMAL32 32
#define DEC_INIT_DECIMAL64 64 #define DEC_INIT_DECIMAL64 64
#define DEC_INIT_DECIMAL128 128 #define DEC_INIT_DECIMAL128 128
/* Synonyms */
#define DEC_INIT_DECSINGLE DEC_INIT_DECIMAL32
#define DEC_INIT_DECDOUBLE DEC_INIT_DECIMAL64
#define DEC_INIT_DECQUAD DEC_INIT_DECIMAL128
/* decContext routines */ /* decContext routines */
#ifdef IN_LIBGCC2
#define decContextDefault __decContextDefault #include "decContextSymbols.h"
#define decContextSetStatus __decContextSetStatus
#define decContextStatusToString __decContextStatusToString extern decContext * decContextClearStatus(decContext *, uint32_t);
#define decContextSetStatusFromString __decContextSetStatusFromString extern decContext * decContextDefault(decContext *, int32_t);
#endif extern enum rounding decContextGetRounding(decContext *);
decContext *decContextDefault (decContext *, int32_t); extern uint32_t decContextGetStatus(decContext *);
decContext *decContextSetStatus (decContext *, uint32_t); extern decContext * decContextRestoreStatus(decContext *, uint32_t, uint32_t);
const char *decContextStatusToString (const decContext *); extern uint32_t decContextSaveStatus(decContext *, uint32_t);
decContext *decContextSetStatusFromString (decContext *, const char *); extern decContext * decContextSetRounding(decContext *, enum rounding);
extern decContext * decContextSetStatus(decContext *, uint32_t);
extern decContext * decContextSetStatusFromString(decContext *, const char *);
extern decContext * decContextSetStatusFromStringQuiet(decContext *, const char *);
extern decContext * decContextSetStatusQuiet(decContext *, uint32_t);
extern const char * decContextStatusToString(const decContext *);
extern uint32_t decContextTestSavedStatus(uint32_t, uint32_t);
extern uint32_t decContextTestStatus(decContext *, uint32_t);
extern decContext * decContextZeroStatus(decContext *);
#endif #endif
#if !defined(DECCONTEXTSYMBOLS)
#define DECCONTEXTSYMBOLS
#ifdef IN_LIBGCC2
#define decContextClearStatus __decContextClearStatus
#define decContextDefault __decContextDefault
#define decContextGetRounding __decContextGetRounding
#define decContextGetStatus __decContextGetStatus
#define decContextRestoreStatus __decContextRestoreStatus
#define decContextSaveStatus __decContextSaveStatus
#define decContextSetRounding __decContextSetRounding
#define decContextSetStatus __decContextSetStatus
#define decContextSetStatusFromString __decContextSetStatusFromString
#define decContextSetStatusFromStringQuiet __decContextSetStatusFromStringQuiet
#define decContextSetStatusQuiet __decContextSetStatusQuiet
#define decContextStatusToString __decContextStatusToString
#define decContextTestSavedStatus __decContextTestSavedStatus
#define decContextTestStatus __decContextTestStatus
#define decContextZeroStatus __decContextZeroStatus
#endif
#endif
/* Binary Coded Decimal <--> Densely Packed Decimal lookup tables. /* Conversion lookup tables for the decNumber C Library.
Copyright (C) 2005 Free Software Foundation, Inc. Copyright (C) 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw. Contributed by IBM Corporation. Author Mike Cowlishaw.
This file is part of GCC. This file is part of GCC.
...@@ -29,26 +29,41 @@ ...@@ -29,26 +29,41 @@
02110-1301, USA. */ 02110-1301, USA. */
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
/* Binary Coded Decimal and Densely Packed Decimal conversion lookup tables */
/* [Automatically generated -- do not edit. 2007.05.05] */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
/* For details, see: http://www2.hursley.ibm.com/decimal/DPDecimal.html */ /* For details, see: http://www2.hursley.ibm.com/decimal/DPDecimal.html */
/* */ /* */
/* This include file defines conversion tables for DPD, as follows. */ /* This include file defines several DPD and BCD conversion tables: */
/* */ /* */
/* uint16_t BCD2DPD[2458]; // BCD -> DPD (0x999 => 2457) */ /* uint16_t BCD2DPD[2458]; -- BCD -> DPD (0x999 => 2457) */
/* uint16_t DPD2BCD[1024]; // DPD -> BCD (0x3FF => 0x999) */ /* uint16_t BIN2DPD[1000]; -- Bin -> DPD (999 => 2457) */
/* uint16_t BIN2DPD[1000]; // BIN -> DPD (999 => 2457) */ /* uint8_t BIN2CHAR[4001]; -- Bin -> CHAR (999 => '\3' '9' '9' '9') */
/* uint16_t DPD2BIN[1024]; // DPD -> BIN (0x3FF => 999) */ /* uint8_t BIN2BCD8[4000]; -- Bin -> bytes (999 => 9 9 9 3) */
/* uint16_t DPD2BCD[1024]; -- DPD -> BCD (0x3FF => 0x999) */
/* uint16_t DPD2BIN[1024]; -- DPD -> BIN (0x3FF => 999) */
/* uint32_t DPD2BINK[1024]; -- DPD -> BIN * 1000 (0x3FF => 999000) */
/* uint32_t DPD2BINM[1024]; -- DPD -> BIN * 1E+6 (0x3FF => 999000000) */
/* uint8_t DPD2BCD8[4096]; -- DPD -> bytes (x3FF => 9 9 9 3) */
/* */ /* */
/* In all cases the result (10 bits or 12 bits, or binary) is right-aligned */ /* In all cases the result (10 bits or 12 bits, or binary) is right-aligned */
/* in the table entry. */ /* in the table entry. BIN2CHAR entries are a single byte length (0 for */
/* value 0) followed by three digit characters; a trailing terminator is */
/* included to allow 4-char moves always. BIN2BCD8 and DPD2BCD8 entries */
/* are similar with the three BCD8 digits followed by a one-byte length */
/* (again, length=0 for value 0). */
/* */ /* */
/* To use a table, its name, prefixed with DEC_, must be defined with a */ /* To use a table, its name, prefixed with DEC_, must be defined with a */
/* value of 1 before this header file is included. For example: */ /* value of 1 before this header file is included. For example: */
/* #define DEC_BCD2DPD 1 */ /* #define DEC_BCD2DPD 1 */
/* This mechanism allows software to only include tables that are needed. */
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
#if DEC_BCD2DPD==1 #if defined(DEC_BCD2DPD) && DEC_BCD2DPD==1 && !defined(DECBCD2DPD)
#define DECBCD2DPD
const uint16_t BCD2DPD[2458] = { 0, 1, 2, 3, 4, 5, 6, 7, const uint16_t BCD2DPD[2458]={ 0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 0, 0, 0, 0, 0, 0, 16, 17, 18, 19, 20, 8, 9, 0, 0, 0, 0, 0, 0, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 32, 33, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 32, 33,
34, 35, 36, 37, 38, 39, 40, 41, 0, 0, 0, 0, 0, 34, 35, 36, 37, 38, 39, 40, 41, 0, 0, 0, 0, 0,
...@@ -65,8 +80,8 @@ const uint16_t BCD2DPD[2458] = { 0, 1, 2, 3, 4, 5, 6, 7, ...@@ -65,8 +80,8 @@ const uint16_t BCD2DPD[2458] = { 0, 1, 2, 3, 4, 5, 6, 7,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 42, 43, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
75, 106, 107, 78, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 0, 0, 0, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 0, 0,
0, 0, 0, 0, 144, 145, 146, 147, 148, 149, 150, 151, 152, 0, 0, 0, 0, 144, 145, 146, 147, 148, 149, 150, 151, 152,
...@@ -85,8 +100,8 @@ const uint16_t BCD2DPD[2458] = { 0, 1, 2, 3, 4, 5, 6, 7, ...@@ -85,8 +100,8 @@ const uint16_t BCD2DPD[2458] = { 0, 1, 2, 3, 4, 5, 6, 7,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 138, 139, 170, 171, 202, 203, 234, 235, 206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, 257, 258, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, 257, 258,
259, 260, 261, 262, 263, 264, 265, 0, 0, 0, 0, 0, 0, 259, 260, 261, 262, 263, 264, 265, 0, 0, 0, 0, 0, 0,
272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 0, 0, 0, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 0, 0, 0,
...@@ -105,7 +120,7 @@ const uint16_t BCD2DPD[2458] = { 0, 1, 2, 3, 4, 5, 6, 7, ...@@ -105,7 +120,7 @@ const uint16_t BCD2DPD[2458] = { 0, 1, 2, 3, 4, 5, 6, 7,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
266, 267, 298, 299, 330, 331, 362, 363, 334, 335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 384, 385, 386, 387, 388, 389, 390, 0, 0, 0, 0, 0, 0, 384, 385, 386, 387, 388, 389, 390,
391, 392, 393, 0, 0, 0, 0, 0, 0, 400, 401, 402, 403, 391, 392, 393, 0, 0, 0, 0, 0, 0, 400, 401, 402, 403,
...@@ -124,8 +139,8 @@ const uint16_t BCD2DPD[2458] = { 0, 1, 2, 3, 4, 5, 6, 7, ...@@ -124,8 +139,8 @@ const uint16_t BCD2DPD[2458] = { 0, 1, 2, 3, 4, 5, 6, 7,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 394, 395, 426, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
458, 459, 490, 491, 462, 463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 0, 0, 0, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 0,
0, 0, 0, 0, 0, 528, 529, 530, 531, 532, 533, 534, 535, 0, 0, 0, 0, 0, 528, 529, 530, 531, 532, 533, 534, 535,
...@@ -144,8 +159,8 @@ const uint16_t BCD2DPD[2458] = { 0, 1, 2, 3, 4, 5, 6, 7, ...@@ -144,8 +159,8 @@ const uint16_t BCD2DPD[2458] = { 0, 1, 2, 3, 4, 5, 6, 7,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 522, 523, 554, 555, 586, 587, 618, 619, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
590, 591, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 640, 641, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 640, 641,
642, 643, 644, 645, 646, 647, 648, 649, 0, 0, 0, 0, 0, 642, 643, 644, 645, 646, 647, 648, 649, 0, 0, 0, 0, 0,
0, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 0, 0, 0, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 0, 0,
...@@ -164,7 +179,7 @@ const uint16_t BCD2DPD[2458] = { 0, 1, 2, 3, 4, 5, 6, 7, ...@@ -164,7 +179,7 @@ const uint16_t BCD2DPD[2458] = { 0, 1, 2, 3, 4, 5, 6, 7,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 650, 651, 682, 683, 714, 715, 746, 747, 718, 719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 768, 769, 770, 771, 772, 773, 0, 0, 0, 0, 0, 0, 0, 768, 769, 770, 771, 772, 773,
774, 775, 776, 777, 0, 0, 0, 0, 0, 0, 784, 785, 786, 774, 775, 776, 777, 0, 0, 0, 0, 0, 0, 784, 785, 786,
...@@ -183,8 +198,8 @@ const uint16_t BCD2DPD[2458] = { 0, 1, 2, 3, 4, 5, 6, 7, ...@@ -183,8 +198,8 @@ const uint16_t BCD2DPD[2458] = { 0, 1, 2, 3, 4, 5, 6, 7,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 778, 779, 810, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
811, 842, 843, 874, 875, 846, 847, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 0, 0, 0, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905,
0, 0, 0, 0, 0, 0, 912, 913, 914, 915, 916, 917, 918, 0, 0, 0, 0, 0, 0, 912, 913, 914, 915, 916, 917, 918,
...@@ -203,8 +218,8 @@ const uint16_t BCD2DPD[2458] = { 0, 1, 2, 3, 4, 5, 6, 7, ...@@ -203,8 +218,8 @@ const uint16_t BCD2DPD[2458] = { 0, 1, 2, 3, 4, 5, 6, 7,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 906, 907, 938, 939, 970, 971, 1002, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1003, 974, 975, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
13, 268, 269, 524, 525, 780, 781, 46, 47, 0, 0, 0, 0, 13, 268, 269, 524, 525, 780, 781, 46, 47, 0, 0, 0, 0,
0, 0, 28, 29, 284, 285, 540, 541, 796, 797, 62, 63, 0, 0, 0, 28, 29, 284, 285, 540, 541, 796, 797, 62, 63, 0,
...@@ -223,7 +238,7 @@ const uint16_t BCD2DPD[2458] = { 0, 1, 2, 3, 4, 5, 6, 7, ...@@ -223,7 +238,7 @@ const uint16_t BCD2DPD[2458] = { 0, 1, 2, 3, 4, 5, 6, 7,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 14, 15, 270, 271, 526, 527, 782, 783, 110, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 140, 141, 396, 397, 652, 0, 0, 0, 0, 0, 0, 0, 0, 140, 141, 396, 397, 652,
653, 908, 909, 174, 175, 0, 0, 0, 0, 0, 0, 156, 157, 653, 908, 909, 174, 175, 0, 0, 0, 0, 0, 0, 156, 157,
...@@ -237,13 +252,13 @@ const uint16_t BCD2DPD[2458] = { 0, 1, 2, 3, 4, 5, 6, 7, ...@@ -237,13 +252,13 @@ const uint16_t BCD2DPD[2458] = { 0, 1, 2, 3, 4, 5, 6, 7,
0, 0, 0, 252, 253, 508, 509, 764, 765, 1020, 1021, 958, 959, 0, 0, 0, 252, 253, 508, 509, 764, 765, 1020, 1021, 958, 959,
0, 0, 0, 0, 0, 0, 142, 143, 398, 399, 654, 655, 910, 0, 0, 0, 0, 0, 0, 142, 143, 398, 399, 654, 655, 910,
911, 238, 239, 0, 0, 0, 0, 0, 0, 158, 159, 414, 415, 911, 238, 239, 0, 0, 0, 0, 0, 0, 158, 159, 414, 415,
670, 671, 926, 927, 254, 255 670, 671, 926, 927, 254, 255};
};
#endif #endif
#if DEC_DPD2BCD==1 #if defined(DEC_DPD2BCD) && DEC_DPD2BCD==1 && !defined(DECDPD2BCD)
#define DECDPD2BCD
const uint16_t DPD2BCD[1024] = { 0, 1, 2, 3, 4, 5, 6, 7, const uint16_t DPD2BCD[1024]={ 0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 128, 129, 2048, 2049, 2176, 2177, 16, 17, 18, 19, 20, 8, 9, 128, 129, 2048, 2049, 2176, 2177, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 144, 145, 2064, 2065, 2192, 2193, 32, 33, 21, 22, 23, 24, 25, 144, 145, 2064, 2065, 2192, 2193, 32, 33,
34, 35, 36, 37, 38, 39, 40, 41, 130, 131, 2080, 2081, 2056, 34, 35, 36, 37, 38, 39, 40, 41, 130, 131, 2080, 2081, 2056,
...@@ -283,91 +298,52 @@ const uint16_t DPD2BCD[1024] = { 0, 1, 2, 3, 4, 5, 6, 7, ...@@ -283,91 +298,52 @@ const uint16_t DPD2BCD[1024] = { 0, 1, 2, 3, 4, 5, 6, 7,
2386, 2387, 920, 921, 864, 865, 866, 867, 868, 869, 870, 871, 872, 2386, 2387, 920, 921, 864, 865, 866, 867, 868, 869, 870, 871, 872,
873, 902, 903, 2402, 2403, 2440, 2441, 880, 881, 882, 883, 884, 885, 873, 902, 903, 2402, 2403, 2440, 2441, 880, 881, 882, 883, 884, 885,
886, 887, 888, 889, 918, 919, 2418, 2419, 2456, 2457, 1024, 1025, 1026, 886, 887, 888, 889, 918, 919, 2418, 2419, 2456, 2457, 1024, 1025, 1026,
1027, 1028, 1029, 1030, 1031, 1032, 1033, 1152, 1153, 2052, 2053, 2180, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1152, 1153, 2052, 2053, 2180, 2181,
2181, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1168, 1169, 2068,
1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1168, 1169, 2069, 2196, 2197, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065,
2068, 1154, 1155, 2084, 2085, 2120, 2121, 1072, 1073, 1074, 1075, 1076, 1077, 1078,
2069, 2196, 2197, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1079, 1080, 1081, 1170, 1171, 2100, 2101, 2136, 2137, 1088, 1089, 1090, 1091,
1065, 1092, 1093, 1094, 1095, 1096, 1097, 1156, 1157, 2116, 2117, 1160, 1161, 1104,
1154, 1155, 2084, 2085, 2120, 2121, 1072, 1073, 1074, 1075, 1076, 1077, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1172, 1173, 2132, 2133,
1078, 1176, 1177, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1158,
1079, 1080, 1081, 1170, 1171, 2100, 2101, 2136, 2137, 1088, 1089, 1090, 1159, 2148, 2149, 2184, 2185, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143,
1091, 1144, 1145, 1174, 1175, 2164, 2165, 2200, 2201, 1280, 1281, 1282, 1283, 1284,
1092, 1093, 1094, 1095, 1096, 1097, 1156, 1157, 2116, 2117, 1160, 1161, 1285, 1286, 1287, 1288, 1289, 1408, 1409, 2308, 2309, 2436, 2437, 1296, 1297,
1104, 1298, 1299, 1300, 1301, 1302, 1303, 1304, 1305, 1424, 1425, 2324, 2325, 2452,
1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1172, 1173, 2132, 2453, 1312, 1313, 1314, 1315, 1316, 1317, 1318, 1319, 1320, 1321, 1410, 1411,
2133, 2340, 2341, 2376, 2377, 1328, 1329, 1330, 1331, 1332, 1333, 1334, 1335, 1336,
1176, 1177, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1337, 1426, 1427, 2356, 2357, 2392, 2393, 1344, 1345, 1346, 1347, 1348, 1349,
1158, 1350, 1351, 1352, 1353, 1412, 1413, 2372, 2373, 1416, 1417, 1360, 1361, 1362,
1159, 2148, 2149, 2184, 2185, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1363, 1364, 1365, 1366, 1367, 1368, 1369, 1428, 1429, 2388, 2389, 1432, 1433,
1143, 1376, 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1414, 1415, 2404,
1144, 1145, 1174, 1175, 2164, 2165, 2200, 2201, 1280, 1281, 1282, 1283, 2405, 2440, 2441, 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401,
1284, 1430, 1431, 2420, 2421, 2456, 2457, 1536, 1537, 1538, 1539, 1540, 1541, 1542,
1285, 1286, 1287, 1288, 1289, 1408, 1409, 2308, 2309, 2436, 2437, 1296, 1543, 1544, 1545, 1664, 1665, 2054, 2055, 2182, 2183, 1552, 1553, 1554, 1555,
1297, 1556, 1557, 1558, 1559, 1560, 1561, 1680, 1681, 2070, 2071, 2198, 2199, 1568,
1298, 1299, 1300, 1301, 1302, 1303, 1304, 1305, 1424, 1425, 2324, 2325, 1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1666, 1667, 2086, 2087,
2452, 2152, 2153, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1682,
2453, 1312, 1313, 1314, 1315, 1316, 1317, 1318, 1319, 1320, 1321, 1410, 1683, 2102, 2103, 2168, 2169, 1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607,
1411, 1608, 1609, 1668, 1669, 2118, 2119, 1672, 1673, 1616, 1617, 1618, 1619, 1620,
2340, 2341, 2376, 2377, 1328, 1329, 1330, 1331, 1332, 1333, 1334, 1335, 1621, 1622, 1623, 1624, 1625, 1684, 1685, 2134, 2135, 1688, 1689, 1632, 1633,
1336, 1634, 1635, 1636, 1637, 1638, 1639, 1640, 1641, 1670, 1671, 2150, 2151, 2184,
1337, 1426, 1427, 2356, 2357, 2392, 2393, 1344, 1345, 1346, 1347, 1348, 2185, 1648, 1649, 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1657, 1686, 1687,
1349, 2166, 2167, 2200, 2201, 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799, 1800,
1350, 1351, 1352, 1353, 1412, 1413, 2372, 2373, 1416, 1417, 1360, 1361, 1801, 1920, 1921, 2310, 2311, 2438, 2439, 1808, 1809, 1810, 1811, 1812, 1813,
1362, 1814, 1815, 1816, 1817, 1936, 1937, 2326, 2327, 2454, 2455, 1824, 1825, 1826,
1363, 1364, 1365, 1366, 1367, 1368, 1369, 1428, 1429, 2388, 2389, 1432, 1827, 1828, 1829, 1830, 1831, 1832, 1833, 1922, 1923, 2342, 2343, 2408, 2409,
1433, 1840, 1841, 1842, 1843, 1844, 1845, 1846, 1847, 1848, 1849, 1938, 1939, 2358,
1376, 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1414, 1415, 2359, 2424, 2425, 1856, 1857, 1858, 1859, 1860, 1861, 1862, 1863, 1864, 1865,
2404, 1924, 1925, 2374, 2375, 1928, 1929, 1872, 1873, 1874, 1875, 1876, 1877, 1878,
2405, 2440, 2441, 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1879, 1880, 1881, 1940, 1941, 2390, 2391, 1944, 1945, 1888, 1889, 1890, 1891,
1401, 1892, 1893, 1894, 1895, 1896, 1897, 1926, 1927, 2406, 2407, 2440, 2441, 1904,
1430, 1431, 2420, 2421, 2456, 2457, 1536, 1537, 1538, 1539, 1540, 1541, 1905, 1906, 1907, 1908, 1909, 1910, 1911, 1912, 1913, 1942, 1943, 2422, 2423,
1542, 2456, 2457};
1543, 1544, 1545, 1664, 1665, 2054, 2055, 2182, 2183, 1552, 1553, 1554,
1555,
1556, 1557, 1558, 1559, 1560, 1561, 1680, 1681, 2070, 2071, 2198, 2199,
1568,
1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1666, 1667, 2086,
2087,
2152, 2153, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593,
1682,
1683, 2102, 2103, 2168, 2169, 1600, 1601, 1602, 1603, 1604, 1605, 1606,
1607,
1608, 1609, 1668, 1669, 2118, 2119, 1672, 1673, 1616, 1617, 1618, 1619,
1620,
1621, 1622, 1623, 1624, 1625, 1684, 1685, 2134, 2135, 1688, 1689, 1632,
1633,
1634, 1635, 1636, 1637, 1638, 1639, 1640, 1641, 1670, 1671, 2150, 2151,
2184,
2185, 1648, 1649, 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1657, 1686,
1687,
2166, 2167, 2200, 2201, 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799,
1800,
1801, 1920, 1921, 2310, 2311, 2438, 2439, 1808, 1809, 1810, 1811, 1812,
1813,
1814, 1815, 1816, 1817, 1936, 1937, 2326, 2327, 2454, 2455, 1824, 1825,
1826,
1827, 1828, 1829, 1830, 1831, 1832, 1833, 1922, 1923, 2342, 2343, 2408,
2409,
1840, 1841, 1842, 1843, 1844, 1845, 1846, 1847, 1848, 1849, 1938, 1939,
2358,
2359, 2424, 2425, 1856, 1857, 1858, 1859, 1860, 1861, 1862, 1863, 1864,
1865,
1924, 1925, 2374, 2375, 1928, 1929, 1872, 1873, 1874, 1875, 1876, 1877,
1878,
1879, 1880, 1881, 1940, 1941, 2390, 2391, 1944, 1945, 1888, 1889, 1890,
1891,
1892, 1893, 1894, 1895, 1896, 1897, 1926, 1927, 2406, 2407, 2440, 2441,
1904,
1905, 1906, 1907, 1908, 1909, 1910, 1911, 1912, 1913, 1942, 1943, 2422,
2423,
2456, 2457
};
#endif #endif
#if DEC_BIN2DPD==1 #if defined(DEC_BIN2DPD) && DEC_BIN2DPD==1 && !defined(DECBIN2DPD)
#define DECBIN2DPD
const uint16_t BIN2DPD[1000] = { 0, 1, 2, 3, 4, 5, 6, 7, const uint16_t BIN2DPD[1000]={ 0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 32, 8, 9, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 32,
33, 34, 35, 36, 37, 38, 39, 40, 41, 48, 49, 50, 51, 33, 34, 35, 36, 37, 38, 39, 40, 41, 48, 49, 50, 51,
52, 53, 54, 55, 56, 57, 64, 65, 66, 67, 68, 69, 70, 52, 53, 54, 55, 56, 57, 64, 65, 66, 67, 68, 69, 70,
...@@ -444,13 +420,13 @@ const uint16_t BIN2DPD[1000] = { 0, 1, 2, 3, 4, 5, 6, 7, ...@@ -444,13 +420,13 @@ const uint16_t BIN2DPD[1000] = { 0, 1, 2, 3, 4, 5, 6, 7,
989, 702, 703, 236, 237, 492, 493, 748, 749, 1004, 1005, 942, 943, 989, 702, 703, 236, 237, 492, 493, 748, 749, 1004, 1005, 942, 943,
252, 253, 508, 509, 764, 765, 1020, 1021, 958, 959, 142, 143, 398, 252, 253, 508, 509, 764, 765, 1020, 1021, 958, 959, 142, 143, 398,
399, 654, 655, 910, 911, 238, 239, 158, 159, 414, 415, 670, 671, 399, 654, 655, 910, 911, 238, 239, 158, 159, 414, 415, 670, 671,
926, 927, 254, 255 926, 927, 254, 255};
};
#endif #endif
#if DEC_DPD2BIN==1 #if defined(DEC_DPD2BIN) && DEC_DPD2BIN==1 && !defined(DECDPD2BIN)
#define DECDPD2BIN
const uint16_t DPD2BIN[1024] = { 0, 1, 2, 3, 4, 5, 6, 7, const uint16_t DPD2BIN[1024]={ 0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 80, 81, 800, 801, 880, 881, 10, 11, 12, 13, 14, 8, 9, 80, 81, 800, 801, 880, 881, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 90, 91, 810, 811, 890, 891, 20, 21, 15, 16, 17, 18, 19, 90, 91, 810, 811, 890, 891, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 82, 83, 820, 821, 808, 22, 23, 24, 25, 26, 27, 28, 29, 82, 83, 820, 821, 808,
...@@ -529,6 +505,710 @@ const uint16_t DPD2BIN[1024] = { 0, 1, 2, 3, 4, 5, 6, 7, ...@@ -529,6 +505,710 @@ const uint16_t DPD2BIN[1024] = { 0, 1, 2, 3, 4, 5, 6, 7,
757, 758, 759, 794, 795, 956, 957, 798, 799, 760, 761, 762, 763, 757, 758, 759, 794, 795, 956, 957, 798, 799, 760, 761, 762, 763,
764, 765, 766, 767, 768, 769, 786, 787, 966, 967, 988, 989, 770, 764, 765, 766, 767, 768, 769, 786, 787, 966, 967, 988, 989, 770,
771, 772, 773, 774, 775, 776, 777, 778, 779, 796, 797, 976, 977, 771, 772, 773, 774, 775, 776, 777, 778, 779, 796, 797, 976, 977,
998, 999 998, 999};
};
#endif #endif
#if defined(DEC_DPD2BINK) && DEC_DPD2BINK==1 && !defined(DECDPD2BINK)
#define DECDPD2BINK
const uint32_t DPD2BINK[1024]={ 0, 1000, 2000, 3000, 4000, 5000,
6000, 7000, 8000, 9000, 80000, 81000, 800000, 801000, 880000, 881000,
10000, 11000, 12000, 13000, 14000, 15000, 16000, 17000, 18000, 19000,
90000, 91000, 810000, 811000, 890000, 891000, 20000, 21000, 22000, 23000,
24000, 25000, 26000, 27000, 28000, 29000, 82000, 83000, 820000, 821000,
808000, 809000, 30000, 31000, 32000, 33000, 34000, 35000, 36000, 37000,
38000, 39000, 92000, 93000, 830000, 831000, 818000, 819000, 40000, 41000,
42000, 43000, 44000, 45000, 46000, 47000, 48000, 49000, 84000, 85000,
840000, 841000, 88000, 89000, 50000, 51000, 52000, 53000, 54000, 55000,
56000, 57000, 58000, 59000, 94000, 95000, 850000, 851000, 98000, 99000,
60000, 61000, 62000, 63000, 64000, 65000, 66000, 67000, 68000, 69000,
86000, 87000, 860000, 861000, 888000, 889000, 70000, 71000, 72000, 73000,
74000, 75000, 76000, 77000, 78000, 79000, 96000, 97000, 870000, 871000,
898000, 899000, 100000, 101000, 102000, 103000, 104000, 105000, 106000, 107000,
108000, 109000, 180000, 181000, 900000, 901000, 980000, 981000, 110000, 111000,
112000, 113000, 114000, 115000, 116000, 117000, 118000, 119000, 190000, 191000,
910000, 911000, 990000, 991000, 120000, 121000, 122000, 123000, 124000, 125000,
126000, 127000, 128000, 129000, 182000, 183000, 920000, 921000, 908000, 909000,
130000, 131000, 132000, 133000, 134000, 135000, 136000, 137000, 138000, 139000,
192000, 193000, 930000, 931000, 918000, 919000, 140000, 141000, 142000, 143000,
144000, 145000, 146000, 147000, 148000, 149000, 184000, 185000, 940000, 941000,
188000, 189000, 150000, 151000, 152000, 153000, 154000, 155000, 156000, 157000,
158000, 159000, 194000, 195000, 950000, 951000, 198000, 199000, 160000, 161000,
162000, 163000, 164000, 165000, 166000, 167000, 168000, 169000, 186000, 187000,
960000, 961000, 988000, 989000, 170000, 171000, 172000, 173000, 174000, 175000,
176000, 177000, 178000, 179000, 196000, 197000, 970000, 971000, 998000, 999000,
200000, 201000, 202000, 203000, 204000, 205000, 206000, 207000, 208000, 209000,
280000, 281000, 802000, 803000, 882000, 883000, 210000, 211000, 212000, 213000,
214000, 215000, 216000, 217000, 218000, 219000, 290000, 291000, 812000, 813000,
892000, 893000, 220000, 221000, 222000, 223000, 224000, 225000, 226000, 227000,
228000, 229000, 282000, 283000, 822000, 823000, 828000, 829000, 230000, 231000,
232000, 233000, 234000, 235000, 236000, 237000, 238000, 239000, 292000, 293000,
832000, 833000, 838000, 839000, 240000, 241000, 242000, 243000, 244000, 245000,
246000, 247000, 248000, 249000, 284000, 285000, 842000, 843000, 288000, 289000,
250000, 251000, 252000, 253000, 254000, 255000, 256000, 257000, 258000, 259000,
294000, 295000, 852000, 853000, 298000, 299000, 260000, 261000, 262000, 263000,
264000, 265000, 266000, 267000, 268000, 269000, 286000, 287000, 862000, 863000,
888000, 889000, 270000, 271000, 272000, 273000, 274000, 275000, 276000, 277000,
278000, 279000, 296000, 297000, 872000, 873000, 898000, 899000, 300000, 301000,
302000, 303000, 304000, 305000, 306000, 307000, 308000, 309000, 380000, 381000,
902000, 903000, 982000, 983000, 310000, 311000, 312000, 313000, 314000, 315000,
316000, 317000, 318000, 319000, 390000, 391000, 912000, 913000, 992000, 993000,
320000, 321000, 322000, 323000, 324000, 325000, 326000, 327000, 328000, 329000,
382000, 383000, 922000, 923000, 928000, 929000, 330000, 331000, 332000, 333000,
334000, 335000, 336000, 337000, 338000, 339000, 392000, 393000, 932000, 933000,
938000, 939000, 340000, 341000, 342000, 343000, 344000, 345000, 346000, 347000,
348000, 349000, 384000, 385000, 942000, 943000, 388000, 389000, 350000, 351000,
352000, 353000, 354000, 355000, 356000, 357000, 358000, 359000, 394000, 395000,
952000, 953000, 398000, 399000, 360000, 361000, 362000, 363000, 364000, 365000,
366000, 367000, 368000, 369000, 386000, 387000, 962000, 963000, 988000, 989000,
370000, 371000, 372000, 373000, 374000, 375000, 376000, 377000, 378000, 379000,
396000, 397000, 972000, 973000, 998000, 999000, 400000, 401000, 402000, 403000,
404000, 405000, 406000, 407000, 408000, 409000, 480000, 481000, 804000, 805000,
884000, 885000, 410000, 411000, 412000, 413000, 414000, 415000, 416000, 417000,
418000, 419000, 490000, 491000, 814000, 815000, 894000, 895000, 420000, 421000,
422000, 423000, 424000, 425000, 426000, 427000, 428000, 429000, 482000, 483000,
824000, 825000, 848000, 849000, 430000, 431000, 432000, 433000, 434000, 435000,
436000, 437000, 438000, 439000, 492000, 493000, 834000, 835000, 858000, 859000,
440000, 441000, 442000, 443000, 444000, 445000, 446000, 447000, 448000, 449000,
484000, 485000, 844000, 845000, 488000, 489000, 450000, 451000, 452000, 453000,
454000, 455000, 456000, 457000, 458000, 459000, 494000, 495000, 854000, 855000,
498000, 499000, 460000, 461000, 462000, 463000, 464000, 465000, 466000, 467000,
468000, 469000, 486000, 487000, 864000, 865000, 888000, 889000, 470000, 471000,
472000, 473000, 474000, 475000, 476000, 477000, 478000, 479000, 496000, 497000,
874000, 875000, 898000, 899000, 500000, 501000, 502000, 503000, 504000, 505000,
506000, 507000, 508000, 509000, 580000, 581000, 904000, 905000, 984000, 985000,
510000, 511000, 512000, 513000, 514000, 515000, 516000, 517000, 518000, 519000,
590000, 591000, 914000, 915000, 994000, 995000, 520000, 521000, 522000, 523000,
524000, 525000, 526000, 527000, 528000, 529000, 582000, 583000, 924000, 925000,
948000, 949000, 530000, 531000, 532000, 533000, 534000, 535000, 536000, 537000,
538000, 539000, 592000, 593000, 934000, 935000, 958000, 959000, 540000, 541000,
542000, 543000, 544000, 545000, 546000, 547000, 548000, 549000, 584000, 585000,
944000, 945000, 588000, 589000, 550000, 551000, 552000, 553000, 554000, 555000,
556000, 557000, 558000, 559000, 594000, 595000, 954000, 955000, 598000, 599000,
560000, 561000, 562000, 563000, 564000, 565000, 566000, 567000, 568000, 569000,
586000, 587000, 964000, 965000, 988000, 989000, 570000, 571000, 572000, 573000,
574000, 575000, 576000, 577000, 578000, 579000, 596000, 597000, 974000, 975000,
998000, 999000, 600000, 601000, 602000, 603000, 604000, 605000, 606000, 607000,
608000, 609000, 680000, 681000, 806000, 807000, 886000, 887000, 610000, 611000,
612000, 613000, 614000, 615000, 616000, 617000, 618000, 619000, 690000, 691000,
816000, 817000, 896000, 897000, 620000, 621000, 622000, 623000, 624000, 625000,
626000, 627000, 628000, 629000, 682000, 683000, 826000, 827000, 868000, 869000,
630000, 631000, 632000, 633000, 634000, 635000, 636000, 637000, 638000, 639000,
692000, 693000, 836000, 837000, 878000, 879000, 640000, 641000, 642000, 643000,
644000, 645000, 646000, 647000, 648000, 649000, 684000, 685000, 846000, 847000,
688000, 689000, 650000, 651000, 652000, 653000, 654000, 655000, 656000, 657000,
658000, 659000, 694000, 695000, 856000, 857000, 698000, 699000, 660000, 661000,
662000, 663000, 664000, 665000, 666000, 667000, 668000, 669000, 686000, 687000,
866000, 867000, 888000, 889000, 670000, 671000, 672000, 673000, 674000, 675000,
676000, 677000, 678000, 679000, 696000, 697000, 876000, 877000, 898000, 899000,
700000, 701000, 702000, 703000, 704000, 705000, 706000, 707000, 708000, 709000,
780000, 781000, 906000, 907000, 986000, 987000, 710000, 711000, 712000, 713000,
714000, 715000, 716000, 717000, 718000, 719000, 790000, 791000, 916000, 917000,
996000, 997000, 720000, 721000, 722000, 723000, 724000, 725000, 726000, 727000,
728000, 729000, 782000, 783000, 926000, 927000, 968000, 969000, 730000, 731000,
732000, 733000, 734000, 735000, 736000, 737000, 738000, 739000, 792000, 793000,
936000, 937000, 978000, 979000, 740000, 741000, 742000, 743000, 744000, 745000,
746000, 747000, 748000, 749000, 784000, 785000, 946000, 947000, 788000, 789000,
750000, 751000, 752000, 753000, 754000, 755000, 756000, 757000, 758000, 759000,
794000, 795000, 956000, 957000, 798000, 799000, 760000, 761000, 762000, 763000,
764000, 765000, 766000, 767000, 768000, 769000, 786000, 787000, 966000, 967000,
988000, 989000, 770000, 771000, 772000, 773000, 774000, 775000, 776000, 777000,
778000, 779000, 796000, 797000, 976000, 977000, 998000, 999000};
#endif
#if defined(DEC_DPD2BINM) && DEC_DPD2BINM==1 && !defined(DECDPD2BINM)
#define DECDPD2BINM
const uint32_t DPD2BINM[1024]={0, 1000000, 2000000, 3000000, 4000000,
5000000, 6000000, 7000000, 8000000, 9000000, 80000000, 81000000,
800000000, 801000000, 880000000, 881000000, 10000000, 11000000, 12000000,
13000000, 14000000, 15000000, 16000000, 17000000, 18000000, 19000000,
90000000, 91000000, 810000000, 811000000, 890000000, 891000000, 20000000,
21000000, 22000000, 23000000, 24000000, 25000000, 26000000, 27000000,
28000000, 29000000, 82000000, 83000000, 820000000, 821000000, 808000000,
809000000, 30000000, 31000000, 32000000, 33000000, 34000000, 35000000,
36000000, 37000000, 38000000, 39000000, 92000000, 93000000, 830000000,
831000000, 818000000, 819000000, 40000000, 41000000, 42000000, 43000000,
44000000, 45000000, 46000000, 47000000, 48000000, 49000000, 84000000,
85000000, 840000000, 841000000, 88000000, 89000000, 50000000, 51000000,
52000000, 53000000, 54000000, 55000000, 56000000, 57000000, 58000000,
59000000, 94000000, 95000000, 850000000, 851000000, 98000000, 99000000,
60000000, 61000000, 62000000, 63000000, 64000000, 65000000, 66000000,
67000000, 68000000, 69000000, 86000000, 87000000, 860000000, 861000000,
888000000, 889000000, 70000000, 71000000, 72000000, 73000000, 74000000,
75000000, 76000000, 77000000, 78000000, 79000000, 96000000, 97000000,
870000000, 871000000, 898000000, 899000000, 100000000, 101000000, 102000000,
103000000, 104000000, 105000000, 106000000, 107000000, 108000000, 109000000,
180000000, 181000000, 900000000, 901000000, 980000000, 981000000, 110000000,
111000000, 112000000, 113000000, 114000000, 115000000, 116000000, 117000000,
118000000, 119000000, 190000000, 191000000, 910000000, 911000000, 990000000,
991000000, 120000000, 121000000, 122000000, 123000000, 124000000, 125000000,
126000000, 127000000, 128000000, 129000000, 182000000, 183000000, 920000000,
921000000, 908000000, 909000000, 130000000, 131000000, 132000000, 133000000,
134000000, 135000000, 136000000, 137000000, 138000000, 139000000, 192000000,
193000000, 930000000, 931000000, 918000000, 919000000, 140000000, 141000000,
142000000, 143000000, 144000000, 145000000, 146000000, 147000000, 148000000,
149000000, 184000000, 185000000, 940000000, 941000000, 188000000, 189000000,
150000000, 151000000, 152000000, 153000000, 154000000, 155000000, 156000000,
157000000, 158000000, 159000000, 194000000, 195000000, 950000000, 951000000,
198000000, 199000000, 160000000, 161000000, 162000000, 163000000, 164000000,
165000000, 166000000, 167000000, 168000000, 169000000, 186000000, 187000000,
960000000, 961000000, 988000000, 989000000, 170000000, 171000000, 172000000,
173000000, 174000000, 175000000, 176000000, 177000000, 178000000, 179000000,
196000000, 197000000, 970000000, 971000000, 998000000, 999000000, 200000000,
201000000, 202000000, 203000000, 204000000, 205000000, 206000000, 207000000,
208000000, 209000000, 280000000, 281000000, 802000000, 803000000, 882000000,
883000000, 210000000, 211000000, 212000000, 213000000, 214000000, 215000000,
216000000, 217000000, 218000000, 219000000, 290000000, 291000000, 812000000,
813000000, 892000000, 893000000, 220000000, 221000000, 222000000, 223000000,
224000000, 225000000, 226000000, 227000000, 228000000, 229000000, 282000000,
283000000, 822000000, 823000000, 828000000, 829000000, 230000000, 231000000,
232000000, 233000000, 234000000, 235000000, 236000000, 237000000, 238000000,
239000000, 292000000, 293000000, 832000000, 833000000, 838000000, 839000000,
240000000, 241000000, 242000000, 243000000, 244000000, 245000000, 246000000,
247000000, 248000000, 249000000, 284000000, 285000000, 842000000, 843000000,
288000000, 289000000, 250000000, 251000000, 252000000, 253000000, 254000000,
255000000, 256000000, 257000000, 258000000, 259000000, 294000000, 295000000,
852000000, 853000000, 298000000, 299000000, 260000000, 261000000, 262000000,
263000000, 264000000, 265000000, 266000000, 267000000, 268000000, 269000000,
286000000, 287000000, 862000000, 863000000, 888000000, 889000000, 270000000,
271000000, 272000000, 273000000, 274000000, 275000000, 276000000, 277000000,
278000000, 279000000, 296000000, 297000000, 872000000, 873000000, 898000000,
899000000, 300000000, 301000000, 302000000, 303000000, 304000000, 305000000,
306000000, 307000000, 308000000, 309000000, 380000000, 381000000, 902000000,
903000000, 982000000, 983000000, 310000000, 311000000, 312000000, 313000000,
314000000, 315000000, 316000000, 317000000, 318000000, 319000000, 390000000,
391000000, 912000000, 913000000, 992000000, 993000000, 320000000, 321000000,
322000000, 323000000, 324000000, 325000000, 326000000, 327000000, 328000000,
329000000, 382000000, 383000000, 922000000, 923000000, 928000000, 929000000,
330000000, 331000000, 332000000, 333000000, 334000000, 335000000, 336000000,
337000000, 338000000, 339000000, 392000000, 393000000, 932000000, 933000000,
938000000, 939000000, 340000000, 341000000, 342000000, 343000000, 344000000,
345000000, 346000000, 347000000, 348000000, 349000000, 384000000, 385000000,
942000000, 943000000, 388000000, 389000000, 350000000, 351000000, 352000000,
353000000, 354000000, 355000000, 356000000, 357000000, 358000000, 359000000,
394000000, 395000000, 952000000, 953000000, 398000000, 399000000, 360000000,
361000000, 362000000, 363000000, 364000000, 365000000, 366000000, 367000000,
368000000, 369000000, 386000000, 387000000, 962000000, 963000000, 988000000,
989000000, 370000000, 371000000, 372000000, 373000000, 374000000, 375000000,
376000000, 377000000, 378000000, 379000000, 396000000, 397000000, 972000000,
973000000, 998000000, 999000000, 400000000, 401000000, 402000000, 403000000,
404000000, 405000000, 406000000, 407000000, 408000000, 409000000, 480000000,
481000000, 804000000, 805000000, 884000000, 885000000, 410000000, 411000000,
412000000, 413000000, 414000000, 415000000, 416000000, 417000000, 418000000,
419000000, 490000000, 491000000, 814000000, 815000000, 894000000, 895000000,
420000000, 421000000, 422000000, 423000000, 424000000, 425000000, 426000000,
427000000, 428000000, 429000000, 482000000, 483000000, 824000000, 825000000,
848000000, 849000000, 430000000, 431000000, 432000000, 433000000, 434000000,
435000000, 436000000, 437000000, 438000000, 439000000, 492000000, 493000000,
834000000, 835000000, 858000000, 859000000, 440000000, 441000000, 442000000,
443000000, 444000000, 445000000, 446000000, 447000000, 448000000, 449000000,
484000000, 485000000, 844000000, 845000000, 488000000, 489000000, 450000000,
451000000, 452000000, 453000000, 454000000, 455000000, 456000000, 457000000,
458000000, 459000000, 494000000, 495000000, 854000000, 855000000, 498000000,
499000000, 460000000, 461000000, 462000000, 463000000, 464000000, 465000000,
466000000, 467000000, 468000000, 469000000, 486000000, 487000000, 864000000,
865000000, 888000000, 889000000, 470000000, 471000000, 472000000, 473000000,
474000000, 475000000, 476000000, 477000000, 478000000, 479000000, 496000000,
497000000, 874000000, 875000000, 898000000, 899000000, 500000000, 501000000,
502000000, 503000000, 504000000, 505000000, 506000000, 507000000, 508000000,
509000000, 580000000, 581000000, 904000000, 905000000, 984000000, 985000000,
510000000, 511000000, 512000000, 513000000, 514000000, 515000000, 516000000,
517000000, 518000000, 519000000, 590000000, 591000000, 914000000, 915000000,
994000000, 995000000, 520000000, 521000000, 522000000, 523000000, 524000000,
525000000, 526000000, 527000000, 528000000, 529000000, 582000000, 583000000,
924000000, 925000000, 948000000, 949000000, 530000000, 531000000, 532000000,
533000000, 534000000, 535000000, 536000000, 537000000, 538000000, 539000000,
592000000, 593000000, 934000000, 935000000, 958000000, 959000000, 540000000,
541000000, 542000000, 543000000, 544000000, 545000000, 546000000, 547000000,
548000000, 549000000, 584000000, 585000000, 944000000, 945000000, 588000000,
589000000, 550000000, 551000000, 552000000, 553000000, 554000000, 555000000,
556000000, 557000000, 558000000, 559000000, 594000000, 595000000, 954000000,
955000000, 598000000, 599000000, 560000000, 561000000, 562000000, 563000000,
564000000, 565000000, 566000000, 567000000, 568000000, 569000000, 586000000,
587000000, 964000000, 965000000, 988000000, 989000000, 570000000, 571000000,
572000000, 573000000, 574000000, 575000000, 576000000, 577000000, 578000000,
579000000, 596000000, 597000000, 974000000, 975000000, 998000000, 999000000,
600000000, 601000000, 602000000, 603000000, 604000000, 605000000, 606000000,
607000000, 608000000, 609000000, 680000000, 681000000, 806000000, 807000000,
886000000, 887000000, 610000000, 611000000, 612000000, 613000000, 614000000,
615000000, 616000000, 617000000, 618000000, 619000000, 690000000, 691000000,
816000000, 817000000, 896000000, 897000000, 620000000, 621000000, 622000000,
623000000, 624000000, 625000000, 626000000, 627000000, 628000000, 629000000,
682000000, 683000000, 826000000, 827000000, 868000000, 869000000, 630000000,
631000000, 632000000, 633000000, 634000000, 635000000, 636000000, 637000000,
638000000, 639000000, 692000000, 693000000, 836000000, 837000000, 878000000,
879000000, 640000000, 641000000, 642000000, 643000000, 644000000, 645000000,
646000000, 647000000, 648000000, 649000000, 684000000, 685000000, 846000000,
847000000, 688000000, 689000000, 650000000, 651000000, 652000000, 653000000,
654000000, 655000000, 656000000, 657000000, 658000000, 659000000, 694000000,
695000000, 856000000, 857000000, 698000000, 699000000, 660000000, 661000000,
662000000, 663000000, 664000000, 665000000, 666000000, 667000000, 668000000,
669000000, 686000000, 687000000, 866000000, 867000000, 888000000, 889000000,
670000000, 671000000, 672000000, 673000000, 674000000, 675000000, 676000000,
677000000, 678000000, 679000000, 696000000, 697000000, 876000000, 877000000,
898000000, 899000000, 700000000, 701000000, 702000000, 703000000, 704000000,
705000000, 706000000, 707000000, 708000000, 709000000, 780000000, 781000000,
906000000, 907000000, 986000000, 987000000, 710000000, 711000000, 712000000,
713000000, 714000000, 715000000, 716000000, 717000000, 718000000, 719000000,
790000000, 791000000, 916000000, 917000000, 996000000, 997000000, 720000000,
721000000, 722000000, 723000000, 724000000, 725000000, 726000000, 727000000,
728000000, 729000000, 782000000, 783000000, 926000000, 927000000, 968000000,
969000000, 730000000, 731000000, 732000000, 733000000, 734000000, 735000000,
736000000, 737000000, 738000000, 739000000, 792000000, 793000000, 936000000,
937000000, 978000000, 979000000, 740000000, 741000000, 742000000, 743000000,
744000000, 745000000, 746000000, 747000000, 748000000, 749000000, 784000000,
785000000, 946000000, 947000000, 788000000, 789000000, 750000000, 751000000,
752000000, 753000000, 754000000, 755000000, 756000000, 757000000, 758000000,
759000000, 794000000, 795000000, 956000000, 957000000, 798000000, 799000000,
760000000, 761000000, 762000000, 763000000, 764000000, 765000000, 766000000,
767000000, 768000000, 769000000, 786000000, 787000000, 966000000, 967000000,
988000000, 989000000, 770000000, 771000000, 772000000, 773000000, 774000000,
775000000, 776000000, 777000000, 778000000, 779000000, 796000000, 797000000,
976000000, 977000000, 998000000, 999000000};
#endif
#if defined(DEC_BIN2CHAR) && DEC_BIN2CHAR==1 && !defined(DECBIN2CHAR)
#define DECBIN2CHAR
const uint8_t BIN2CHAR[4001]={
'\0','0','0','0', '\1','0','0','1', '\1','0','0','2', '\1','0','0','3', '\1','0','0','4',
'\1','0','0','5', '\1','0','0','6', '\1','0','0','7', '\1','0','0','8', '\1','0','0','9',
'\2','0','1','0', '\2','0','1','1', '\2','0','1','2', '\2','0','1','3', '\2','0','1','4',
'\2','0','1','5', '\2','0','1','6', '\2','0','1','7', '\2','0','1','8', '\2','0','1','9',
'\2','0','2','0', '\2','0','2','1', '\2','0','2','2', '\2','0','2','3', '\2','0','2','4',
'\2','0','2','5', '\2','0','2','6', '\2','0','2','7', '\2','0','2','8', '\2','0','2','9',
'\2','0','3','0', '\2','0','3','1', '\2','0','3','2', '\2','0','3','3', '\2','0','3','4',
'\2','0','3','5', '\2','0','3','6', '\2','0','3','7', '\2','0','3','8', '\2','0','3','9',
'\2','0','4','0', '\2','0','4','1', '\2','0','4','2', '\2','0','4','3', '\2','0','4','4',
'\2','0','4','5', '\2','0','4','6', '\2','0','4','7', '\2','0','4','8', '\2','0','4','9',
'\2','0','5','0', '\2','0','5','1', '\2','0','5','2', '\2','0','5','3', '\2','0','5','4',
'\2','0','5','5', '\2','0','5','6', '\2','0','5','7', '\2','0','5','8', '\2','0','5','9',
'\2','0','6','0', '\2','0','6','1', '\2','0','6','2', '\2','0','6','3', '\2','0','6','4',
'\2','0','6','5', '\2','0','6','6', '\2','0','6','7', '\2','0','6','8', '\2','0','6','9',
'\2','0','7','0', '\2','0','7','1', '\2','0','7','2', '\2','0','7','3', '\2','0','7','4',
'\2','0','7','5', '\2','0','7','6', '\2','0','7','7', '\2','0','7','8', '\2','0','7','9',
'\2','0','8','0', '\2','0','8','1', '\2','0','8','2', '\2','0','8','3', '\2','0','8','4',
'\2','0','8','5', '\2','0','8','6', '\2','0','8','7', '\2','0','8','8', '\2','0','8','9',
'\2','0','9','0', '\2','0','9','1', '\2','0','9','2', '\2','0','9','3', '\2','0','9','4',
'\2','0','9','5', '\2','0','9','6', '\2','0','9','7', '\2','0','9','8', '\2','0','9','9',
'\3','1','0','0', '\3','1','0','1', '\3','1','0','2', '\3','1','0','3', '\3','1','0','4',
'\3','1','0','5', '\3','1','0','6', '\3','1','0','7', '\3','1','0','8', '\3','1','0','9',
'\3','1','1','0', '\3','1','1','1', '\3','1','1','2', '\3','1','1','3', '\3','1','1','4',
'\3','1','1','5', '\3','1','1','6', '\3','1','1','7', '\3','1','1','8', '\3','1','1','9',
'\3','1','2','0', '\3','1','2','1', '\3','1','2','2', '\3','1','2','3', '\3','1','2','4',
'\3','1','2','5', '\3','1','2','6', '\3','1','2','7', '\3','1','2','8', '\3','1','2','9',
'\3','1','3','0', '\3','1','3','1', '\3','1','3','2', '\3','1','3','3', '\3','1','3','4',
'\3','1','3','5', '\3','1','3','6', '\3','1','3','7', '\3','1','3','8', '\3','1','3','9',
'\3','1','4','0', '\3','1','4','1', '\3','1','4','2', '\3','1','4','3', '\3','1','4','4',
'\3','1','4','5', '\3','1','4','6', '\3','1','4','7', '\3','1','4','8', '\3','1','4','9',
'\3','1','5','0', '\3','1','5','1', '\3','1','5','2', '\3','1','5','3', '\3','1','5','4',
'\3','1','5','5', '\3','1','5','6', '\3','1','5','7', '\3','1','5','8', '\3','1','5','9',
'\3','1','6','0', '\3','1','6','1', '\3','1','6','2', '\3','1','6','3', '\3','1','6','4',
'\3','1','6','5', '\3','1','6','6', '\3','1','6','7', '\3','1','6','8', '\3','1','6','9',
'\3','1','7','0', '\3','1','7','1', '\3','1','7','2', '\3','1','7','3', '\3','1','7','4',
'\3','1','7','5', '\3','1','7','6', '\3','1','7','7', '\3','1','7','8', '\3','1','7','9',
'\3','1','8','0', '\3','1','8','1', '\3','1','8','2', '\3','1','8','3', '\3','1','8','4',
'\3','1','8','5', '\3','1','8','6', '\3','1','8','7', '\3','1','8','8', '\3','1','8','9',
'\3','1','9','0', '\3','1','9','1', '\3','1','9','2', '\3','1','9','3', '\3','1','9','4',
'\3','1','9','5', '\3','1','9','6', '\3','1','9','7', '\3','1','9','8', '\3','1','9','9',
'\3','2','0','0', '\3','2','0','1', '\3','2','0','2', '\3','2','0','3', '\3','2','0','4',
'\3','2','0','5', '\3','2','0','6', '\3','2','0','7', '\3','2','0','8', '\3','2','0','9',
'\3','2','1','0', '\3','2','1','1', '\3','2','1','2', '\3','2','1','3', '\3','2','1','4',
'\3','2','1','5', '\3','2','1','6', '\3','2','1','7', '\3','2','1','8', '\3','2','1','9',
'\3','2','2','0', '\3','2','2','1', '\3','2','2','2', '\3','2','2','3', '\3','2','2','4',
'\3','2','2','5', '\3','2','2','6', '\3','2','2','7', '\3','2','2','8', '\3','2','2','9',
'\3','2','3','0', '\3','2','3','1', '\3','2','3','2', '\3','2','3','3', '\3','2','3','4',
'\3','2','3','5', '\3','2','3','6', '\3','2','3','7', '\3','2','3','8', '\3','2','3','9',
'\3','2','4','0', '\3','2','4','1', '\3','2','4','2', '\3','2','4','3', '\3','2','4','4',
'\3','2','4','5', '\3','2','4','6', '\3','2','4','7', '\3','2','4','8', '\3','2','4','9',
'\3','2','5','0', '\3','2','5','1', '\3','2','5','2', '\3','2','5','3', '\3','2','5','4',
'\3','2','5','5', '\3','2','5','6', '\3','2','5','7', '\3','2','5','8', '\3','2','5','9',
'\3','2','6','0', '\3','2','6','1', '\3','2','6','2', '\3','2','6','3', '\3','2','6','4',
'\3','2','6','5', '\3','2','6','6', '\3','2','6','7', '\3','2','6','8', '\3','2','6','9',
'\3','2','7','0', '\3','2','7','1', '\3','2','7','2', '\3','2','7','3', '\3','2','7','4',
'\3','2','7','5', '\3','2','7','6', '\3','2','7','7', '\3','2','7','8', '\3','2','7','9',
'\3','2','8','0', '\3','2','8','1', '\3','2','8','2', '\3','2','8','3', '\3','2','8','4',
'\3','2','8','5', '\3','2','8','6', '\3','2','8','7', '\3','2','8','8', '\3','2','8','9',
'\3','2','9','0', '\3','2','9','1', '\3','2','9','2', '\3','2','9','3', '\3','2','9','4',
'\3','2','9','5', '\3','2','9','6', '\3','2','9','7', '\3','2','9','8', '\3','2','9','9',
'\3','3','0','0', '\3','3','0','1', '\3','3','0','2', '\3','3','0','3', '\3','3','0','4',
'\3','3','0','5', '\3','3','0','6', '\3','3','0','7', '\3','3','0','8', '\3','3','0','9',
'\3','3','1','0', '\3','3','1','1', '\3','3','1','2', '\3','3','1','3', '\3','3','1','4',
'\3','3','1','5', '\3','3','1','6', '\3','3','1','7', '\3','3','1','8', '\3','3','1','9',
'\3','3','2','0', '\3','3','2','1', '\3','3','2','2', '\3','3','2','3', '\3','3','2','4',
'\3','3','2','5', '\3','3','2','6', '\3','3','2','7', '\3','3','2','8', '\3','3','2','9',
'\3','3','3','0', '\3','3','3','1', '\3','3','3','2', '\3','3','3','3', '\3','3','3','4',
'\3','3','3','5', '\3','3','3','6', '\3','3','3','7', '\3','3','3','8', '\3','3','3','9',
'\3','3','4','0', '\3','3','4','1', '\3','3','4','2', '\3','3','4','3', '\3','3','4','4',
'\3','3','4','5', '\3','3','4','6', '\3','3','4','7', '\3','3','4','8', '\3','3','4','9',
'\3','3','5','0', '\3','3','5','1', '\3','3','5','2', '\3','3','5','3', '\3','3','5','4',
'\3','3','5','5', '\3','3','5','6', '\3','3','5','7', '\3','3','5','8', '\3','3','5','9',
'\3','3','6','0', '\3','3','6','1', '\3','3','6','2', '\3','3','6','3', '\3','3','6','4',
'\3','3','6','5', '\3','3','6','6', '\3','3','6','7', '\3','3','6','8', '\3','3','6','9',
'\3','3','7','0', '\3','3','7','1', '\3','3','7','2', '\3','3','7','3', '\3','3','7','4',
'\3','3','7','5', '\3','3','7','6', '\3','3','7','7', '\3','3','7','8', '\3','3','7','9',
'\3','3','8','0', '\3','3','8','1', '\3','3','8','2', '\3','3','8','3', '\3','3','8','4',
'\3','3','8','5', '\3','3','8','6', '\3','3','8','7', '\3','3','8','8', '\3','3','8','9',
'\3','3','9','0', '\3','3','9','1', '\3','3','9','2', '\3','3','9','3', '\3','3','9','4',
'\3','3','9','5', '\3','3','9','6', '\3','3','9','7', '\3','3','9','8', '\3','3','9','9',
'\3','4','0','0', '\3','4','0','1', '\3','4','0','2', '\3','4','0','3', '\3','4','0','4',
'\3','4','0','5', '\3','4','0','6', '\3','4','0','7', '\3','4','0','8', '\3','4','0','9',
'\3','4','1','0', '\3','4','1','1', '\3','4','1','2', '\3','4','1','3', '\3','4','1','4',
'\3','4','1','5', '\3','4','1','6', '\3','4','1','7', '\3','4','1','8', '\3','4','1','9',
'\3','4','2','0', '\3','4','2','1', '\3','4','2','2', '\3','4','2','3', '\3','4','2','4',
'\3','4','2','5', '\3','4','2','6', '\3','4','2','7', '\3','4','2','8', '\3','4','2','9',
'\3','4','3','0', '\3','4','3','1', '\3','4','3','2', '\3','4','3','3', '\3','4','3','4',
'\3','4','3','5', '\3','4','3','6', '\3','4','3','7', '\3','4','3','8', '\3','4','3','9',
'\3','4','4','0', '\3','4','4','1', '\3','4','4','2', '\3','4','4','3', '\3','4','4','4',
'\3','4','4','5', '\3','4','4','6', '\3','4','4','7', '\3','4','4','8', '\3','4','4','9',
'\3','4','5','0', '\3','4','5','1', '\3','4','5','2', '\3','4','5','3', '\3','4','5','4',
'\3','4','5','5', '\3','4','5','6', '\3','4','5','7', '\3','4','5','8', '\3','4','5','9',
'\3','4','6','0', '\3','4','6','1', '\3','4','6','2', '\3','4','6','3', '\3','4','6','4',
'\3','4','6','5', '\3','4','6','6', '\3','4','6','7', '\3','4','6','8', '\3','4','6','9',
'\3','4','7','0', '\3','4','7','1', '\3','4','7','2', '\3','4','7','3', '\3','4','7','4',
'\3','4','7','5', '\3','4','7','6', '\3','4','7','7', '\3','4','7','8', '\3','4','7','9',
'\3','4','8','0', '\3','4','8','1', '\3','4','8','2', '\3','4','8','3', '\3','4','8','4',
'\3','4','8','5', '\3','4','8','6', '\3','4','8','7', '\3','4','8','8', '\3','4','8','9',
'\3','4','9','0', '\3','4','9','1', '\3','4','9','2', '\3','4','9','3', '\3','4','9','4',
'\3','4','9','5', '\3','4','9','6', '\3','4','9','7', '\3','4','9','8', '\3','4','9','9',
'\3','5','0','0', '\3','5','0','1', '\3','5','0','2', '\3','5','0','3', '\3','5','0','4',
'\3','5','0','5', '\3','5','0','6', '\3','5','0','7', '\3','5','0','8', '\3','5','0','9',
'\3','5','1','0', '\3','5','1','1', '\3','5','1','2', '\3','5','1','3', '\3','5','1','4',
'\3','5','1','5', '\3','5','1','6', '\3','5','1','7', '\3','5','1','8', '\3','5','1','9',
'\3','5','2','0', '\3','5','2','1', '\3','5','2','2', '\3','5','2','3', '\3','5','2','4',
'\3','5','2','5', '\3','5','2','6', '\3','5','2','7', '\3','5','2','8', '\3','5','2','9',
'\3','5','3','0', '\3','5','3','1', '\3','5','3','2', '\3','5','3','3', '\3','5','3','4',
'\3','5','3','5', '\3','5','3','6', '\3','5','3','7', '\3','5','3','8', '\3','5','3','9',
'\3','5','4','0', '\3','5','4','1', '\3','5','4','2', '\3','5','4','3', '\3','5','4','4',
'\3','5','4','5', '\3','5','4','6', '\3','5','4','7', '\3','5','4','8', '\3','5','4','9',
'\3','5','5','0', '\3','5','5','1', '\3','5','5','2', '\3','5','5','3', '\3','5','5','4',
'\3','5','5','5', '\3','5','5','6', '\3','5','5','7', '\3','5','5','8', '\3','5','5','9',
'\3','5','6','0', '\3','5','6','1', '\3','5','6','2', '\3','5','6','3', '\3','5','6','4',
'\3','5','6','5', '\3','5','6','6', '\3','5','6','7', '\3','5','6','8', '\3','5','6','9',
'\3','5','7','0', '\3','5','7','1', '\3','5','7','2', '\3','5','7','3', '\3','5','7','4',
'\3','5','7','5', '\3','5','7','6', '\3','5','7','7', '\3','5','7','8', '\3','5','7','9',
'\3','5','8','0', '\3','5','8','1', '\3','5','8','2', '\3','5','8','3', '\3','5','8','4',
'\3','5','8','5', '\3','5','8','6', '\3','5','8','7', '\3','5','8','8', '\3','5','8','9',
'\3','5','9','0', '\3','5','9','1', '\3','5','9','2', '\3','5','9','3', '\3','5','9','4',
'\3','5','9','5', '\3','5','9','6', '\3','5','9','7', '\3','5','9','8', '\3','5','9','9',
'\3','6','0','0', '\3','6','0','1', '\3','6','0','2', '\3','6','0','3', '\3','6','0','4',
'\3','6','0','5', '\3','6','0','6', '\3','6','0','7', '\3','6','0','8', '\3','6','0','9',
'\3','6','1','0', '\3','6','1','1', '\3','6','1','2', '\3','6','1','3', '\3','6','1','4',
'\3','6','1','5', '\3','6','1','6', '\3','6','1','7', '\3','6','1','8', '\3','6','1','9',
'\3','6','2','0', '\3','6','2','1', '\3','6','2','2', '\3','6','2','3', '\3','6','2','4',
'\3','6','2','5', '\3','6','2','6', '\3','6','2','7', '\3','6','2','8', '\3','6','2','9',
'\3','6','3','0', '\3','6','3','1', '\3','6','3','2', '\3','6','3','3', '\3','6','3','4',
'\3','6','3','5', '\3','6','3','6', '\3','6','3','7', '\3','6','3','8', '\3','6','3','9',
'\3','6','4','0', '\3','6','4','1', '\3','6','4','2', '\3','6','4','3', '\3','6','4','4',
'\3','6','4','5', '\3','6','4','6', '\3','6','4','7', '\3','6','4','8', '\3','6','4','9',
'\3','6','5','0', '\3','6','5','1', '\3','6','5','2', '\3','6','5','3', '\3','6','5','4',
'\3','6','5','5', '\3','6','5','6', '\3','6','5','7', '\3','6','5','8', '\3','6','5','9',
'\3','6','6','0', '\3','6','6','1', '\3','6','6','2', '\3','6','6','3', '\3','6','6','4',
'\3','6','6','5', '\3','6','6','6', '\3','6','6','7', '\3','6','6','8', '\3','6','6','9',
'\3','6','7','0', '\3','6','7','1', '\3','6','7','2', '\3','6','7','3', '\3','6','7','4',
'\3','6','7','5', '\3','6','7','6', '\3','6','7','7', '\3','6','7','8', '\3','6','7','9',
'\3','6','8','0', '\3','6','8','1', '\3','6','8','2', '\3','6','8','3', '\3','6','8','4',
'\3','6','8','5', '\3','6','8','6', '\3','6','8','7', '\3','6','8','8', '\3','6','8','9',
'\3','6','9','0', '\3','6','9','1', '\3','6','9','2', '\3','6','9','3', '\3','6','9','4',
'\3','6','9','5', '\3','6','9','6', '\3','6','9','7', '\3','6','9','8', '\3','6','9','9',
'\3','7','0','0', '\3','7','0','1', '\3','7','0','2', '\3','7','0','3', '\3','7','0','4',
'\3','7','0','5', '\3','7','0','6', '\3','7','0','7', '\3','7','0','8', '\3','7','0','9',
'\3','7','1','0', '\3','7','1','1', '\3','7','1','2', '\3','7','1','3', '\3','7','1','4',
'\3','7','1','5', '\3','7','1','6', '\3','7','1','7', '\3','7','1','8', '\3','7','1','9',
'\3','7','2','0', '\3','7','2','1', '\3','7','2','2', '\3','7','2','3', '\3','7','2','4',
'\3','7','2','5', '\3','7','2','6', '\3','7','2','7', '\3','7','2','8', '\3','7','2','9',
'\3','7','3','0', '\3','7','3','1', '\3','7','3','2', '\3','7','3','3', '\3','7','3','4',
'\3','7','3','5', '\3','7','3','6', '\3','7','3','7', '\3','7','3','8', '\3','7','3','9',
'\3','7','4','0', '\3','7','4','1', '\3','7','4','2', '\3','7','4','3', '\3','7','4','4',
'\3','7','4','5', '\3','7','4','6', '\3','7','4','7', '\3','7','4','8', '\3','7','4','9',
'\3','7','5','0', '\3','7','5','1', '\3','7','5','2', '\3','7','5','3', '\3','7','5','4',
'\3','7','5','5', '\3','7','5','6', '\3','7','5','7', '\3','7','5','8', '\3','7','5','9',
'\3','7','6','0', '\3','7','6','1', '\3','7','6','2', '\3','7','6','3', '\3','7','6','4',
'\3','7','6','5', '\3','7','6','6', '\3','7','6','7', '\3','7','6','8', '\3','7','6','9',
'\3','7','7','0', '\3','7','7','1', '\3','7','7','2', '\3','7','7','3', '\3','7','7','4',
'\3','7','7','5', '\3','7','7','6', '\3','7','7','7', '\3','7','7','8', '\3','7','7','9',
'\3','7','8','0', '\3','7','8','1', '\3','7','8','2', '\3','7','8','3', '\3','7','8','4',
'\3','7','8','5', '\3','7','8','6', '\3','7','8','7', '\3','7','8','8', '\3','7','8','9',
'\3','7','9','0', '\3','7','9','1', '\3','7','9','2', '\3','7','9','3', '\3','7','9','4',
'\3','7','9','5', '\3','7','9','6', '\3','7','9','7', '\3','7','9','8', '\3','7','9','9',
'\3','8','0','0', '\3','8','0','1', '\3','8','0','2', '\3','8','0','3', '\3','8','0','4',
'\3','8','0','5', '\3','8','0','6', '\3','8','0','7', '\3','8','0','8', '\3','8','0','9',
'\3','8','1','0', '\3','8','1','1', '\3','8','1','2', '\3','8','1','3', '\3','8','1','4',
'\3','8','1','5', '\3','8','1','6', '\3','8','1','7', '\3','8','1','8', '\3','8','1','9',
'\3','8','2','0', '\3','8','2','1', '\3','8','2','2', '\3','8','2','3', '\3','8','2','4',
'\3','8','2','5', '\3','8','2','6', '\3','8','2','7', '\3','8','2','8', '\3','8','2','9',
'\3','8','3','0', '\3','8','3','1', '\3','8','3','2', '\3','8','3','3', '\3','8','3','4',
'\3','8','3','5', '\3','8','3','6', '\3','8','3','7', '\3','8','3','8', '\3','8','3','9',
'\3','8','4','0', '\3','8','4','1', '\3','8','4','2', '\3','8','4','3', '\3','8','4','4',
'\3','8','4','5', '\3','8','4','6', '\3','8','4','7', '\3','8','4','8', '\3','8','4','9',
'\3','8','5','0', '\3','8','5','1', '\3','8','5','2', '\3','8','5','3', '\3','8','5','4',
'\3','8','5','5', '\3','8','5','6', '\3','8','5','7', '\3','8','5','8', '\3','8','5','9',
'\3','8','6','0', '\3','8','6','1', '\3','8','6','2', '\3','8','6','3', '\3','8','6','4',
'\3','8','6','5', '\3','8','6','6', '\3','8','6','7', '\3','8','6','8', '\3','8','6','9',
'\3','8','7','0', '\3','8','7','1', '\3','8','7','2', '\3','8','7','3', '\3','8','7','4',
'\3','8','7','5', '\3','8','7','6', '\3','8','7','7', '\3','8','7','8', '\3','8','7','9',
'\3','8','8','0', '\3','8','8','1', '\3','8','8','2', '\3','8','8','3', '\3','8','8','4',
'\3','8','8','5', '\3','8','8','6', '\3','8','8','7', '\3','8','8','8', '\3','8','8','9',
'\3','8','9','0', '\3','8','9','1', '\3','8','9','2', '\3','8','9','3', '\3','8','9','4',
'\3','8','9','5', '\3','8','9','6', '\3','8','9','7', '\3','8','9','8', '\3','8','9','9',
'\3','9','0','0', '\3','9','0','1', '\3','9','0','2', '\3','9','0','3', '\3','9','0','4',
'\3','9','0','5', '\3','9','0','6', '\3','9','0','7', '\3','9','0','8', '\3','9','0','9',
'\3','9','1','0', '\3','9','1','1', '\3','9','1','2', '\3','9','1','3', '\3','9','1','4',
'\3','9','1','5', '\3','9','1','6', '\3','9','1','7', '\3','9','1','8', '\3','9','1','9',
'\3','9','2','0', '\3','9','2','1', '\3','9','2','2', '\3','9','2','3', '\3','9','2','4',
'\3','9','2','5', '\3','9','2','6', '\3','9','2','7', '\3','9','2','8', '\3','9','2','9',
'\3','9','3','0', '\3','9','3','1', '\3','9','3','2', '\3','9','3','3', '\3','9','3','4',
'\3','9','3','5', '\3','9','3','6', '\3','9','3','7', '\3','9','3','8', '\3','9','3','9',
'\3','9','4','0', '\3','9','4','1', '\3','9','4','2', '\3','9','4','3', '\3','9','4','4',
'\3','9','4','5', '\3','9','4','6', '\3','9','4','7', '\3','9','4','8', '\3','9','4','9',
'\3','9','5','0', '\3','9','5','1', '\3','9','5','2', '\3','9','5','3', '\3','9','5','4',
'\3','9','5','5', '\3','9','5','6', '\3','9','5','7', '\3','9','5','8', '\3','9','5','9',
'\3','9','6','0', '\3','9','6','1', '\3','9','6','2', '\3','9','6','3', '\3','9','6','4',
'\3','9','6','5', '\3','9','6','6', '\3','9','6','7', '\3','9','6','8', '\3','9','6','9',
'\3','9','7','0', '\3','9','7','1', '\3','9','7','2', '\3','9','7','3', '\3','9','7','4',
'\3','9','7','5', '\3','9','7','6', '\3','9','7','7', '\3','9','7','8', '\3','9','7','9',
'\3','9','8','0', '\3','9','8','1', '\3','9','8','2', '\3','9','8','3', '\3','9','8','4',
'\3','9','8','5', '\3','9','8','6', '\3','9','8','7', '\3','9','8','8', '\3','9','8','9',
'\3','9','9','0', '\3','9','9','1', '\3','9','9','2', '\3','9','9','3', '\3','9','9','4',
'\3','9','9','5', '\3','9','9','6', '\3','9','9','7', '\3','9','9','8', '\3','9','9','9', '\0'};
#endif
#if defined(DEC_DPD2BCD8) && DEC_DPD2BCD8==1 && !defined(DECDPD2BCD8)
#define DECDPD2BCD8
const uint8_t DPD2BCD8[4096]={
0,0,0,0, 0,0,1,1, 0,0,2,1, 0,0,3,1, 0,0,4,1, 0,0,5,1, 0,0,6,1, 0,0,7,1, 0,0,8,1,
0,0,9,1, 0,8,0,2, 0,8,1,2, 8,0,0,3, 8,0,1,3, 8,8,0,3, 8,8,1,3, 0,1,0,2, 0,1,1,2,
0,1,2,2, 0,1,3,2, 0,1,4,2, 0,1,5,2, 0,1,6,2, 0,1,7,2, 0,1,8,2, 0,1,9,2, 0,9,0,2,
0,9,1,2, 8,1,0,3, 8,1,1,3, 8,9,0,3, 8,9,1,3, 0,2,0,2, 0,2,1,2, 0,2,2,2, 0,2,3,2,
0,2,4,2, 0,2,5,2, 0,2,6,2, 0,2,7,2, 0,2,8,2, 0,2,9,2, 0,8,2,2, 0,8,3,2, 8,2,0,3,
8,2,1,3, 8,0,8,3, 8,0,9,3, 0,3,0,2, 0,3,1,2, 0,3,2,2, 0,3,3,2, 0,3,4,2, 0,3,5,2,
0,3,6,2, 0,3,7,2, 0,3,8,2, 0,3,9,2, 0,9,2,2, 0,9,3,2, 8,3,0,3, 8,3,1,3, 8,1,8,3,
8,1,9,3, 0,4,0,2, 0,4,1,2, 0,4,2,2, 0,4,3,2, 0,4,4,2, 0,4,5,2, 0,4,6,2, 0,4,7,2,
0,4,8,2, 0,4,9,2, 0,8,4,2, 0,8,5,2, 8,4,0,3, 8,4,1,3, 0,8,8,2, 0,8,9,2, 0,5,0,2,
0,5,1,2, 0,5,2,2, 0,5,3,2, 0,5,4,2, 0,5,5,2, 0,5,6,2, 0,5,7,2, 0,5,8,2, 0,5,9,2,
0,9,4,2, 0,9,5,2, 8,5,0,3, 8,5,1,3, 0,9,8,2, 0,9,9,2, 0,6,0,2, 0,6,1,2, 0,6,2,2,
0,6,3,2, 0,6,4,2, 0,6,5,2, 0,6,6,2, 0,6,7,2, 0,6,8,2, 0,6,9,2, 0,8,6,2, 0,8,7,2,
8,6,0,3, 8,6,1,3, 8,8,8,3, 8,8,9,3, 0,7,0,2, 0,7,1,2, 0,7,2,2, 0,7,3,2, 0,7,4,2,
0,7,5,2, 0,7,6,2, 0,7,7,2, 0,7,8,2, 0,7,9,2, 0,9,6,2, 0,9,7,2, 8,7,0,3, 8,7,1,3,
8,9,8,3, 8,9,9,3, 1,0,0,3, 1,0,1,3, 1,0,2,3, 1,0,3,3, 1,0,4,3, 1,0,5,3, 1,0,6,3,
1,0,7,3, 1,0,8,3, 1,0,9,3, 1,8,0,3, 1,8,1,3, 9,0,0,3, 9,0,1,3, 9,8,0,3, 9,8,1,3,
1,1,0,3, 1,1,1,3, 1,1,2,3, 1,1,3,3, 1,1,4,3, 1,1,5,3, 1,1,6,3, 1,1,7,3, 1,1,8,3,
1,1,9,3, 1,9,0,3, 1,9,1,3, 9,1,0,3, 9,1,1,3, 9,9,0,3, 9,9,1,3, 1,2,0,3, 1,2,1,3,
1,2,2,3, 1,2,3,3, 1,2,4,3, 1,2,5,3, 1,2,6,3, 1,2,7,3, 1,2,8,3, 1,2,9,3, 1,8,2,3,
1,8,3,3, 9,2,0,3, 9,2,1,3, 9,0,8,3, 9,0,9,3, 1,3,0,3, 1,3,1,3, 1,3,2,3, 1,3,3,3,
1,3,4,3, 1,3,5,3, 1,3,6,3, 1,3,7,3, 1,3,8,3, 1,3,9,3, 1,9,2,3, 1,9,3,3, 9,3,0,3,
9,3,1,3, 9,1,8,3, 9,1,9,3, 1,4,0,3, 1,4,1,3, 1,4,2,3, 1,4,3,3, 1,4,4,3, 1,4,5,3,
1,4,6,3, 1,4,7,3, 1,4,8,3, 1,4,9,3, 1,8,4,3, 1,8,5,3, 9,4,0,3, 9,4,1,3, 1,8,8,3,
1,8,9,3, 1,5,0,3, 1,5,1,3, 1,5,2,3, 1,5,3,3, 1,5,4,3, 1,5,5,3, 1,5,6,3, 1,5,7,3,
1,5,8,3, 1,5,9,3, 1,9,4,3, 1,9,5,3, 9,5,0,3, 9,5,1,3, 1,9,8,3, 1,9,9,3, 1,6,0,3,
1,6,1,3, 1,6,2,3, 1,6,3,3, 1,6,4,3, 1,6,5,3, 1,6,6,3, 1,6,7,3, 1,6,8,3, 1,6,9,3,
1,8,6,3, 1,8,7,3, 9,6,0,3, 9,6,1,3, 9,8,8,3, 9,8,9,3, 1,7,0,3, 1,7,1,3, 1,7,2,3,
1,7,3,3, 1,7,4,3, 1,7,5,3, 1,7,6,3, 1,7,7,3, 1,7,8,3, 1,7,9,3, 1,9,6,3, 1,9,7,3,
9,7,0,3, 9,7,1,3, 9,9,8,3, 9,9,9,3, 2,0,0,3, 2,0,1,3, 2,0,2,3, 2,0,3,3, 2,0,4,3,
2,0,5,3, 2,0,6,3, 2,0,7,3, 2,0,8,3, 2,0,9,3, 2,8,0,3, 2,8,1,3, 8,0,2,3, 8,0,3,3,
8,8,2,3, 8,8,3,3, 2,1,0,3, 2,1,1,3, 2,1,2,3, 2,1,3,3, 2,1,4,3, 2,1,5,3, 2,1,6,3,
2,1,7,3, 2,1,8,3, 2,1,9,3, 2,9,0,3, 2,9,1,3, 8,1,2,3, 8,1,3,3, 8,9,2,3, 8,9,3,3,
2,2,0,3, 2,2,1,3, 2,2,2,3, 2,2,3,3, 2,2,4,3, 2,2,5,3, 2,2,6,3, 2,2,7,3, 2,2,8,3,
2,2,9,3, 2,8,2,3, 2,8,3,3, 8,2,2,3, 8,2,3,3, 8,2,8,3, 8,2,9,3, 2,3,0,3, 2,3,1,3,
2,3,2,3, 2,3,3,3, 2,3,4,3, 2,3,5,3, 2,3,6,3, 2,3,7,3, 2,3,8,3, 2,3,9,3, 2,9,2,3,
2,9,3,3, 8,3,2,3, 8,3,3,3, 8,3,8,3, 8,3,9,3, 2,4,0,3, 2,4,1,3, 2,4,2,3, 2,4,3,3,
2,4,4,3, 2,4,5,3, 2,4,6,3, 2,4,7,3, 2,4,8,3, 2,4,9,3, 2,8,4,3, 2,8,5,3, 8,4,2,3,
8,4,3,3, 2,8,8,3, 2,8,9,3, 2,5,0,3, 2,5,1,3, 2,5,2,3, 2,5,3,3, 2,5,4,3, 2,5,5,3,
2,5,6,3, 2,5,7,3, 2,5,8,3, 2,5,9,3, 2,9,4,3, 2,9,5,3, 8,5,2,3, 8,5,3,3, 2,9,8,3,
2,9,9,3, 2,6,0,3, 2,6,1,3, 2,6,2,3, 2,6,3,3, 2,6,4,3, 2,6,5,3, 2,6,6,3, 2,6,7,3,
2,6,8,3, 2,6,9,3, 2,8,6,3, 2,8,7,3, 8,6,2,3, 8,6,3,3, 8,8,8,3, 8,8,9,3, 2,7,0,3,
2,7,1,3, 2,7,2,3, 2,7,3,3, 2,7,4,3, 2,7,5,3, 2,7,6,3, 2,7,7,3, 2,7,8,3, 2,7,9,3,
2,9,6,3, 2,9,7,3, 8,7,2,3, 8,7,3,3, 8,9,8,3, 8,9,9,3, 3,0,0,3, 3,0,1,3, 3,0,2,3,
3,0,3,3, 3,0,4,3, 3,0,5,3, 3,0,6,3, 3,0,7,3, 3,0,8,3, 3,0,9,3, 3,8,0,3, 3,8,1,3,
9,0,2,3, 9,0,3,3, 9,8,2,3, 9,8,3,3, 3,1,0,3, 3,1,1,3, 3,1,2,3, 3,1,3,3, 3,1,4,3,
3,1,5,3, 3,1,6,3, 3,1,7,3, 3,1,8,3, 3,1,9,3, 3,9,0,3, 3,9,1,3, 9,1,2,3, 9,1,3,3,
9,9,2,3, 9,9,3,3, 3,2,0,3, 3,2,1,3, 3,2,2,3, 3,2,3,3, 3,2,4,3, 3,2,5,3, 3,2,6,3,
3,2,7,3, 3,2,8,3, 3,2,9,3, 3,8,2,3, 3,8,3,3, 9,2,2,3, 9,2,3,3, 9,2,8,3, 9,2,9,3,
3,3,0,3, 3,3,1,3, 3,3,2,3, 3,3,3,3, 3,3,4,3, 3,3,5,3, 3,3,6,3, 3,3,7,3, 3,3,8,3,
3,3,9,3, 3,9,2,3, 3,9,3,3, 9,3,2,3, 9,3,3,3, 9,3,8,3, 9,3,9,3, 3,4,0,3, 3,4,1,3,
3,4,2,3, 3,4,3,3, 3,4,4,3, 3,4,5,3, 3,4,6,3, 3,4,7,3, 3,4,8,3, 3,4,9,3, 3,8,4,3,
3,8,5,3, 9,4,2,3, 9,4,3,3, 3,8,8,3, 3,8,9,3, 3,5,0,3, 3,5,1,3, 3,5,2,3, 3,5,3,3,
3,5,4,3, 3,5,5,3, 3,5,6,3, 3,5,7,3, 3,5,8,3, 3,5,9,3, 3,9,4,3, 3,9,5,3, 9,5,2,3,
9,5,3,3, 3,9,8,3, 3,9,9,3, 3,6,0,3, 3,6,1,3, 3,6,2,3, 3,6,3,3, 3,6,4,3, 3,6,5,3,
3,6,6,3, 3,6,7,3, 3,6,8,3, 3,6,9,3, 3,8,6,3, 3,8,7,3, 9,6,2,3, 9,6,3,3, 9,8,8,3,
9,8,9,3, 3,7,0,3, 3,7,1,3, 3,7,2,3, 3,7,3,3, 3,7,4,3, 3,7,5,3, 3,7,6,3, 3,7,7,3,
3,7,8,3, 3,7,9,3, 3,9,6,3, 3,9,7,3, 9,7,2,3, 9,7,3,3, 9,9,8,3, 9,9,9,3, 4,0,0,3,
4,0,1,3, 4,0,2,3, 4,0,3,3, 4,0,4,3, 4,0,5,3, 4,0,6,3, 4,0,7,3, 4,0,8,3, 4,0,9,3,
4,8,0,3, 4,8,1,3, 8,0,4,3, 8,0,5,3, 8,8,4,3, 8,8,5,3, 4,1,0,3, 4,1,1,3, 4,1,2,3,
4,1,3,3, 4,1,4,3, 4,1,5,3, 4,1,6,3, 4,1,7,3, 4,1,8,3, 4,1,9,3, 4,9,0,3, 4,9,1,3,
8,1,4,3, 8,1,5,3, 8,9,4,3, 8,9,5,3, 4,2,0,3, 4,2,1,3, 4,2,2,3, 4,2,3,3, 4,2,4,3,
4,2,5,3, 4,2,6,3, 4,2,7,3, 4,2,8,3, 4,2,9,3, 4,8,2,3, 4,8,3,3, 8,2,4,3, 8,2,5,3,
8,4,8,3, 8,4,9,3, 4,3,0,3, 4,3,1,3, 4,3,2,3, 4,3,3,3, 4,3,4,3, 4,3,5,3, 4,3,6,3,
4,3,7,3, 4,3,8,3, 4,3,9,3, 4,9,2,3, 4,9,3,3, 8,3,4,3, 8,3,5,3, 8,5,8,3, 8,5,9,3,
4,4,0,3, 4,4,1,3, 4,4,2,3, 4,4,3,3, 4,4,4,3, 4,4,5,3, 4,4,6,3, 4,4,7,3, 4,4,8,3,
4,4,9,3, 4,8,4,3, 4,8,5,3, 8,4,4,3, 8,4,5,3, 4,8,8,3, 4,8,9,3, 4,5,0,3, 4,5,1,3,
4,5,2,3, 4,5,3,3, 4,5,4,3, 4,5,5,3, 4,5,6,3, 4,5,7,3, 4,5,8,3, 4,5,9,3, 4,9,4,3,
4,9,5,3, 8,5,4,3, 8,5,5,3, 4,9,8,3, 4,9,9,3, 4,6,0,3, 4,6,1,3, 4,6,2,3, 4,6,3,3,
4,6,4,3, 4,6,5,3, 4,6,6,3, 4,6,7,3, 4,6,8,3, 4,6,9,3, 4,8,6,3, 4,8,7,3, 8,6,4,3,
8,6,5,3, 8,8,8,3, 8,8,9,3, 4,7,0,3, 4,7,1,3, 4,7,2,3, 4,7,3,3, 4,7,4,3, 4,7,5,3,
4,7,6,3, 4,7,7,3, 4,7,8,3, 4,7,9,3, 4,9,6,3, 4,9,7,3, 8,7,4,3, 8,7,5,3, 8,9,8,3,
8,9,9,3, 5,0,0,3, 5,0,1,3, 5,0,2,3, 5,0,3,3, 5,0,4,3, 5,0,5,3, 5,0,6,3, 5,0,7,3,
5,0,8,3, 5,0,9,3, 5,8,0,3, 5,8,1,3, 9,0,4,3, 9,0,5,3, 9,8,4,3, 9,8,5,3, 5,1,0,3,
5,1,1,3, 5,1,2,3, 5,1,3,3, 5,1,4,3, 5,1,5,3, 5,1,6,3, 5,1,7,3, 5,1,8,3, 5,1,9,3,
5,9,0,3, 5,9,1,3, 9,1,4,3, 9,1,5,3, 9,9,4,3, 9,9,5,3, 5,2,0,3, 5,2,1,3, 5,2,2,3,
5,2,3,3, 5,2,4,3, 5,2,5,3, 5,2,6,3, 5,2,7,3, 5,2,8,3, 5,2,9,3, 5,8,2,3, 5,8,3,3,
9,2,4,3, 9,2,5,3, 9,4,8,3, 9,4,9,3, 5,3,0,3, 5,3,1,3, 5,3,2,3, 5,3,3,3, 5,3,4,3,
5,3,5,3, 5,3,6,3, 5,3,7,3, 5,3,8,3, 5,3,9,3, 5,9,2,3, 5,9,3,3, 9,3,4,3, 9,3,5,3,
9,5,8,3, 9,5,9,3, 5,4,0,3, 5,4,1,3, 5,4,2,3, 5,4,3,3, 5,4,4,3, 5,4,5,3, 5,4,6,3,
5,4,7,3, 5,4,8,3, 5,4,9,3, 5,8,4,3, 5,8,5,3, 9,4,4,3, 9,4,5,3, 5,8,8,3, 5,8,9,3,
5,5,0,3, 5,5,1,3, 5,5,2,3, 5,5,3,3, 5,5,4,3, 5,5,5,3, 5,5,6,3, 5,5,7,3, 5,5,8,3,
5,5,9,3, 5,9,4,3, 5,9,5,3, 9,5,4,3, 9,5,5,3, 5,9,8,3, 5,9,9,3, 5,6,0,3, 5,6,1,3,
5,6,2,3, 5,6,3,3, 5,6,4,3, 5,6,5,3, 5,6,6,3, 5,6,7,3, 5,6,8,3, 5,6,9,3, 5,8,6,3,
5,8,7,3, 9,6,4,3, 9,6,5,3, 9,8,8,3, 9,8,9,3, 5,7,0,3, 5,7,1,3, 5,7,2,3, 5,7,3,3,
5,7,4,3, 5,7,5,3, 5,7,6,3, 5,7,7,3, 5,7,8,3, 5,7,9,3, 5,9,6,3, 5,9,7,3, 9,7,4,3,
9,7,5,3, 9,9,8,3, 9,9,9,3, 6,0,0,3, 6,0,1,3, 6,0,2,3, 6,0,3,3, 6,0,4,3, 6,0,5,3,
6,0,6,3, 6,0,7,3, 6,0,8,3, 6,0,9,3, 6,8,0,3, 6,8,1,3, 8,0,6,3, 8,0,7,3, 8,8,6,3,
8,8,7,3, 6,1,0,3, 6,1,1,3, 6,1,2,3, 6,1,3,3, 6,1,4,3, 6,1,5,3, 6,1,6,3, 6,1,7,3,
6,1,8,3, 6,1,9,3, 6,9,0,3, 6,9,1,3, 8,1,6,3, 8,1,7,3, 8,9,6,3, 8,9,7,3, 6,2,0,3,
6,2,1,3, 6,2,2,3, 6,2,3,3, 6,2,4,3, 6,2,5,3, 6,2,6,3, 6,2,7,3, 6,2,8,3, 6,2,9,3,
6,8,2,3, 6,8,3,3, 8,2,6,3, 8,2,7,3, 8,6,8,3, 8,6,9,3, 6,3,0,3, 6,3,1,3, 6,3,2,3,
6,3,3,3, 6,3,4,3, 6,3,5,3, 6,3,6,3, 6,3,7,3, 6,3,8,3, 6,3,9,3, 6,9,2,3, 6,9,3,3,
8,3,6,3, 8,3,7,3, 8,7,8,3, 8,7,9,3, 6,4,0,3, 6,4,1,3, 6,4,2,3, 6,4,3,3, 6,4,4,3,
6,4,5,3, 6,4,6,3, 6,4,7,3, 6,4,8,3, 6,4,9,3, 6,8,4,3, 6,8,5,3, 8,4,6,3, 8,4,7,3,
6,8,8,3, 6,8,9,3, 6,5,0,3, 6,5,1,3, 6,5,2,3, 6,5,3,3, 6,5,4,3, 6,5,5,3, 6,5,6,3,
6,5,7,3, 6,5,8,3, 6,5,9,3, 6,9,4,3, 6,9,5,3, 8,5,6,3, 8,5,7,3, 6,9,8,3, 6,9,9,3,
6,6,0,3, 6,6,1,3, 6,6,2,3, 6,6,3,3, 6,6,4,3, 6,6,5,3, 6,6,6,3, 6,6,7,3, 6,6,8,3,
6,6,9,3, 6,8,6,3, 6,8,7,3, 8,6,6,3, 8,6,7,3, 8,8,8,3, 8,8,9,3, 6,7,0,3, 6,7,1,3,
6,7,2,3, 6,7,3,3, 6,7,4,3, 6,7,5,3, 6,7,6,3, 6,7,7,3, 6,7,8,3, 6,7,9,3, 6,9,6,3,
6,9,7,3, 8,7,6,3, 8,7,7,3, 8,9,8,3, 8,9,9,3, 7,0,0,3, 7,0,1,3, 7,0,2,3, 7,0,3,3,
7,0,4,3, 7,0,5,3, 7,0,6,3, 7,0,7,3, 7,0,8,3, 7,0,9,3, 7,8,0,3, 7,8,1,3, 9,0,6,3,
9,0,7,3, 9,8,6,3, 9,8,7,3, 7,1,0,3, 7,1,1,3, 7,1,2,3, 7,1,3,3, 7,1,4,3, 7,1,5,3,
7,1,6,3, 7,1,7,3, 7,1,8,3, 7,1,9,3, 7,9,0,3, 7,9,1,3, 9,1,6,3, 9,1,7,3, 9,9,6,3,
9,9,7,3, 7,2,0,3, 7,2,1,3, 7,2,2,3, 7,2,3,3, 7,2,4,3, 7,2,5,3, 7,2,6,3, 7,2,7,3,
7,2,8,3, 7,2,9,3, 7,8,2,3, 7,8,3,3, 9,2,6,3, 9,2,7,3, 9,6,8,3, 9,6,9,3, 7,3,0,3,
7,3,1,3, 7,3,2,3, 7,3,3,3, 7,3,4,3, 7,3,5,3, 7,3,6,3, 7,3,7,3, 7,3,8,3, 7,3,9,3,
7,9,2,3, 7,9,3,3, 9,3,6,3, 9,3,7,3, 9,7,8,3, 9,7,9,3, 7,4,0,3, 7,4,1,3, 7,4,2,3,
7,4,3,3, 7,4,4,3, 7,4,5,3, 7,4,6,3, 7,4,7,3, 7,4,8,3, 7,4,9,3, 7,8,4,3, 7,8,5,3,
9,4,6,3, 9,4,7,3, 7,8,8,3, 7,8,9,3, 7,5,0,3, 7,5,1,3, 7,5,2,3, 7,5,3,3, 7,5,4,3,
7,5,5,3, 7,5,6,3, 7,5,7,3, 7,5,8,3, 7,5,9,3, 7,9,4,3, 7,9,5,3, 9,5,6,3, 9,5,7,3,
7,9,8,3, 7,9,9,3, 7,6,0,3, 7,6,1,3, 7,6,2,3, 7,6,3,3, 7,6,4,3, 7,6,5,3, 7,6,6,3,
7,6,7,3, 7,6,8,3, 7,6,9,3, 7,8,6,3, 7,8,7,3, 9,6,6,3, 9,6,7,3, 9,8,8,3, 9,8,9,3,
7,7,0,3, 7,7,1,3, 7,7,2,3, 7,7,3,3, 7,7,4,3, 7,7,5,3, 7,7,6,3, 7,7,7,3, 7,7,8,3,
7,7,9,3, 7,9,6,3, 7,9,7,3, 9,7,6,3, 9,7,7,3, 9,9,8,3, 9,9,9,3};
#endif
#if defined(DEC_BIN2BCD8) && DEC_BIN2BCD8==1 && !defined(DECBIN2BCD8)
#define DECBIN2BCD8
const uint8_t BIN2BCD8[4000]={
0,0,0,0, 0,0,1,1, 0,0,2,1, 0,0,3,1, 0,0,4,1, 0,0,5,1, 0,0,6,1, 0,0,7,1, 0,0,8,1,
0,0,9,1, 0,1,0,2, 0,1,1,2, 0,1,2,2, 0,1,3,2, 0,1,4,2, 0,1,5,2, 0,1,6,2, 0,1,7,2,
0,1,8,2, 0,1,9,2, 0,2,0,2, 0,2,1,2, 0,2,2,2, 0,2,3,2, 0,2,4,2, 0,2,5,2, 0,2,6,2,
0,2,7,2, 0,2,8,2, 0,2,9,2, 0,3,0,2, 0,3,1,2, 0,3,2,2, 0,3,3,2, 0,3,4,2, 0,3,5,2,
0,3,6,2, 0,3,7,2, 0,3,8,2, 0,3,9,2, 0,4,0,2, 0,4,1,2, 0,4,2,2, 0,4,3,2, 0,4,4,2,
0,4,5,2, 0,4,6,2, 0,4,7,2, 0,4,8,2, 0,4,9,2, 0,5,0,2, 0,5,1,2, 0,5,2,2, 0,5,3,2,
0,5,4,2, 0,5,5,2, 0,5,6,2, 0,5,7,2, 0,5,8,2, 0,5,9,2, 0,6,0,2, 0,6,1,2, 0,6,2,2,
0,6,3,2, 0,6,4,2, 0,6,5,2, 0,6,6,2, 0,6,7,2, 0,6,8,2, 0,6,9,2, 0,7,0,2, 0,7,1,2,
0,7,2,2, 0,7,3,2, 0,7,4,2, 0,7,5,2, 0,7,6,2, 0,7,7,2, 0,7,8,2, 0,7,9,2, 0,8,0,2,
0,8,1,2, 0,8,2,2, 0,8,3,2, 0,8,4,2, 0,8,5,2, 0,8,6,2, 0,8,7,2, 0,8,8,2, 0,8,9,2,
0,9,0,2, 0,9,1,2, 0,9,2,2, 0,9,3,2, 0,9,4,2, 0,9,5,2, 0,9,6,2, 0,9,7,2, 0,9,8,2,
0,9,9,2, 1,0,0,3, 1,0,1,3, 1,0,2,3, 1,0,3,3, 1,0,4,3, 1,0,5,3, 1,0,6,3, 1,0,7,3,
1,0,8,3, 1,0,9,3, 1,1,0,3, 1,1,1,3, 1,1,2,3, 1,1,3,3, 1,1,4,3, 1,1,5,3, 1,1,6,3,
1,1,7,3, 1,1,8,3, 1,1,9,3, 1,2,0,3, 1,2,1,3, 1,2,2,3, 1,2,3,3, 1,2,4,3, 1,2,5,3,
1,2,6,3, 1,2,7,3, 1,2,8,3, 1,2,9,3, 1,3,0,3, 1,3,1,3, 1,3,2,3, 1,3,3,3, 1,3,4,3,
1,3,5,3, 1,3,6,3, 1,3,7,3, 1,3,8,3, 1,3,9,3, 1,4,0,3, 1,4,1,3, 1,4,2,3, 1,4,3,3,
1,4,4,3, 1,4,5,3, 1,4,6,3, 1,4,7,3, 1,4,8,3, 1,4,9,3, 1,5,0,3, 1,5,1,3, 1,5,2,3,
1,5,3,3, 1,5,4,3, 1,5,5,3, 1,5,6,3, 1,5,7,3, 1,5,8,3, 1,5,9,3, 1,6,0,3, 1,6,1,3,
1,6,2,3, 1,6,3,3, 1,6,4,3, 1,6,5,3, 1,6,6,3, 1,6,7,3, 1,6,8,3, 1,6,9,3, 1,7,0,3,
1,7,1,3, 1,7,2,3, 1,7,3,3, 1,7,4,3, 1,7,5,3, 1,7,6,3, 1,7,7,3, 1,7,8,3, 1,7,9,3,
1,8,0,3, 1,8,1,3, 1,8,2,3, 1,8,3,3, 1,8,4,3, 1,8,5,3, 1,8,6,3, 1,8,7,3, 1,8,8,3,
1,8,9,3, 1,9,0,3, 1,9,1,3, 1,9,2,3, 1,9,3,3, 1,9,4,3, 1,9,5,3, 1,9,6,3, 1,9,7,3,
1,9,8,3, 1,9,9,3, 2,0,0,3, 2,0,1,3, 2,0,2,3, 2,0,3,3, 2,0,4,3, 2,0,5,3, 2,0,6,3,
2,0,7,3, 2,0,8,3, 2,0,9,3, 2,1,0,3, 2,1,1,3, 2,1,2,3, 2,1,3,3, 2,1,4,3, 2,1,5,3,
2,1,6,3, 2,1,7,3, 2,1,8,3, 2,1,9,3, 2,2,0,3, 2,2,1,3, 2,2,2,3, 2,2,3,3, 2,2,4,3,
2,2,5,3, 2,2,6,3, 2,2,7,3, 2,2,8,3, 2,2,9,3, 2,3,0,3, 2,3,1,3, 2,3,2,3, 2,3,3,3,
2,3,4,3, 2,3,5,3, 2,3,6,3, 2,3,7,3, 2,3,8,3, 2,3,9,3, 2,4,0,3, 2,4,1,3, 2,4,2,3,
2,4,3,3, 2,4,4,3, 2,4,5,3, 2,4,6,3, 2,4,7,3, 2,4,8,3, 2,4,9,3, 2,5,0,3, 2,5,1,3,
2,5,2,3, 2,5,3,3, 2,5,4,3, 2,5,5,3, 2,5,6,3, 2,5,7,3, 2,5,8,3, 2,5,9,3, 2,6,0,3,
2,6,1,3, 2,6,2,3, 2,6,3,3, 2,6,4,3, 2,6,5,3, 2,6,6,3, 2,6,7,3, 2,6,8,3, 2,6,9,3,
2,7,0,3, 2,7,1,3, 2,7,2,3, 2,7,3,3, 2,7,4,3, 2,7,5,3, 2,7,6,3, 2,7,7,3, 2,7,8,3,
2,7,9,3, 2,8,0,3, 2,8,1,3, 2,8,2,3, 2,8,3,3, 2,8,4,3, 2,8,5,3, 2,8,6,3, 2,8,7,3,
2,8,8,3, 2,8,9,3, 2,9,0,3, 2,9,1,3, 2,9,2,3, 2,9,3,3, 2,9,4,3, 2,9,5,3, 2,9,6,3,
2,9,7,3, 2,9,8,3, 2,9,9,3, 3,0,0,3, 3,0,1,3, 3,0,2,3, 3,0,3,3, 3,0,4,3, 3,0,5,3,
3,0,6,3, 3,0,7,3, 3,0,8,3, 3,0,9,3, 3,1,0,3, 3,1,1,3, 3,1,2,3, 3,1,3,3, 3,1,4,3,
3,1,5,3, 3,1,6,3, 3,1,7,3, 3,1,8,3, 3,1,9,3, 3,2,0,3, 3,2,1,3, 3,2,2,3, 3,2,3,3,
3,2,4,3, 3,2,5,3, 3,2,6,3, 3,2,7,3, 3,2,8,3, 3,2,9,3, 3,3,0,3, 3,3,1,3, 3,3,2,3,
3,3,3,3, 3,3,4,3, 3,3,5,3, 3,3,6,3, 3,3,7,3, 3,3,8,3, 3,3,9,3, 3,4,0,3, 3,4,1,3,
3,4,2,3, 3,4,3,3, 3,4,4,3, 3,4,5,3, 3,4,6,3, 3,4,7,3, 3,4,8,3, 3,4,9,3, 3,5,0,3,
3,5,1,3, 3,5,2,3, 3,5,3,3, 3,5,4,3, 3,5,5,3, 3,5,6,3, 3,5,7,3, 3,5,8,3, 3,5,9,3,
3,6,0,3, 3,6,1,3, 3,6,2,3, 3,6,3,3, 3,6,4,3, 3,6,5,3, 3,6,6,3, 3,6,7,3, 3,6,8,3,
3,6,9,3, 3,7,0,3, 3,7,1,3, 3,7,2,3, 3,7,3,3, 3,7,4,3, 3,7,5,3, 3,7,6,3, 3,7,7,3,
3,7,8,3, 3,7,9,3, 3,8,0,3, 3,8,1,3, 3,8,2,3, 3,8,3,3, 3,8,4,3, 3,8,5,3, 3,8,6,3,
3,8,7,3, 3,8,8,3, 3,8,9,3, 3,9,0,3, 3,9,1,3, 3,9,2,3, 3,9,3,3, 3,9,4,3, 3,9,5,3,
3,9,6,3, 3,9,7,3, 3,9,8,3, 3,9,9,3, 4,0,0,3, 4,0,1,3, 4,0,2,3, 4,0,3,3, 4,0,4,3,
4,0,5,3, 4,0,6,3, 4,0,7,3, 4,0,8,3, 4,0,9,3, 4,1,0,3, 4,1,1,3, 4,1,2,3, 4,1,3,3,
4,1,4,3, 4,1,5,3, 4,1,6,3, 4,1,7,3, 4,1,8,3, 4,1,9,3, 4,2,0,3, 4,2,1,3, 4,2,2,3,
4,2,3,3, 4,2,4,3, 4,2,5,3, 4,2,6,3, 4,2,7,3, 4,2,8,3, 4,2,9,3, 4,3,0,3, 4,3,1,3,
4,3,2,3, 4,3,3,3, 4,3,4,3, 4,3,5,3, 4,3,6,3, 4,3,7,3, 4,3,8,3, 4,3,9,3, 4,4,0,3,
4,4,1,3, 4,4,2,3, 4,4,3,3, 4,4,4,3, 4,4,5,3, 4,4,6,3, 4,4,7,3, 4,4,8,3, 4,4,9,3,
4,5,0,3, 4,5,1,3, 4,5,2,3, 4,5,3,3, 4,5,4,3, 4,5,5,3, 4,5,6,3, 4,5,7,3, 4,5,8,3,
4,5,9,3, 4,6,0,3, 4,6,1,3, 4,6,2,3, 4,6,3,3, 4,6,4,3, 4,6,5,3, 4,6,6,3, 4,6,7,3,
4,6,8,3, 4,6,9,3, 4,7,0,3, 4,7,1,3, 4,7,2,3, 4,7,3,3, 4,7,4,3, 4,7,5,3, 4,7,6,3,
4,7,7,3, 4,7,8,3, 4,7,9,3, 4,8,0,3, 4,8,1,3, 4,8,2,3, 4,8,3,3, 4,8,4,3, 4,8,5,3,
4,8,6,3, 4,8,7,3, 4,8,8,3, 4,8,9,3, 4,9,0,3, 4,9,1,3, 4,9,2,3, 4,9,3,3, 4,9,4,3,
4,9,5,3, 4,9,6,3, 4,9,7,3, 4,9,8,3, 4,9,9,3, 5,0,0,3, 5,0,1,3, 5,0,2,3, 5,0,3,3,
5,0,4,3, 5,0,5,3, 5,0,6,3, 5,0,7,3, 5,0,8,3, 5,0,9,3, 5,1,0,3, 5,1,1,3, 5,1,2,3,
5,1,3,3, 5,1,4,3, 5,1,5,3, 5,1,6,3, 5,1,7,3, 5,1,8,3, 5,1,9,3, 5,2,0,3, 5,2,1,3,
5,2,2,3, 5,2,3,3, 5,2,4,3, 5,2,5,3, 5,2,6,3, 5,2,7,3, 5,2,8,3, 5,2,9,3, 5,3,0,3,
5,3,1,3, 5,3,2,3, 5,3,3,3, 5,3,4,3, 5,3,5,3, 5,3,6,3, 5,3,7,3, 5,3,8,3, 5,3,9,3,
5,4,0,3, 5,4,1,3, 5,4,2,3, 5,4,3,3, 5,4,4,3, 5,4,5,3, 5,4,6,3, 5,4,7,3, 5,4,8,3,
5,4,9,3, 5,5,0,3, 5,5,1,3, 5,5,2,3, 5,5,3,3, 5,5,4,3, 5,5,5,3, 5,5,6,3, 5,5,7,3,
5,5,8,3, 5,5,9,3, 5,6,0,3, 5,6,1,3, 5,6,2,3, 5,6,3,3, 5,6,4,3, 5,6,5,3, 5,6,6,3,
5,6,7,3, 5,6,8,3, 5,6,9,3, 5,7,0,3, 5,7,1,3, 5,7,2,3, 5,7,3,3, 5,7,4,3, 5,7,5,3,
5,7,6,3, 5,7,7,3, 5,7,8,3, 5,7,9,3, 5,8,0,3, 5,8,1,3, 5,8,2,3, 5,8,3,3, 5,8,4,3,
5,8,5,3, 5,8,6,3, 5,8,7,3, 5,8,8,3, 5,8,9,3, 5,9,0,3, 5,9,1,3, 5,9,2,3, 5,9,3,3,
5,9,4,3, 5,9,5,3, 5,9,6,3, 5,9,7,3, 5,9,8,3, 5,9,9,3, 6,0,0,3, 6,0,1,3, 6,0,2,3,
6,0,3,3, 6,0,4,3, 6,0,5,3, 6,0,6,3, 6,0,7,3, 6,0,8,3, 6,0,9,3, 6,1,0,3, 6,1,1,3,
6,1,2,3, 6,1,3,3, 6,1,4,3, 6,1,5,3, 6,1,6,3, 6,1,7,3, 6,1,8,3, 6,1,9,3, 6,2,0,3,
6,2,1,3, 6,2,2,3, 6,2,3,3, 6,2,4,3, 6,2,5,3, 6,2,6,3, 6,2,7,3, 6,2,8,3, 6,2,9,3,
6,3,0,3, 6,3,1,3, 6,3,2,3, 6,3,3,3, 6,3,4,3, 6,3,5,3, 6,3,6,3, 6,3,7,3, 6,3,8,3,
6,3,9,3, 6,4,0,3, 6,4,1,3, 6,4,2,3, 6,4,3,3, 6,4,4,3, 6,4,5,3, 6,4,6,3, 6,4,7,3,
6,4,8,3, 6,4,9,3, 6,5,0,3, 6,5,1,3, 6,5,2,3, 6,5,3,3, 6,5,4,3, 6,5,5,3, 6,5,6,3,
6,5,7,3, 6,5,8,3, 6,5,9,3, 6,6,0,3, 6,6,1,3, 6,6,2,3, 6,6,3,3, 6,6,4,3, 6,6,5,3,
6,6,6,3, 6,6,7,3, 6,6,8,3, 6,6,9,3, 6,7,0,3, 6,7,1,3, 6,7,2,3, 6,7,3,3, 6,7,4,3,
6,7,5,3, 6,7,6,3, 6,7,7,3, 6,7,8,3, 6,7,9,3, 6,8,0,3, 6,8,1,3, 6,8,2,3, 6,8,3,3,
6,8,4,3, 6,8,5,3, 6,8,6,3, 6,8,7,3, 6,8,8,3, 6,8,9,3, 6,9,0,3, 6,9,1,3, 6,9,2,3,
6,9,3,3, 6,9,4,3, 6,9,5,3, 6,9,6,3, 6,9,7,3, 6,9,8,3, 6,9,9,3, 7,0,0,3, 7,0,1,3,
7,0,2,3, 7,0,3,3, 7,0,4,3, 7,0,5,3, 7,0,6,3, 7,0,7,3, 7,0,8,3, 7,0,9,3, 7,1,0,3,
7,1,1,3, 7,1,2,3, 7,1,3,3, 7,1,4,3, 7,1,5,3, 7,1,6,3, 7,1,7,3, 7,1,8,3, 7,1,9,3,
7,2,0,3, 7,2,1,3, 7,2,2,3, 7,2,3,3, 7,2,4,3, 7,2,5,3, 7,2,6,3, 7,2,7,3, 7,2,8,3,
7,2,9,3, 7,3,0,3, 7,3,1,3, 7,3,2,3, 7,3,3,3, 7,3,4,3, 7,3,5,3, 7,3,6,3, 7,3,7,3,
7,3,8,3, 7,3,9,3, 7,4,0,3, 7,4,1,3, 7,4,2,3, 7,4,3,3, 7,4,4,3, 7,4,5,3, 7,4,6,3,
7,4,7,3, 7,4,8,3, 7,4,9,3, 7,5,0,3, 7,5,1,3, 7,5,2,3, 7,5,3,3, 7,5,4,3, 7,5,5,3,
7,5,6,3, 7,5,7,3, 7,5,8,3, 7,5,9,3, 7,6,0,3, 7,6,1,3, 7,6,2,3, 7,6,3,3, 7,6,4,3,
7,6,5,3, 7,6,6,3, 7,6,7,3, 7,6,8,3, 7,6,9,3, 7,7,0,3, 7,7,1,3, 7,7,2,3, 7,7,3,3,
7,7,4,3, 7,7,5,3, 7,7,6,3, 7,7,7,3, 7,7,8,3, 7,7,9,3, 7,8,0,3, 7,8,1,3, 7,8,2,3,
7,8,3,3, 7,8,4,3, 7,8,5,3, 7,8,6,3, 7,8,7,3, 7,8,8,3, 7,8,9,3, 7,9,0,3, 7,9,1,3,
7,9,2,3, 7,9,3,3, 7,9,4,3, 7,9,5,3, 7,9,6,3, 7,9,7,3, 7,9,8,3, 7,9,9,3, 8,0,0,3,
8,0,1,3, 8,0,2,3, 8,0,3,3, 8,0,4,3, 8,0,5,3, 8,0,6,3, 8,0,7,3, 8,0,8,3, 8,0,9,3,
8,1,0,3, 8,1,1,3, 8,1,2,3, 8,1,3,3, 8,1,4,3, 8,1,5,3, 8,1,6,3, 8,1,7,3, 8,1,8,3,
8,1,9,3, 8,2,0,3, 8,2,1,3, 8,2,2,3, 8,2,3,3, 8,2,4,3, 8,2,5,3, 8,2,6,3, 8,2,7,3,
8,2,8,3, 8,2,9,3, 8,3,0,3, 8,3,1,3, 8,3,2,3, 8,3,3,3, 8,3,4,3, 8,3,5,3, 8,3,6,3,
8,3,7,3, 8,3,8,3, 8,3,9,3, 8,4,0,3, 8,4,1,3, 8,4,2,3, 8,4,3,3, 8,4,4,3, 8,4,5,3,
8,4,6,3, 8,4,7,3, 8,4,8,3, 8,4,9,3, 8,5,0,3, 8,5,1,3, 8,5,2,3, 8,5,3,3, 8,5,4,3,
8,5,5,3, 8,5,6,3, 8,5,7,3, 8,5,8,3, 8,5,9,3, 8,6,0,3, 8,6,1,3, 8,6,2,3, 8,6,3,3,
8,6,4,3, 8,6,5,3, 8,6,6,3, 8,6,7,3, 8,6,8,3, 8,6,9,3, 8,7,0,3, 8,7,1,3, 8,7,2,3,
8,7,3,3, 8,7,4,3, 8,7,5,3, 8,7,6,3, 8,7,7,3, 8,7,8,3, 8,7,9,3, 8,8,0,3, 8,8,1,3,
8,8,2,3, 8,8,3,3, 8,8,4,3, 8,8,5,3, 8,8,6,3, 8,8,7,3, 8,8,8,3, 8,8,9,3, 8,9,0,3,
8,9,1,3, 8,9,2,3, 8,9,3,3, 8,9,4,3, 8,9,5,3, 8,9,6,3, 8,9,7,3, 8,9,8,3, 8,9,9,3,
9,0,0,3, 9,0,1,3, 9,0,2,3, 9,0,3,3, 9,0,4,3, 9,0,5,3, 9,0,6,3, 9,0,7,3, 9,0,8,3,
9,0,9,3, 9,1,0,3, 9,1,1,3, 9,1,2,3, 9,1,3,3, 9,1,4,3, 9,1,5,3, 9,1,6,3, 9,1,7,3,
9,1,8,3, 9,1,9,3, 9,2,0,3, 9,2,1,3, 9,2,2,3, 9,2,3,3, 9,2,4,3, 9,2,5,3, 9,2,6,3,
9,2,7,3, 9,2,8,3, 9,2,9,3, 9,3,0,3, 9,3,1,3, 9,3,2,3, 9,3,3,3, 9,3,4,3, 9,3,5,3,
9,3,6,3, 9,3,7,3, 9,3,8,3, 9,3,9,3, 9,4,0,3, 9,4,1,3, 9,4,2,3, 9,4,3,3, 9,4,4,3,
9,4,5,3, 9,4,6,3, 9,4,7,3, 9,4,8,3, 9,4,9,3, 9,5,0,3, 9,5,1,3, 9,5,2,3, 9,5,3,3,
9,5,4,3, 9,5,5,3, 9,5,6,3, 9,5,7,3, 9,5,8,3, 9,5,9,3, 9,6,0,3, 9,6,1,3, 9,6,2,3,
9,6,3,3, 9,6,4,3, 9,6,5,3, 9,6,6,3, 9,6,7,3, 9,6,8,3, 9,6,9,3, 9,7,0,3, 9,7,1,3,
9,7,2,3, 9,7,3,3, 9,7,4,3, 9,7,5,3, 9,7,6,3, 9,7,7,3, 9,7,8,3, 9,7,9,3, 9,8,0,3,
9,8,1,3, 9,8,2,3, 9,8,3,3, 9,8,4,3, 9,8,5,3, 9,8,6,3, 9,8,7,3, 9,8,8,3, 9,8,9,3,
9,9,0,3, 9,9,1,3, 9,9,2,3, 9,9,3,3, 9,9,4,3, 9,9,5,3, 9,9,6,3, 9,9,7,3, 9,9,8,3,
9,9,9,3};
#endif
/* decDouble module for the decNumber C Library.
Copyright (C) 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
This file is part of GCC.
GCC 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 2, or (at your option) any later
version.
In addition to the permissions in the GNU General Public License,
the Free Software Foundation gives you unlimited permission to link
the compiled version of this file into combinations with other
programs, and to distribute those combinations without any
restriction coming from the use of this file. (The General Public
License restrictions do apply in other respects; for example, they
cover modification of the file, and distribution when not linked
into a combine executable.)
GCC 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.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
/* ------------------------------------------------------------------ */
/* decDouble.c -- decDouble operations module */
/* ------------------------------------------------------------------ */
/* This module comprises decDouble operations (including conversions) */
/* ------------------------------------------------------------------ */
#include "decContext.h" /* public includes */
#include "decDouble.h" /* .. */
/* Constant mappings for shared code */
#define DECPMAX DECDOUBLE_Pmax
#define DECEMIN DECDOUBLE_Emin
#define DECEMAX DECDOUBLE_Emax
#define DECEMAXD DECDOUBLE_EmaxD
#define DECBYTES DECDOUBLE_Bytes
#define DECSTRING DECDOUBLE_String
#define DECECONL DECDOUBLE_EconL
#define DECBIAS DECDOUBLE_Bias
#define DECLETS DECDOUBLE_Declets
#define DECQTINY (-DECDOUBLE_Bias)
/* parameters of next-wider format */
#define DECWBYTES DECQUAD_Bytes
#define DECWPMAX DECQUAD_Pmax
#define DECWECONL DECQUAD_EconL
#define DECWBIAS DECQUAD_Bias
/* Type and function mappings for shared code */
#define decFloat decDouble /* Type name */
#define decFloatWider decQuad /* Type name */
/* Utilities and conversions (binary results, extractors, etc.) */
#define decFloatFromBCD decDoubleFromBCD
#define decFloatFromInt32 decDoubleFromInt32
#define decFloatFromPacked decDoubleFromPacked
#define decFloatFromString decDoubleFromString
#define decFloatFromUInt32 decDoubleFromUInt32
#define decFloatFromWider decDoubleFromWider
#define decFloatGetCoefficient decDoubleGetCoefficient
#define decFloatGetExponent decDoubleGetExponent
#define decFloatSetCoefficient decDoubleSetCoefficient
#define decFloatSetExponent decDoubleSetExponent
#define decFloatShow decDoubleShow
#define decFloatToBCD decDoubleToBCD
#define decFloatToEngString decDoubleToEngString
#define decFloatToInt32 decDoubleToInt32
#define decFloatToInt32Exact decDoubleToInt32Exact
#define decFloatToPacked decDoubleToPacked
#define decFloatToString decDoubleToString
#define decFloatToUInt32 decDoubleToUInt32
#define decFloatToUInt32Exact decDoubleToUInt32Exact
#define decFloatToWider decDoubleToWider
#define decFloatZero decDoubleZero
/* Computational (result is a decFloat) */
#define decFloatAbs decDoubleAbs
#define decFloatAdd decDoubleAdd
#define decFloatAnd decDoubleAnd
#define decFloatDivide decDoubleDivide
#define decFloatDivideInteger decDoubleDivideInteger
#define decFloatFMA decDoubleFMA
#define decFloatInvert decDoubleInvert
#define decFloatLogB decDoubleLogB
#define decFloatMax decDoubleMax
#define decFloatMaxMag decDoubleMaxMag
#define decFloatMin decDoubleMin
#define decFloatMinMag decDoubleMinMag
#define decFloatMinus decDoubleMinus
#define decFloatMultiply decDoubleMultiply
#define decFloatNextMinus decDoubleNextMinus
#define decFloatNextPlus decDoubleNextPlus
#define decFloatNextToward decDoubleNextToward
#define decFloatOr decDoubleOr
#define decFloatPlus decDoublePlus
#define decFloatQuantize decDoubleQuantize
#define decFloatReduce decDoubleReduce
#define decFloatRemainder decDoubleRemainder
#define decFloatRemainderNear decDoubleRemainderNear
#define decFloatRotate decDoubleRotate
#define decFloatScaleB decDoubleScaleB
#define decFloatShift decDoubleShift
#define decFloatSubtract decDoubleSubtract
#define decFloatToIntegralValue decDoubleToIntegralValue
#define decFloatToIntegralExact decDoubleToIntegralExact
#define decFloatXor decDoubleXor
/* Comparisons */
#define decFloatCompare decDoubleCompare
#define decFloatCompareSignal decDoubleCompareSignal
#define decFloatCompareTotal decDoubleCompareTotal
#define decFloatCompareTotalMag decDoubleCompareTotalMag
/* Copies */
#define decFloatCanonical decDoubleCanonical
#define decFloatCopy decDoubleCopy
#define decFloatCopyAbs decDoubleCopyAbs
#define decFloatCopyNegate decDoubleCopyNegate
#define decFloatCopySign decDoubleCopySign
/* Non-computational */
#define decFloatClass decDoubleClass
#define decFloatClassString decDoubleClassString
#define decFloatDigits decDoubleDigits
#define decFloatIsCanonical decDoubleIsCanonical
#define decFloatIsFinite decDoubleIsFinite
#define decFloatIsInfinite decDoubleIsInfinite
#define decFloatIsInteger decDoubleIsInteger
#define decFloatIsNaN decDoubleIsNaN
#define decFloatIsNormal decDoubleIsNormal
#define decFloatIsSignaling decDoubleIsSignaling
#define decFloatIsSignalling decDoubleIsSignalling
#define decFloatIsSigned decDoubleIsSigned
#define decFloatIsSubnormal decDoubleIsSubnormal
#define decFloatIsZero decDoubleIsZero
#define decFloatRadix decDoubleRadix
#define decFloatSameQuantum decDoubleSameQuantum
#define decFloatVersion decDoubleVersion
#include "decNumberLocal.h" /* local includes (need DECPMAX) */
#include "decCommon.c" /* non-arithmetic decFloat routines */
#include "decBasic.c" /* basic formats routines */
/* Below here will move to shared file as completed */
/* decDouble module header for the decNumber C Library.
Copyright (C) 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
This file is part of GCC.
GCC 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 2, or (at your option) any later
version.
In addition to the permissions in the GNU General Public License,
the Free Software Foundation gives you unlimited permission to link
the compiled version of this file into combinations with other
programs, and to distribute those combinations without any
restriction coming from the use of this file. (The General Public
License restrictions do apply in other respects; for example, they
cover modification of the file, and distribution when not linked
into a combine executable.)
GCC 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.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
/* ------------------------------------------------------------------ */
/* decDouble.h -- Decimal 64-bit format module header */
/* ------------------------------------------------------------------ */
/* Please see decFloats.h for an overview and documentation details. */
/* ------------------------------------------------------------------ */
#if !defined(DECDOUBLE)
#define DECDOUBLE
#define DECDOUBLENAME "decimalDouble" /* Short name */
#define DECDOUBLETITLE "Decimal 64-bit datum" /* Verbose name */
#define DECDOUBLEAUTHOR "Mike Cowlishaw" /* Who to blame */
/* parameters for decDoubles */
#define DECDOUBLE_Bytes 8 /* length */
#define DECDOUBLE_Pmax 16 /* maximum precision (digits) */
#define DECDOUBLE_Emin -383 /* minimum adjusted exponent */
#define DECDOUBLE_Emax 384 /* maximum adjusted exponent */
#define DECDOUBLE_EmaxD 3 /* maximum exponent digits */
#define DECDOUBLE_Bias 398 /* bias for the exponent */
#define DECDOUBLE_String 25 /* maximum string length, +1 */
#define DECDOUBLE_EconL 8 /* exponent continuation length */
#define DECDOUBLE_Declets 5 /* count of declets */
/* highest biased exponent (Elimit-1) */
#define DECDOUBLE_Ehigh (DECDOUBLE_Emax + DECDOUBLE_Bias - (DECDOUBLE_Pmax-1))
/* Required includes */
#include "decContext.h"
#include "decQuad.h"
/* The decDouble decimal 64-bit type, accessible by bytes */
typedef struct {
uint8_t bytes[DECDOUBLE_Bytes]; /* fields: 1, 5, 8, 50 bits */
} decDouble;
/* ---------------------------------------------------------------- */
/* Routines -- implemented as decFloat routines in common files */
/* ---------------------------------------------------------------- */
#include "decDoubleSymbols.h"
/* Utilities and conversions, extractors, etc.) */
extern decDouble * decDoubleFromBCD(decDouble *, int32_t, const uint8_t *, int32_t);
extern decDouble * decDoubleFromInt32(decDouble *, int32_t);
extern decDouble * decDoubleFromPacked(decDouble *, int32_t, const uint8_t *);
extern decDouble * decDoubleFromString(decDouble *, const char *, decContext *);
extern decDouble * decDoubleFromUInt32(decDouble *, uint32_t);
extern decDouble * decDoubleFromWider(decDouble *, const decQuad *, decContext *);
extern int32_t decDoubleGetCoefficient(const decDouble *, uint8_t *);
extern int32_t decDoubleGetExponent(const decDouble *);
extern decDouble * decDoubleSetCoefficient(decDouble *, const uint8_t *, int32_t);
extern decDouble * decDoubleSetExponent(decDouble *, decContext *, int32_t);
extern void decDoubleShow(const decDouble *, const char *);
extern int32_t decDoubleToBCD(const decDouble *, int32_t *, uint8_t *);
extern char * decDoubleToEngString(const decDouble *, char *);
extern int32_t decDoubleToInt32(const decDouble *, decContext *, enum rounding);
extern int32_t decDoubleToInt32Exact(const decDouble *, decContext *, enum rounding);
extern int32_t decDoubleToPacked(const decDouble *, int32_t *, uint8_t *);
extern char * decDoubleToString(const decDouble *, char *);
extern uint32_t decDoubleToUInt32(const decDouble *, decContext *, enum rounding);
extern uint32_t decDoubleToUInt32Exact(const decDouble *, decContext *, enum rounding);
extern decQuad * decDoubleToWider(const decDouble *, decQuad *);
extern decDouble * decDoubleZero(decDouble *);
/* Computational (result is a decDouble) */
extern decDouble * decDoubleAbs(decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleAdd(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleAnd(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleDivide(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleDivideInteger(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleFMA(decDouble *, const decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleInvert(decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleLogB(decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleMax(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleMaxMag(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleMin(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleMinMag(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleMinus(decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleMultiply(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleNextMinus(decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleNextPlus(decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleNextToward(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleOr(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoublePlus(decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleQuantize(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleReduce(decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleRemainder(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleRemainderNear(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleRotate(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleScaleB(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleShift(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleSubtract(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleToIntegralValue(decDouble *, const decDouble *, decContext *, enum rounding);
extern decDouble * decDoubleToIntegralExact(decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleXor(decDouble *, const decDouble *, const decDouble *, decContext *);
/* Comparisons */
extern decDouble * decDoubleCompare(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleCompareSignal(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleCompareTotal(decDouble *, const decDouble *, const decDouble *);
extern decDouble * decDoubleCompareTotalMag(decDouble *, const decDouble *, const decDouble *);
/* Copies */
extern decDouble * decDoubleCanonical(decDouble *, const decDouble *);
extern decDouble * decDoubleCopy(decDouble *, const decDouble *);
extern decDouble * decDoubleCopyAbs(decDouble *, const decDouble *);
extern decDouble * decDoubleCopyNegate(decDouble *, const decDouble *);
extern decDouble * decDoubleCopySign(decDouble *, const decDouble *, const decDouble *);
/* Non-computational */
extern enum decClass decDoubleClass(const decDouble *);
extern const char * decDoubleClassString(const decDouble *);
extern uint32_t decDoubleDigits(const decDouble *);
extern uint32_t decDoubleIsCanonical(const decDouble *);
extern uint32_t decDoubleIsFinite(const decDouble *);
extern uint32_t decDoubleIsInfinite(const decDouble *);
extern uint32_t decDoubleIsInteger(const decDouble *);
extern uint32_t decDoubleIsNaN(const decDouble *);
extern uint32_t decDoubleIsNormal(const decDouble *);
extern uint32_t decDoubleIsSignaling(const decDouble *);
extern uint32_t decDoubleIsSignalling(const decDouble *);
extern uint32_t decDoubleIsSigned(const decDouble *);
extern uint32_t decDoubleIsSubnormal(const decDouble *);
extern uint32_t decDoubleIsZero(const decDouble *);
extern uint32_t decDoubleRadix(const decDouble *);
extern uint32_t decDoubleSameQuantum(const decDouble *, const decDouble *);
extern const char * decDoubleVersion(void);
/* decNumber conversions; these are implemented as macros so as not */
/* to force a dependency on decimal64 and decNumber in decDouble. */
#define decDoubleToNumber(dq, dn) decimal64ToNumber((decimal64 *)(dq), dn)
#define decDoubleFromNumber(dq, dn, set) (decDouble *)decimal64FromNumber((decimal64 *)(dq), dn, set)
#endif
#if !defined(DECDOUBLESYMBOLS)
#define DECDOUBLESYMBOLS
#ifdef IN_LIBGCC2
#define decDoubleAbs __decDoubleAbs
#define decDoubleAdd __decDoubleAdd
#define decDoubleAnd __decDoubleAnd
#define decDoubleCanonical __decDoubleCanonical
#define decDoubleClass __decDoubleClass
#define decDoubleClassString __decDoubleClassString
#define decDoubleCompare __decDoubleCompare
#define decDoubleCompareSignal __decDoubleCompareSignal
#define decDoubleCompareTotal __decDoubleCompareTotal
#define decDoubleCompareTotalMag __decDoubleCompareTotalMag
#define decDoubleCopy __decDoubleCopy
#define decDoubleCopyAbs __decDoubleCopyAbs
#define decDoubleCopyNegate __decDoubleCopyNegate
#define decDoubleCopySign __decDoubleCopySign
#define decDoubleDigits __decDoubleDigits
#define decDoubleDivide __decDoubleDivide
#define decDoubleDivideInteger __decDoubleDivideInteger
#define decDoubleFMA __decDoubleFMA
#define decDoubleFromBCD __decDoubleFromBCD
#define decDoubleFromInt32 __decDoubleFromInt32
#define decDoubleFromPacked __decDoubleFromPacked
#define decDoubleFromString __decDoubleFromString
#define decDoubleFromUInt32 __decDoubleFromUInt32
#define decDoubleFromWider __decDoubleFromWider
#define decDoubleGetCoefficient __decDoubleGetCoefficient
#define decDoubleGetExponent __decDoubleGetExponent
#define decDoubleInvert __decDoubleInvert
#define decDoubleIsCanonical __decDoubleIsCanonical
#define decDoubleIsFinite __decDoubleIsFinite
#define decDoubleIsInfinite __decDoubleIsInfinite
#define decDoubleIsInteger __decDoubleIsInteger
#define decDoubleIsNaN __decDoubleIsNaN
#define decDoubleIsNormal __decDoubleIsNormal
#define decDoubleIsSignaling __decDoubleIsSignaling
#define decDoubleIsSignalling __decDoubleIsSignalling
#define decDoubleIsSigned __decDoubleIsSigned
#define decDoubleIsSubnormal __decDoubleIsSubnormal
#define decDoubleIsZero __decDoubleIsZero
#define decDoubleLogB __decDoubleLogB
#define decDoubleMax __decDoubleMax
#define decDoubleMaxMag __decDoubleMaxMag
#define decDoubleMin __decDoubleMin
#define decDoubleMinMag __decDoubleMinMag
#define decDoubleMinus __decDoubleMinus
#define decDoubleMultiply __decDoubleMultiply
#define decDoubleNextMinus __decDoubleNextMinus
#define decDoubleNextPlus __decDoubleNextPlus
#define decDoubleNextToward __decDoubleNextToward
#define decDoubleOr __decDoubleOr
#define decDoublePlus __decDoublePlus
#define decDoubleQuantize __decDoubleQuantize
#define decDoubleRadix __decDoubleRadix
#define decDoubleReduce __decDoubleReduce
#define decDoubleRemainder __decDoubleRemainder
#define decDoubleRemainderNear __decDoubleRemainderNear
#define decDoubleRotate __decDoubleRotate
#define decDoubleSameQuantum __decDoubleSameQuantum
#define decDoubleScaleB __decDoubleScaleB
#define decDoubleSetCoefficient __decDoubleSetCoefficient
#define decDoubleSetExponent __decDoubleSetExponent
#define decDoubleShift __decDoubleShift
#define decDoubleShow __decDoubleShow
#define decDoubleSubtract __decDoubleSubtract
#define decDoubleToBCD __decDoubleToBCD
#define decDoubleToEngString __decDoubleToEngString
#define decDoubleToInt32 __decDoubleToInt32
#define decDoubleToInt32Exact __decDoubleToInt32Exact
#define decDoubleToIntegralExact __decDoubleToIntegralExact
#define decDoubleToIntegralValue __decDoubleToIntegralValue
#define decDoubleToPacked __decDoubleToPacked
#define decDoubleToString __decDoubleToString
#define decDoubleToUInt32 __decDoubleToUInt32
#define decDoubleToUInt32Exact __decDoubleToUInt32Exact
#define decDoubleToWider __decDoubleToWider
#define decDoubleVersion __decDoubleVersion
#define decDoubleXor __decDoubleXor
#define decDoubleZero __decDoubleZero
#endif
#endif
...@@ -74,22 +74,3 @@ isinfd128 (_Decimal128 arg) ...@@ -74,22 +74,3 @@ isinfd128 (_Decimal128 arg)
decimal128ToNumber (&d128, &dn); decimal128ToNumber (&d128, &dn);
return (decNumberIsInfinite (&dn)); return (decNumberIsInfinite (&dn));
} }
uint32_t
__dec_byte_swap (uint32_t in)
{
uint32_t out = 0;
unsigned char *p = (unsigned char *) &out;
union {
uint32_t i;
unsigned char b[4];
} u;
u.i = in;
p[0] = u.b[3];
p[1] = u.b[2];
p[2] = u.b[1];
p[3] = u.b[0];
return out;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
/* Decimal Number module header for the decNumber C Library /* Decimal number arithmetic module header for the decNumber C Library.
Copyright (C) 2005 Free Software Foundation, Inc. Copyright (C) 2005, 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw. Contributed by IBM Corporation. Author Mike Cowlishaw.
This file is part of GCC. This file is part of GCC.
...@@ -28,167 +28,173 @@ ...@@ -28,167 +28,173 @@
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */ 02110-1301, USA. */
/* ------------------------------------------------------------------ */
/* Decimal Number arithmetic module header */
/* ------------------------------------------------------------------ */
#if !defined(DECNUMBER) #if !defined(DECNUMBER)
#define DECNUMBER #define DECNUMBER
#define DECNAME "decNumber" /* Short name */ #define DECNAME "decNumber" /* Short name */
#define DECVERSION "decNumber 3.24" /* Version [16 max.] */ #define DECFULLNAME "Decimal Number Module" /* Verbose name */
#define DECFULLNAME "Decimal Number Module" /* Verbose name */ #define DECAUTHOR "Mike Cowlishaw" /* Who to blame */
#define DECAUTHOR "Mike Cowlishaw" /* Who to blame */
#if !defined(DECCONTEXT)
#include "decContext.h"
#endif
#if !defined(DECCONTEXT)
#include "decContext.h"
#endif
/* Bit settings for decNumber.bits */ /* Bit settings for decNumber.bits */
#define DECNEG 0x80 /* Sign; 1=negative, 0=positive or zero */ #define DECNEG 0x80 /* Sign; 1=negative, 0=positive or zero */
#define DECINF 0x40 /* 1=Infinity */ #define DECINF 0x40 /* 1=Infinity */
#define DECNAN 0x20 /* 1=NaN */ #define DECNAN 0x20 /* 1=NaN */
#define DECSNAN 0x10 /* 1=sNaN */ #define DECSNAN 0x10 /* 1=sNaN */
/* The remaining bits are reserved; they must be 0 */ /* The remaining bits are reserved; they must be 0 */
#define DECSPECIAL (DECINF|DECNAN|DECSNAN) /* any special value */ #define DECSPECIAL (DECINF|DECNAN|DECSNAN) /* any special value */
/* DECNUMDIGITS is the default number of digits we can hold in the */
/* structure. If undefined, 1 is assumed and it is assumed that the */
/* structure will be immediately followed by extra space (if */
/* required). DECNUMDIGITS is always >0. */
#if !defined(DECNUMDIGITS)
#define DECNUMDIGITS 1
#endif
/* Define the decNumber data structure. The size and shape of the */ /* Define the decNumber data structure. The size and shape of the */
/* units array in the structure is determined by the following */ /* units array in the structure is determined by the following */
/* constant. This must not be changed without recompiling the */ /* constant. This must not be changed without recompiling the */
/* decNumber library modules. */ /* decNumber library modules. */
#define DECDPUN 4 /* Decimal Digits Per UNit [must be in */
/* range 1-9; power of 2 recommended]. */ #define DECDPUN 3 /* DECimal Digits Per UNit [must be >0 */
/* and <10; 3 or powers of 2 are best]. */
/* DECNUMDIGITS is the default number of digits that can be held in */
/* the structure. If undefined, 1 is assumed and it is assumed */
/* that the structure will be immediately followed by extra space, */
/* as required. DECNUMDIGITS is always >0. */
#if !defined(DECNUMDIGITS)
#define DECNUMDIGITS 1
#endif
/* The size (integer data type) of each unit is determined by the */ /* The size (integer data type) of each unit is determined by the */
/* number of digits it will hold. */ /* number of digits it will hold. */
#if DECDPUN<=2 #if DECDPUN<=2
#define decNumberUnit uint8_t #define decNumberUnit uint8_t
#elif DECDPUN<=4 #elif DECDPUN<=4
#define decNumberUnit uint16_t #define decNumberUnit uint16_t
#else #else
#define decNumberUnit uint32_t #define decNumberUnit uint32_t
#endif #endif
/* The number of decNumberUnits we need is ceiling of DECNUMDIGITS/DECDPUN */ /* The number of units needed is ceil(DECNUMDIGITS/DECDPUN) */
#define DECNUMUNITS ((DECNUMDIGITS+DECDPUN-1)/DECDPUN) #define DECNUMUNITS ((DECNUMDIGITS+DECDPUN-1)/DECDPUN)
/* The data structure... */ /* The data structure... */
typedef struct typedef struct {
{
int32_t digits; /* Count of digits in the coefficient; >0 */ int32_t digits; /* Count of digits in the coefficient; >0 */
int32_t exponent; /* Unadjusted exponent, unbiased, in */ int32_t exponent; /* Unadjusted exponent, unbiased, in */
/* range: -1999999997 through 999999999 */ /* range: -1999999997 through 999999999 */
uint8_t bits; /* Indicator bits (see above) */ uint8_t bits; /* Indicator bits (see above) */
decNumberUnit lsu[DECNUMUNITS]; /* Coefficient, from least significant unit */ /* Coefficient, from least significant unit */
} decNumber; decNumberUnit lsu[DECNUMUNITS];
} decNumber;
/* Notes: */ /* Notes: */
/* 1. If digits is > DECDPUN then there will be more than one */ /* 1. If digits is > DECDPUN then there will one or more */
/* decNumberUnits immediately following the first element of lsu. */ /* decNumberUnits immediately following the first element of lsu.*/
/* These contain the remaining (more significant) digits of the */ /* These contain the remaining (more significant) digits of the */
/* number, and may be in the lsu array, or may be guaranteed by */ /* number, and may be in the lsu array, or may be guaranteed by */
/* some other mechanism (such as being contained in another */ /* some other mechanism (such as being contained in another */
/* structure, or being overlaid on dynamically allocated storage). */ /* structure, or being overlaid on dynamically allocated */
/* storage). */
/* */ /* */
/* Each integer of the coefficient (except the possibly the last) */ /* Each integer of the coefficient (except potentially the last) */
/* contains DECDPUN digits (e.g., a value in the range 0 through */ /* contains DECDPUN digits (e.g., a value in the range 0 through */
/* 99999999 if DECDPUN is 8, or 0 through 9999 if DECDPUN is 4). */ /* 99999999 if DECDPUN is 8, or 0 through 999 if DECDPUN is 3). */
/* */ /* */
/* 2. A decNumber converted to a string may need up to digits+14 */ /* 2. A decNumber converted to a string may need up to digits+14 */
/* characters. The worst cases (non-exponential and exponential */ /* characters. The worst cases (non-exponential and exponential */
/* formats) are: -0.00000{9...}# */ /* formats) are -0.00000{9...}# and -9.{9...}E+999999999# */
/* and: -9.{9...}E+999999999# (where # is '\0') */ /* (where # is '\0') */
/* ------------------------------------------------------------------ */ /* ---------------------------------------------------------------- */
/* decNumber public functions and macros */ /* decNumber public functions and macros */
/* ------------------------------------------------------------------ */ /* ---------------------------------------------------------------- */
#ifdef IN_LIBGCC2 #include "decNumberSymbols.h"
#define decNumberFromString __decNumberFromString
#define decNumberToString __decNumberToString
#define decNumberToEngString __decNumberToEngString
#define decNumberAbs __decNumberAbs
#define decNumberAdd __decNumberAdd
#define decNumberCompare __decNumberCompare
#define decNumberDivide __decNumberDivide
#define decNumberDivideInteger __decNumberDivideInteger
#define decNumberMax __decNumberMax
#define decNumberMin __decNumberMin
#define decNumberMinus __decNumberMinus
#define decNumberMultiply __decNumberMultiply
#define decNumberNormalize __decNumberNormalize
#define decNumberPlus __decNumberPlus
#define decNumberPower __decNumberPower
#define decNumberQuantize __decNumberQuantize
#define decNumberRemainder __decNumberRemainder
#define decNumberRemainderNear __decNumberRemainderNear
#define decNumberRescale __decNumberRescale
#define decNumberSameQuantum __decNumberSameQuantum
#define decNumberSquareRoot __decNumberSquareRoot
#define decNumberSubtract __decNumberSubtract
#define decNumberToIntegralValue __decNumberToIntegralValue
#define decNumberCopy __decNumberCopy
#define decNumberTrim __decNumberTrim
#define decNumberVersion __decNumberVersion
#define decNumberZero __decNumberZero
#endif
/* Conversions */ /* Conversions */
decNumber *decNumberFromString (decNumber *, const char *, decContext *); decNumber * decNumberFromInt32(decNumber *, int32_t);
char *decNumberToString (const decNumber *, char *); decNumber * decNumberFromUInt32(decNumber *, uint32_t);
char *decNumberToEngString (const decNumber *, char *); decNumber * decNumberFromString(decNumber *, const char *, decContext *);
char * decNumberToString(const decNumber *, char *);
/* Operators */ char * decNumberToEngString(const decNumber *, char *);
decNumber *decNumberAbs (decNumber *, const decNumber *, decContext *); uint32_t decNumberToUInt32(const decNumber *, decContext *);
decNumber *decNumberAdd (decNumber *, const decNumber *, int32_t decNumberToInt32(const decNumber *, decContext *);
const decNumber *, decContext *); uint8_t * decNumberGetBCD(const decNumber *, uint8_t *);
decNumber *decNumberCompare (decNumber *, const decNumber *, decNumber * decNumberSetBCD(decNumber *, const uint8_t *, uint32_t);
const decNumber *, decContext *);
decNumber *decNumberDivide (decNumber *, const decNumber *, /* Operators and elementary functions */
const decNumber *, decContext *); decNumber * decNumberAbs(decNumber *, const decNumber *, decContext *);
decNumber *decNumberDivideInteger (decNumber *, const decNumber *, decNumber * decNumberAdd(decNumber *, const decNumber *, const decNumber *, decContext *);
const decNumber *, decContext *); decNumber * decNumberAnd(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber *decNumberMax (decNumber *, const decNumber *, decNumber * decNumberCompare(decNumber *, const decNumber *, const decNumber *, decContext *);
const decNumber *, decContext *); decNumber * decNumberCompareSignal(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber *decNumberMin (decNumber *, const decNumber *, decNumber * decNumberCompareTotal(decNumber *, const decNumber *, const decNumber *, decContext *);
const decNumber *, decContext *); decNumber * decNumberCompareTotalMag(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber *decNumberMinus (decNumber *, const decNumber *, decContext *); decNumber * decNumberDivide(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber *decNumberMultiply (decNumber *, const decNumber *, decNumber * decNumberDivideInteger(decNumber *, const decNumber *, const decNumber *, decContext *);
const decNumber *, decContext *); decNumber * decNumberExp(decNumber *, const decNumber *, decContext *);
decNumber *decNumberNormalize (decNumber *, const decNumber *, decContext *); decNumber * decNumberFMA(decNumber *, const decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber *decNumberPlus (decNumber *, const decNumber *, decContext *); decNumber * decNumberInvert(decNumber *, const decNumber *, decContext *);
decNumber *decNumberPower (decNumber *, const decNumber *, decNumber * decNumberLn(decNumber *, const decNumber *, decContext *);
const decNumber *, decContext *); decNumber * decNumberLogB(decNumber *, const decNumber *, decContext *);
decNumber *decNumberQuantize (decNumber *, const decNumber *, decNumber * decNumberLog10(decNumber *, const decNumber *, decContext *);
const decNumber *, decContext *); decNumber * decNumberMax(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber *decNumberRemainder (decNumber *, const decNumber *, decNumber * decNumberMaxMag(decNumber *, const decNumber *, const decNumber *, decContext *);
const decNumber *, decContext *); decNumber * decNumberMin(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber *decNumberRemainderNear (decNumber *, const decNumber *, decNumber * decNumberMinMag(decNumber *, const decNumber *, const decNumber *, decContext *);
const decNumber *, decContext *); decNumber * decNumberMinus(decNumber *, const decNumber *, decContext *);
decNumber *decNumberRescale (decNumber *, const decNumber *, decNumber * decNumberMultiply(decNumber *, const decNumber *, const decNumber *, decContext *);
const decNumber *, decContext *); decNumber * decNumberNormalize(decNumber *, const decNumber *, decContext *);
decNumber *decNumberSameQuantum (decNumber *, const decNumber *, const decNumber *); decNumber * decNumberOr(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber *decNumberSquareRoot (decNumber *, const decNumber *, decContext *); decNumber * decNumberPlus(decNumber *, const decNumber *, decContext *);
decNumber *decNumberSubtract (decNumber *, const decNumber *, decNumber * decNumberPower(decNumber *, const decNumber *, const decNumber *, decContext *);
const decNumber *, decContext *); decNumber * decNumberQuantize(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber *decNumberToIntegralValue (decNumber *, const decNumber *, decContext *); decNumber * decNumberReduce(decNumber *, const decNumber *, decContext *);
decNumber * decNumberRemainder(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberRemainderNear(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberRescale(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberRotate(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberSameQuantum(decNumber *, const decNumber *, const decNumber *);
decNumber * decNumberScaleB(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberShift(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberSquareRoot(decNumber *, const decNumber *, decContext *);
decNumber * decNumberSubtract(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberToIntegralExact(decNumber *, const decNumber *, decContext *);
decNumber * decNumberToIntegralValue(decNumber *, const decNumber *, decContext *);
decNumber * decNumberXor(decNumber *, const decNumber *, const decNumber *, decContext *);
/* Utilities */ /* Utilities */
decNumber *decNumberCopy (decNumber *, const decNumber *); enum decClass decNumberClass(const decNumber *, decContext *);
decNumber *decNumberTrim (decNumber *); const char * decNumberClassToString(enum decClass);
const char *decNumberVersion (void); decNumber * decNumberCopy(decNumber *, const decNumber *);
decNumber *decNumberZero (decNumber *); decNumber * decNumberCopyAbs(decNumber *, const decNumber *);
decNumber * decNumberCopyNegate(decNumber *, const decNumber *);
/* Macros */ decNumber * decNumberCopySign(decNumber *, const decNumber *, const decNumber *);
#define decNumberIsZero(dn) (*(dn)->lsu==0 \ decNumber * decNumberNextMinus(decNumber *, const decNumber *, decContext *);
decNumber * decNumberNextPlus(decNumber *, const decNumber *, decContext *);
decNumber * decNumberNextToward(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberTrim(decNumber *);
const char * decNumberVersion(void);
decNumber * decNumberZero(decNumber *);
/* Functions for testing decNumbers (normality depends on context) */
int32_t decNumberIsNormal(const decNumber *, decContext *);
int32_t decNumberIsSubnormal(const decNumber *, decContext *);
/* Macros for testing decNumber *dn */
#define decNumberIsCanonical(dn) (1) /* All decNumbers are saintly */
#define decNumberIsFinite(dn) (((dn)->bits&DECSPECIAL)==0)
#define decNumberIsInfinite(dn) (((dn)->bits&DECINF)!=0)
#define decNumberIsNaN(dn) (((dn)->bits&(DECNAN|DECSNAN))!=0)
#define decNumberIsNegative(dn) (((dn)->bits&DECNEG)!=0)
#define decNumberIsQNaN(dn) (((dn)->bits&(DECNAN))!=0)
#define decNumberIsSNaN(dn) (((dn)->bits&(DECSNAN))!=0)
#define decNumberIsSpecial(dn) (((dn)->bits&DECSPECIAL)!=0)
#define decNumberIsZero(dn) (*(dn)->lsu==0 \
&& (dn)->digits==1 \ && (dn)->digits==1 \
&& (((dn)->bits&DECSPECIAL)==0)) && (((dn)->bits&DECSPECIAL)==0))
#define decNumberIsNegative(dn) (((dn)->bits&DECNEG)!=0) #define decNumberRadix(dn) (10)
#define decNumberIsNaN(dn) (((dn)->bits&(DECNAN|DECSNAN))!=0)
#define decNumberIsInfinite(dn) (((dn)->bits&DECINF)!=0)
#endif #endif
/* decNumber package local type, tuning, and macro definitions. /* Local definitions for the decNumber C Library.
Copyright (C) 2005 Free Software Foundation, Inc. Copyright (C) 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw. Contributed by IBM Corporation. Author Mike Cowlishaw.
This file is part of GCC. This file is part of GCC.
...@@ -29,108 +29,637 @@ ...@@ -29,108 +29,637 @@
02110-1301, USA. */ 02110-1301, USA. */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* decNumber package local type, tuning, and macro definitions */
/* ------------------------------------------------------------------ */
/* This header file is included by all modules in the decNumber */ /* This header file is included by all modules in the decNumber */
/* library, and contains local type definitions, tuning parameters, */ /* library, and contains local type definitions, tuning parameters, */
/* etc. It must only be included once, and should not need to be */ /* etc. It should not need to be used by application programs. */
/* used by application programs. decNumber.h must be included first. */ /* decNumber.h or one of decDouble (etc.) must be included first. */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
#if !defined(DECNUMBERLOC) #if !defined(DECNUMBERLOC)
#define DECNUMBERLOC #define DECNUMBERLOC
#define DECNLAUTHOR "Mike Cowlishaw" /* Who to blame */ #define DECVERSION "decNumber 3.53" /* Package Version [16 max.] */
#define DECNLAUTHOR "Mike Cowlishaw" /* Who to blame */
/* Local names for common types -- decNumber modules do not use int or
long directly */ #include <stdlib.h> /* for abs */
#define Flag uint8_t #include <string.h> /* for memset, strcpy */
#define Byte int8_t #include "config.h" /* for WORDS_BIGENDIAN */
#define uByte uint8_t
#define Short int16_t /* Conditional code flag -- set this to match hardware platform */
#define uShort uint16_t /* 1=little-endian, 0=big-endian */
#define Int int32_t #if WORDS_BIGENDIAN
#define uInt uint32_t #define DECLITEND 0
#define Unit decNumberUnit #else
#define DECLITEND 1
#endif
/* Tuning parameter */
#define DECBUFFER 36 /* Maximum size basis for local buffers. */ /* Conditional code flag -- set this to 1 for best performance */
/* Should be a common maximum precision */ #define DECUSE64 1 /* 1=use int64s, 0=int32 & smaller only */
/* Conditional check flags -- set these to 0 for best performance */
#define DECCHECK 0 /* 1 to enable robust checking */
#define DECALLOC 0 /* 1 to enable memory accounting */
#define DECTRACE 0 /* 1 to trace certain internals, etc. */
/* Tuning parameter for decNumber (arbitrary precision) module */
#define DECBUFFER 36 /* Size basis for local buffers. This */
/* should be a common maximum precision */
/* rounded up to a multiple of 4; must */ /* rounded up to a multiple of 4; must */
/* be non-negative. */ /* be zero or positive. */
/* Conditional code flags -- set these to 0 for best performance */ /* ---------------------------------------------------------------- */
#define DECCHECK 0 /* 1 to enable robust checking */ /* Definitions for all modules (general-purpose) */
#define DECALLOC 0 /* 1 to enable memory allocation accounting */ /* ---------------------------------------------------------------- */
#define DECTRACE 0 /* 1 to trace critical intermediates, etc. */
/* Local names for common types -- for safety, decNumber modules do */
/* not use int or long directly. */
#define Flag uint8_t
#define Byte int8_t
#define uByte uint8_t
#define Short int16_t
#define uShort uint16_t
#define Int int32_t
#define uInt uint32_t
#define Unit decNumberUnit
#if DECUSE64
#define Long int64_t
#define uLong uint64_t
#endif
/* Development use defines */ /* Development-use definitions */
#if DECALLOC typedef long int LI; /* for printf arguments only */
/* if these interfere with your C includes, just comment them out */ #define DECNOINT 0 /* 1 to check no internal use of 'int' */
#define int ? /* enable to ensure we do not use plain C */ #if DECNOINT
#define long ?? /* .. 'int' or 'long' types from here on */ /* if these interfere with your C includes, do not set DECNOINT */
#endif #define int ? /* enable to ensure that plain C 'int' */
#define long ?? /* .. or 'long' types are not used */
#endif
/* Limits and constants */ /* Shared lookup tables */
#define DECNUMMAXP 999999999 /* maximum precision we can handle (9 digits) */ extern const uByte DECSTICKYTAB[10]; /* re-round digits if sticky */
#define DECNUMMAXE 999999999 /* maximum adjusted exponent ditto (9 digits) */ extern const uInt DECPOWERS[10]; /* powers of ten table */
#define DECNUMMINE -999999999 /* minimum adjusted exponent ditto (9 digits) */ /* The following are included from decDPD.h */
#if (DECNUMMAXP != DEC_MAX_DIGITS) extern const uShort DPD2BIN[1024]; /* DPD -> 0-999 */
#error Maximum digits mismatch extern const uShort BIN2DPD[1000]; /* 0-999 -> DPD */
#endif extern const uInt DPD2BINK[1024]; /* DPD -> 0-999000 */
#if (DECNUMMAXE != DEC_MAX_EMAX) extern const uInt DPD2BINM[1024]; /* DPD -> 0-999000000 */
#error Maximum exponent mismatch extern const uByte DPD2BCD8[4096]; /* DPD -> ddd + len */
#endif extern const uByte BIN2BCD8[4000]; /* 0-999 -> ddd + len */
#if (DECNUMMINE != DEC_MIN_EMIN) extern const uShort BCD2DPD[2458]; /* 0-0x999 -> DPD (0x999=2457)*/
#error Minimum exponent mismatch
#endif
/* Set DECDPUNMAX -- the maximum integer that fits in DECDPUN digits */ /* LONGMUL32HI -- set w=(u*v)>>32, where w, u, and v are uInts */
#if DECDPUN==1 /* (that is, sets w to be the high-order word of the 64-bit result; */
#define DECDPUNMAX 9 /* the low-order word is simply u*v.) */
#elif DECDPUN==2 /* This version is derived from Knuth via Hacker's Delight; */
#define DECDPUNMAX 99 /* it seems to optimize better than some others tried */
#elif DECDPUN==3 #define LONGMUL32HI(w, u, v) { \
#define DECDPUNMAX 999 uInt u0, u1, v0, v1, w0, w1, w2, t; \
#elif DECDPUN==4 u0=u & 0xffff; u1=u>>16; \
#define DECDPUNMAX 9999 v0=v & 0xffff; v1=v>>16; \
#elif DECDPUN==5 w0=u0*v0; \
#define DECDPUNMAX 99999 t=u1*v0 + (w0>>16); \
#elif DECDPUN==6 w1=t & 0xffff; w2=t>>16; \
#define DECDPUNMAX 999999 w1=u0*v1 + w1; \
#elif DECDPUN==7 (w)=u1*v1 + w2 + (w1>>16);}
#define DECDPUNMAX 9999999
#elif DECDPUN==8
#define DECDPUNMAX 99999999
#elif DECDPUN==9
#define DECDPUNMAX 999999999
#elif defined(DECDPUN)
#error DECDPUN must be in the range 1-9
#endif
/* ROUNDUP -- round an integer up to a multiple of n */
#define ROUNDUP(i, n) ((((i)+(n)-1)/n)*n)
/* ----- Shared data ----- */ /* ROUNDDOWN -- round an integer down to a multiple of n */
/* The powers of of ten array (powers[n]==10**n, 0<=n<=10) */ #define ROUNDDOWN(i, n) (((i)/n)*n)
extern const uInt powers[]; #define ROUNDDOWN4(i) ((i)&~3) /* special for n=4 */
/* ----- Macros ----- */ /* References to multi-byte sequences under different sizes */
/* ISZERO -- return true if decNumber dn is a zero */ /* Refer to a uInt from four bytes starting at a char* or uByte*, */
/* [performance-critical in some situations] */ /* etc. */
#define ISZERO(dn) decNumberIsZero(dn) /* now just a local name */ #define UINTAT(b) (*((uInt *)(b)))
#define USHORTAT(b) (*((uShort *)(b)))
#define UBYTEAT(b) (*((uByte *)(b)))
/* X10 and X100 -- multiply integer i by 10 or 100 */ /* X10 and X100 -- multiply integer i by 10 or 100 */
/* [shifts are usually faster than multiply; could be conditional] */ /* [shifts are usually faster than multiply; could be conditional] */
#define X10(i) (((i)<<1)+((i)<<3)) #define X10(i) (((i)<<1)+((i)<<3))
#define X100(i) (((i)<<2)+((i)<<5)+((i)<<6)) #define X100(i) (((i)<<2)+((i)<<5)+((i)<<6))
/* MAXI and MINI -- general max & min (not in ANSI) for integers */
#define MAXI(x,y) ((x)<(y)?(y):(x))
#define MINI(x,y) ((x)>(y)?(y):(x))
/* Useful constants */
#define BILLION 1000000000 /* 10**9 */
/* CHARMASK: 0x30303030 for ASCII/UTF8; 0xF0F0F0F0 for EBCDIC */
#define CHARMASK ((((((((uInt)'0')<<8)+'0')<<8)+'0')<<8)+'0')
/* ---------------------------------------------------------------- */
/* Definitions for arbitary-precision modules (only valid after */
/* decNumber.h has been included) */
/* ---------------------------------------------------------------- */
/* Limits and constants */
#define DECNUMMAXP 999999999 /* maximum precision code can handle */
#define DECNUMMAXE 999999999 /* maximum adjusted exponent ditto */
#define DECNUMMINE -999999999 /* minimum adjusted exponent ditto */
#if (DECNUMMAXP != DEC_MAX_DIGITS)
#error Maximum digits mismatch
#endif
#if (DECNUMMAXE != DEC_MAX_EMAX)
#error Maximum exponent mismatch
#endif
#if (DECNUMMINE != DEC_MIN_EMIN)
#error Minimum exponent mismatch
#endif
/* Set DECDPUNMAX -- the maximum integer that fits in DECDPUN */
/* digits, and D2UTABLE -- the initializer for the D2U table */
#if DECDPUN==1
#define DECDPUNMAX 9
#define D2UTABLE {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17, \
18,19,20,21,22,23,24,25,26,27,28,29,30,31,32, \
33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, \
48,49}
#elif DECDPUN==2
#define DECDPUNMAX 99
#define D2UTABLE {0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10, \
11,11,12,12,13,13,14,14,15,15,16,16,17,17,18, \
18,19,19,20,20,21,21,22,22,23,23,24,24,25}
#elif DECDPUN==3
#define DECDPUNMAX 999
#define D2UTABLE {0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7, \
8,8,8,9,9,9,10,10,10,11,11,11,12,12,12,13,13, \
13,14,14,14,15,15,15,16,16,16,17}
#elif DECDPUN==4
#define DECDPUNMAX 9999
#define D2UTABLE {0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6, \
6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10,11, \
11,11,11,12,12,12,12,13}
#elif DECDPUN==5
#define DECDPUNMAX 99999
#define D2UTABLE {0,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5, \
5,5,5,5,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8,9,9,9, \
9,9,10,10,10,10}
#elif DECDPUN==6
#define DECDPUNMAX 999999
#define D2UTABLE {0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4, \
4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,8, \
8,8,8,8,8,9}
#elif DECDPUN==7
#define DECDPUNMAX 9999999
#define D2UTABLE {0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3, \
4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,7, \
7,7,7,7,7,7}
#elif DECDPUN==8
#define DECDPUNMAX 99999999
#define D2UTABLE {0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3, \
3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6, \
6,6,6,6,6,7}
#elif DECDPUN==9
#define DECDPUNMAX 999999999
#define D2UTABLE {0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3, \
3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5, \
5,5,6,6,6,6}
#elif defined(DECDPUN)
#error DECDPUN must be in the range 1-9
#endif
/* ----- Shared data (in decNumber.c) ----- */
/* Public lookup table used by the D2U macro (see below) */
#define DECMAXD2U 49
extern const uByte d2utable[DECMAXD2U+1];
/* ----- Macros ----- */
/* ISZERO -- return true if decNumber dn is a zero */
/* [performance-critical in some situations] */
#define ISZERO(dn) decNumberIsZero(dn) /* now just a local name */
/* D2U -- return the number of Units needed to hold d digits */ /* D2U -- return the number of Units needed to hold d digits */
#if DECDPUN==8 /* (runtime version, with table lookaside for small d) */
#define D2U(d) ((unsigned)((d)+7)>>3) #if DECDPUN==8
#elif DECDPUN==4 #define D2U(d) ((unsigned)((d)<=DECMAXD2U?d2utable[d]:((d)+7)>>3))
#define D2U(d) ((unsigned)((d)+3)>>2) #elif DECDPUN==4
#else #define D2U(d) ((unsigned)((d)<=DECMAXD2U?d2utable[d]:((d)+3)>>2))
#define D2U(d) (((d)+DECDPUN-1)/DECDPUN) #else
#endif #define D2U(d) ((d)<=DECMAXD2U?d2utable[d]:((d)+DECDPUN-1)/DECDPUN)
#endif
/* SD2U -- static D2U macro (for compile-time calculation) */
#define SD2U(d) (((d)+DECDPUN-1)/DECDPUN)
/* MSUDIGITS -- returns digits in msu, from digits, calculated */
/* using D2U */
#define MSUDIGITS(d) ((d)-(D2U(d)-1)*DECDPUN)
/* D2N -- return the number of decNumber structs that would be */
/* needed to contain that number of digits (and the initial */
/* decNumber struct) safely. Note that one Unit is included in the */
/* initial structure. Used for allocating space that is aligned on */
/* a decNumber struct boundary. */
#define D2N(d) \
((((SD2U(d)-1)*sizeof(Unit))+sizeof(decNumber)*2-1)/sizeof(decNumber))
/* TODIGIT -- macro to remove the leading digit from the unsigned */
/* integer u at column cut (counting from the right, LSD=0) and */
/* place it as an ASCII character into the character pointed to by */
/* c. Note that cut must be <= 9, and the maximum value for u is */
/* 2,000,000,000 (as is needed for negative exponents of */
/* subnormals). The unsigned integer pow is used as a temporary */
/* variable. */
#define TODIGIT(u, cut, c, pow) { \
*(c)='0'; \
pow=DECPOWERS[cut]*2; \
if ((u)>pow) { \
pow*=4; \
if ((u)>=pow) {(u)-=pow; *(c)+=8;} \
pow/=2; \
if ((u)>=pow) {(u)-=pow; *(c)+=4;} \
pow/=2; \
} \
if ((u)>=pow) {(u)-=pow; *(c)+=2;} \
pow/=2; \
if ((u)>=pow) {(u)-=pow; *(c)+=1;} \
}
/* ---------------------------------------------------------------- */
/* Definitions for fixed-precision modules (only valid after */
/* decSingle.h, decDouble.h, or decQuad.h has been included) */
/* ---------------------------------------------------------------- */
/* bcdnum -- a structure describing a format-independent finite */
/* number, whose coefficient is a string of bcd8 uBytes */
typedef struct {
uByte *msd; /* -> most significant digit */
uByte *lsd; /* -> least ditto */
uInt sign; /* 0=positive, DECFLOAT_Sign=negative */
Int exponent; /* Unadjusted signed exponent (q), or */
/* DECFLOAT_NaN etc. for a special */
} bcdnum;
/* Test if exponent or bcdnum exponent must be a special, etc. */
#define EXPISSPECIAL(exp) ((exp)>=DECFLOAT_MinSp)
#define EXPISINF(exp) (exp==DECFLOAT_Inf)
#define EXPISNAN(exp) (exp==DECFLOAT_qNaN || exp==DECFLOAT_sNaN)
#define NUMISSPECIAL(num) (EXPISSPECIAL((num)->exponent))
/* Refer to a 32-bit word or byte in a decFloat (df) by big-endian */
/* (array) notation (the 0 word or byte contains the sign bit), */
/* automatically adjusting for endianness; similarly address a word */
/* in the next-wider format (decFloatWider, or dfw) */
#define DECWORDS (DECBYTES/4)
#define DECWWORDS (DECWBYTES/4)
#if DECLITEND
#define DFWORD(df, off) UINTAT((df)->bytes+(DECWORDS-1-(off))*4)
#define DFBYTE(df, off) UBYTEAT((df)->bytes+(DECBYTES-1-(off)))
#define DFWWORD(dfw, off) UINTAT((dfw)->bytes+(DECWWORDS-1-(off))*4)
#else
#define DFWORD(df, off) UINTAT((df)->bytes+(off)*4)
#define DFBYTE(df, off) UBYTEAT((df)->bytes+(off))
#define DFWWORD(dfw, off) UINTAT((dfw)->bytes+(off)*4)
#endif
/* Tests for sign or specials, directly on DECFLOATs */
#define DFISSIGNED(df) (DFWORD(df, 0)&0x80000000)
#define DFISSPECIAL(df) ((DFWORD(df, 0)&0x78000000)==0x78000000)
#define DFISINF(df) ((DFWORD(df, 0)&0x7c000000)==0x78000000)
#define DFISNAN(df) ((DFWORD(df, 0)&0x7c000000)==0x7c000000)
#define DFISQNAN(df) ((DFWORD(df, 0)&0x7e000000)==0x7c000000)
#define DFISSNAN(df) ((DFWORD(df, 0)&0x7e000000)==0x7e000000)
/* Shared lookup tables */
extern const uInt DECCOMBMSD[64]; /* Combination field -> MSD */
extern const uInt DECCOMBFROM[48]; /* exp+msd -> Combination */
/* Private generic (utility) routine */
#if DECCHECK || DECTRACE
extern void decShowNum(const bcdnum *, const char *);
#endif
/* Format-dependent macros and constants */
#if defined(DECPMAX)
/* Useful constants */
#define DECPMAX9 (ROUNDUP(DECPMAX, 9)/9) /* 'Pmax' in 10**9s */
/* Top words for a zero */
#define SINGLEZERO 0x22500000
#define DOUBLEZERO 0x22380000
#define QUADZERO 0x22080000
/* [ZEROWORD is defined to be one of these in the DFISZERO macro] */
/* Format-dependent common tests: */
/* DFISZERO -- test for (any) zero */
/* DFISCCZERO -- test for coefficient continuation being zero */
/* DFISCC01 -- test for coefficient contains only 0s and 1s */
/* DFISINT -- test for finite and exponent q=0 */
/* DFISUINT01 -- test for sign=0, finite, exponent q=0, and */
/* MSD=0 or 1 */
/* ZEROWORD is also defined here. */
/* In DFISZERO the first test checks the least-significant word */
/* (most likely to be non-zero); the penultimate tests MSD and */
/* DPDs in the signword, and the final test excludes specials and */
/* MSD>7. DFISINT similarly has to allow for the two forms of */
/* MSD codes. DFISUINT01 only has to allow for one form of MSD */
/* code. */
#if DECPMAX==7
#define ZEROWORD SINGLEZERO
/* [test macros not needed except for Zero] */
#define DFISZERO(df) ((DFWORD(df, 0)&0x1c0fffff)==0 \
&& (DFWORD(df, 0)&0x60000000)!=0x60000000)
#elif DECPMAX==16
#define ZEROWORD DOUBLEZERO
#define DFISZERO(df) ((DFWORD(df, 1)==0 \
&& (DFWORD(df, 0)&0x1c03ffff)==0 \
&& (DFWORD(df, 0)&0x60000000)!=0x60000000))
#define DFISINT(df) ((DFWORD(df, 0)&0x63fc0000)==0x22380000 \
||(DFWORD(df, 0)&0x7bfc0000)==0x6a380000)
#define DFISUINT01(df) ((DFWORD(df, 0)&0xfbfc0000)==0x22380000)
#define DFISCCZERO(df) (DFWORD(df, 1)==0 \
&& (DFWORD(df, 0)&0x0003ffff)==0)
#define DFISCC01(df) ((DFWORD(df, 0)&~0xfffc9124)==0 \
&& (DFWORD(df, 1)&~0x49124491)==0)
#elif DECPMAX==34
#define ZEROWORD QUADZERO
#define DFISZERO(df) ((DFWORD(df, 3)==0 \
&& DFWORD(df, 2)==0 \
&& DFWORD(df, 1)==0 \
&& (DFWORD(df, 0)&0x1c003fff)==0 \
&& (DFWORD(df, 0)&0x60000000)!=0x60000000))
#define DFISINT(df) ((DFWORD(df, 0)&0x63ffc000)==0x22080000 \
||(DFWORD(df, 0)&0x7bffc000)==0x6a080000)
#define DFISUINT01(df) ((DFWORD(df, 0)&0xfbffc000)==0x22080000)
#define DFISCCZERO(df) (DFWORD(df, 3)==0 \
&& DFWORD(df, 2)==0 \
&& DFWORD(df, 1)==0 \
&& (DFWORD(df, 0)&0x00003fff)==0)
#define DFISCC01(df) ((DFWORD(df, 0)&~0xffffc912)==0 \
&& (DFWORD(df, 1)&~0x44912449)==0 \
&& (DFWORD(df, 2)&~0x12449124)==0 \
&& (DFWORD(df, 3)&~0x49124491)==0)
#endif
/* Macros to test if a certain 10 bits of a uInt or pair of uInts */
/* are a canonical declet [higher or lower bits are ignored]. */
/* declet is at offset 0 (from the right) in a uInt: */
#define CANONDPD(dpd) (((dpd)&0x300)==0 || ((dpd)&0x6e)!=0x6e)
/* declet is at offset k (a multiple of 2) in a uInt: */
#define CANONDPDOFF(dpd, k) (((dpd)&(0x300<<(k)))==0 \
|| ((dpd)&(((uInt)0x6e)<<(k)))!=(((uInt)0x6e)<<(k)))
/* declet is at offset k (a multiple of 2) in a pair of uInts: */
/* [the top 2 bits will always be in the more-significant uInt] */
#define CANONDPDTWO(hi, lo, k) (((hi)&(0x300>>(32-(k))))==0 \
|| ((hi)&(0x6e>>(32-(k))))!=(0x6e>>(32-(k))) \
|| ((lo)&(((uInt)0x6e)<<(k)))!=(((uInt)0x6e)<<(k)))
/* Macro to test whether a full-length (length DECPMAX) BCD8 */
/* coefficient is zero */
/* test just the LSWord first, then the remainder */
#if DECPMAX==7
#define ISCOEFFZERO(u) (UINTAT((u)+DECPMAX-4)==0 \
&& UINTAT((u)+DECPMAX-7)==0)
#elif DECPMAX==16
#define ISCOEFFZERO(u) (UINTAT((u)+DECPMAX-4)==0 \
&& (UINTAT((u)+DECPMAX-8)+UINTAT((u)+DECPMAX-12) \
+UINTAT((u)+DECPMAX-16))==0)
#elif DECPMAX==34
#define ISCOEFFZERO(u) (UINTAT((u)+DECPMAX-4)==0 \
&& (UINTAT((u)+DECPMAX-8) +UINTAT((u)+DECPMAX-12) \
+UINTAT((u)+DECPMAX-16)+UINTAT((u)+DECPMAX-20) \
+UINTAT((u)+DECPMAX-24)+UINTAT((u)+DECPMAX-28) \
+UINTAT((u)+DECPMAX-32)+USHORTAT((u)+DECPMAX-34))==0)
#endif
/* Macros and masks for the exponent continuation field and MSD */
/* Get the exponent continuation from a decFloat *df as an Int */
#define GETECON(df) ((Int)((DFWORD((df), 0)&0x03ffffff)>>(32-6-DECECONL)))
/* Ditto, from the next-wider format */
#define GETWECON(df) ((Int)((DFWWORD((df), 0)&0x03ffffff)>>(32-6-DECWECONL)))
/* Get the biased exponent similarly */
#define GETEXP(df) ((Int)(DECCOMBEXP[DFWORD((df), 0)>>26]+GETECON(df)))
/* Get the unbiased exponent similarly */
#define GETEXPUN(df) ((Int)GETEXP(df)-DECBIAS)
/* Get the MSD similarly (as uInt) */
#define GETMSD(df) (DECCOMBMSD[DFWORD((df), 0)>>26])
/* Compile-time computes of the exponent continuation field masks */
/* full exponent continuation field: */
#define ECONMASK ((0x03ffffff>>(32-6-DECECONL))<<(32-6-DECECONL))
/* same, not including its first digit (the qNaN/sNaN selector): */
#define ECONNANMASK ((0x01ffffff>>(32-6-DECECONL))<<(32-6-DECECONL))
/* Macros to decode the coefficient in a finite decFloat *df into */
/* a BCD string (uByte *bcdin) of length DECPMAX uBytes */
/* In-line sequence to convert 10 bits at right end of uInt dpd */
/* to three BCD8 digits starting at uByte u. Note that an extra */
/* byte is written to the right of the three digits because this */
/* moves four at a time for speed; the alternative macro moves */
/* exactly three bytes */
#define dpd2bcd8(u, dpd) { \
UINTAT(u)=UINTAT(&DPD2BCD8[((dpd)&0x3ff)*4]);}
#define dpd2bcd83(u, dpd) { \
*(u)=DPD2BCD8[((dpd)&0x3ff)*4]; \
*(u+1)=DPD2BCD8[((dpd)&0x3ff)*4+1]; \
*(u+2)=DPD2BCD8[((dpd)&0x3ff)*4+2];}
/* Decode the declets. After extracting each one, it is decoded */
/* to BCD8 using a table lookup (also used for variable-length */
/* decode). Each DPD decode is 3 bytes BCD8 plus a one-byte */
/* length which is not used, here). Fixed-length 4-byte moves */
/* are fast, however, almost everywhere, and so are used except */
/* for the final three bytes (to avoid overrun). The code below */
/* is 36 instructions for Doubles and about 70 for Quads, even */
/* on IA32. */
/* Two macros are defined for each format: */
/* GETCOEFF extracts the coefficient of the current format */
/* GETWCOEFF extracts the coefficient of the next-wider format. */
/* The latter is a copy of the next-wider GETCOEFF using DFWWORD. */
#if DECPMAX==7
#define GETCOEFF(df, bcd) { \
uInt sourhi=DFWORD(df, 0); \
*(bcd)=(uByte)DECCOMBMSD[sourhi>>26]; \
dpd2bcd8(bcd+1, sourhi>>10); \
dpd2bcd83(bcd+4, sourhi);}
#define GETWCOEFF(df, bcd) { \
uInt sourhi=DFWWORD(df, 0); \
uInt sourlo=DFWWORD(df, 1); \
*(bcd)=(uByte)DECCOMBMSD[sourhi>>26]; \
dpd2bcd8(bcd+1, sourhi>>8); \
dpd2bcd8(bcd+4, (sourhi<<2) | (sourlo>>30)); \
dpd2bcd8(bcd+7, sourlo>>20); \
dpd2bcd8(bcd+10, sourlo>>10); \
dpd2bcd83(bcd+13, sourlo);}
#elif DECPMAX==16
#define GETCOEFF(df, bcd) { \
uInt sourhi=DFWORD(df, 0); \
uInt sourlo=DFWORD(df, 1); \
*(bcd)=(uByte)DECCOMBMSD[sourhi>>26]; \
dpd2bcd8(bcd+1, sourhi>>8); \
dpd2bcd8(bcd+4, (sourhi<<2) | (sourlo>>30)); \
dpd2bcd8(bcd+7, sourlo>>20); \
dpd2bcd8(bcd+10, sourlo>>10); \
dpd2bcd83(bcd+13, sourlo);}
#define GETWCOEFF(df, bcd) { \
uInt sourhi=DFWWORD(df, 0); \
uInt sourmh=DFWWORD(df, 1); \
uInt sourml=DFWWORD(df, 2); \
uInt sourlo=DFWWORD(df, 3); \
*(bcd)=(uByte)DECCOMBMSD[sourhi>>26]; \
dpd2bcd8(bcd+1, sourhi>>4); \
dpd2bcd8(bcd+4, ((sourhi)<<6) | (sourmh>>26)); \
dpd2bcd8(bcd+7, sourmh>>16); \
dpd2bcd8(bcd+10, sourmh>>6); \
dpd2bcd8(bcd+13, ((sourmh)<<4) | (sourml>>28)); \
dpd2bcd8(bcd+16, sourml>>18); \
dpd2bcd8(bcd+19, sourml>>8); \
dpd2bcd8(bcd+22, ((sourml)<<2) | (sourlo>>30)); \
dpd2bcd8(bcd+25, sourlo>>20); \
dpd2bcd8(bcd+28, sourlo>>10); \
dpd2bcd83(bcd+31, sourlo);}
#elif DECPMAX==34
#define GETCOEFF(df, bcd) { \
uInt sourhi=DFWORD(df, 0); \
uInt sourmh=DFWORD(df, 1); \
uInt sourml=DFWORD(df, 2); \
uInt sourlo=DFWORD(df, 3); \
*(bcd)=(uByte)DECCOMBMSD[sourhi>>26]; \
dpd2bcd8(bcd+1, sourhi>>4); \
dpd2bcd8(bcd+4, ((sourhi)<<6) | (sourmh>>26)); \
dpd2bcd8(bcd+7, sourmh>>16); \
dpd2bcd8(bcd+10, sourmh>>6); \
dpd2bcd8(bcd+13, ((sourmh)<<4) | (sourml>>28)); \
dpd2bcd8(bcd+16, sourml>>18); \
dpd2bcd8(bcd+19, sourml>>8); \
dpd2bcd8(bcd+22, ((sourml)<<2) | (sourlo>>30)); \
dpd2bcd8(bcd+25, sourlo>>20); \
dpd2bcd8(bcd+28, sourlo>>10); \
dpd2bcd83(bcd+31, sourlo);}
#define GETWCOEFF(df, bcd) {??} /* [should never be used] */
#endif
/* Macros to decode the coefficient in a finite decFloat *df into */
/* a base-billion uInt array, with the least-significant */
/* 0-999999999 'digit' at offset 0. */
/* Decode the declets. After extracting each one, it is decoded */
/* to binary using a table lookup. Three tables are used; one */
/* the usual DPD to binary, the other two pre-multiplied by 1000 */
/* and 1000000 to avoid multiplication during decode. These */
/* tables can also be used for multiplying up the MSD as the DPD */
/* code for 0 through 9 is the identity. */
#define DPD2BIN0 DPD2BIN /* for prettier code */
#if DECPMAX==7
#define GETCOEFFBILL(df, buf) { \
uInt sourhi=DFWORD(df, 0); \
(buf)[0]=DPD2BIN0[sourhi&0x3ff] \
+DPD2BINK[(sourhi>>10)&0x3ff] \
+DPD2BINM[DECCOMBMSD[sourhi>>26]];}
#elif DECPMAX==16
#define GETCOEFFBILL(df, buf) { \
uInt sourhi, sourlo; \
sourlo=DFWORD(df, 1); \
(buf)[0]=DPD2BIN0[sourlo&0x3ff] \
+DPD2BINK[(sourlo>>10)&0x3ff] \
+DPD2BINM[(sourlo>>20)&0x3ff]; \
sourhi=DFWORD(df, 0); \
(buf)[1]=DPD2BIN0[((sourhi<<2) | (sourlo>>30))&0x3ff] \
+DPD2BINK[(sourhi>>8)&0x3ff] \
+DPD2BINM[DECCOMBMSD[sourhi>>26]];}
#elif DECPMAX==34
#define GETCOEFFBILL(df, buf) { \
uInt sourhi, sourmh, sourml, sourlo; \
sourlo=DFWORD(df, 3); \
(buf)[0]=DPD2BIN0[sourlo&0x3ff] \
+DPD2BINK[(sourlo>>10)&0x3ff] \
+DPD2BINM[(sourlo>>20)&0x3ff]; \
sourml=DFWORD(df, 2); \
(buf)[1]=DPD2BIN0[((sourml<<2) | (sourlo>>30))&0x3ff] \
+DPD2BINK[(sourml>>8)&0x3ff] \
+DPD2BINM[(sourml>>18)&0x3ff]; \
sourmh=DFWORD(df, 1); \
(buf)[2]=DPD2BIN0[((sourmh<<4) | (sourml>>28))&0x3ff] \
+DPD2BINK[(sourmh>>6)&0x3ff] \
+DPD2BINM[(sourmh>>16)&0x3ff]; \
sourhi=DFWORD(df, 0); \
(buf)[3]=DPD2BIN0[((sourhi<<6) | (sourmh>>26))&0x3ff] \
+DPD2BINK[(sourhi>>4)&0x3ff] \
+DPD2BINM[DECCOMBMSD[sourhi>>26]];}
#endif
/* Macros to decode the coefficient in a finite decFloat *df into */
/* a base-thousand uInt array, with the least-significant 0-999 */
/* 'digit' at offset 0. */
/* Decode the declets. After extracting each one, it is decoded */
/* to binary using a table lookup. */
#if DECPMAX==7
#define GETCOEFFTHOU(df, buf) { \
uInt sourhi=DFWORD(df, 0); \
(buf)[0]=DPD2BIN[sourhi&0x3ff]; \
(buf)[1]=DPD2BIN[(sourhi>>10)&0x3ff]; \
(buf)[2]=DECCOMBMSD[sourhi>>26];}
#elif DECPMAX==16
#define GETCOEFFTHOU(df, buf) { \
uInt sourhi, sourlo; \
sourlo=DFWORD(df, 1); \
(buf)[0]=DPD2BIN[sourlo&0x3ff]; \
(buf)[1]=DPD2BIN[(sourlo>>10)&0x3ff]; \
(buf)[2]=DPD2BIN[(sourlo>>20)&0x3ff]; \
sourhi=DFWORD(df, 0); \
(buf)[3]=DPD2BIN[((sourhi<<2) | (sourlo>>30))&0x3ff]; \
(buf)[4]=DPD2BIN[(sourhi>>8)&0x3ff]; \
(buf)[5]=DECCOMBMSD[sourhi>>26];}
#elif DECPMAX==34
#define GETCOEFFTHOU(df, buf) { \
uInt sourhi, sourmh, sourml, sourlo; \
sourlo=DFWORD(df, 3); \
(buf)[0]=DPD2BIN[sourlo&0x3ff]; \
(buf)[1]=DPD2BIN[(sourlo>>10)&0x3ff]; \
(buf)[2]=DPD2BIN[(sourlo>>20)&0x3ff]; \
sourml=DFWORD(df, 2); \
(buf)[3]=DPD2BIN[((sourml<<2) | (sourlo>>30))&0x3ff]; \
(buf)[4]=DPD2BIN[(sourml>>8)&0x3ff]; \
(buf)[5]=DPD2BIN[(sourml>>18)&0x3ff]; \
sourmh=DFWORD(df, 1); \
(buf)[6]=DPD2BIN[((sourmh<<4) | (sourml>>28))&0x3ff]; \
(buf)[7]=DPD2BIN[(sourmh>>6)&0x3ff]; \
(buf)[8]=DPD2BIN[(sourmh>>16)&0x3ff]; \
sourhi=DFWORD(df, 0); \
(buf)[9]=DPD2BIN[((sourhi<<6) | (sourmh>>26))&0x3ff]; \
(buf)[10]=DPD2BIN[(sourhi>>4)&0x3ff]; \
(buf)[11]=DECCOMBMSD[sourhi>>26];}
#endif
/* Set a decFloat to the maximum positive finite number (Nmax) */
#if DECPMAX==7
#define DFSETNMAX(df) \
{DFWORD(df, 0)=0x77f3fcff;}
#elif DECPMAX==16
#define DFSETNMAX(df) \
{DFWORD(df, 0)=0x77fcff3f; \
DFWORD(df, 1)=0xcff3fcff;}
#elif DECPMAX==34
#define DFSETNMAX(df) \
{DFWORD(df, 0)=0x77ffcff3; \
DFWORD(df, 1)=0xfcff3fcf; \
DFWORD(df, 2)=0xf3fcff3f; \
DFWORD(df, 3)=0xcff3fcff;}
#endif
/* [end of format-dependent macros and constants] */
#endif
#else #else
#error decNumberLocal included more than once #error decNumberLocal included more than once
#endif #endif
#if !defined(DECNUMBERSYMBOLS)
#define DECNUMBERSYMBOLS
#ifdef IN_LIBGCC2
#define decNumberAbs __decNumberAbs
#define decNumberAdd __decNumberAdd
#define decNumberAnd __decNumberAnd
#define decNumberClass __decNumberClass
#define decNumberClassToString __decNumberClassToString
#define decNumberCompare __decNumberCompare
#define decNumberCompareSignal __decNumberCompareSignal
#define decNumberCompareTotal __decNumberCompareTotal
#define decNumberCompareTotalMag __decNumberCompareTotalMag
#define decNumberCopy __decNumberCopy
#define decNumberCopyAbs __decNumberCopyAbs
#define decNumberCopyNegate __decNumberCopyNegate
#define decNumberCopySign __decNumberCopySign
#define decNumberDivide __decNumberDivide
#define decNumberDivideInteger __decNumberDivideInteger
#define decNumberExp __decNumberExp
#define decNumberFMA __decNumberFMA
#define decNumberFromInt32 __decNumberFromInt32
#define decNumberFromString __decNumberFromString
#define decNumberFromUInt32 __decNumberFromUInt32
#define decNumberGetBCD __decNumberGetBCD
#define decNumberInvert __decNumberInvert
#define decNumberIsNormal __decNumberIsNormal
#define decNumberIsSubnormal __decNumberIsSubnormal
#define decNumberLn __decNumberLn
#define decNumberLog10 __decNumberLog10
#define decNumberLogB __decNumberLogB
#define decNumberMax __decNumberMax
#define decNumberMaxMag __decNumberMaxMag
#define decNumberMin __decNumberMin
#define decNumberMinMag __decNumberMinMag
#define decNumberMinus __decNumberMinus
#define decNumberMultiply __decNumberMultiply
#define decNumberNextMinus __decNumberNextMinus
#define decNumberNextPlus __decNumberNextPlus
#define decNumberNextToward __decNumberNextToward
#define decNumberNormalize __decNumberNormalize
#define decNumberOr __decNumberOr
#define decNumberPlus __decNumberPlus
#define decNumberPower __decNumberPower
#define decNumberQuantize __decNumberQuantize
#define decNumberReduce __decNumberReduce
#define decNumberRemainder __decNumberRemainder
#define decNumberRemainderNear __decNumberRemainderNear
#define decNumberRescale __decNumberRescale
#define decNumberRotate __decNumberRotate
#define decNumberSameQuantum __decNumberSameQuantum
#define decNumberScaleB __decNumberScaleB
#define decNumberSetBCD __decNumberSetBCD
#define decNumberShift __decNumberShift
#define decNumberSquareRoot __decNumberSquareRoot
#define decNumberSubtract __decNumberSubtract
#define decNumberToEngString __decNumberToEngString
#define decNumberToInt32 __decNumberToInt32
#define decNumberToIntegralExact __decNumberToIntegralExact
#define decNumberToIntegralValue __decNumberToIntegralValue
#define decNumberToString __decNumberToString
#define decNumberToUInt32 __decNumberToUInt32
#define decNumberTrim __decNumberTrim
#define decNumberVersion __decNumberVersion
#define decNumberXor __decNumberXor
#define decNumberZero __decNumberZero
#endif
#endif
/* Packed decimal conversion module for the decNumber C Library.
Copyright (C) 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
This file is part of GCC.
GCC 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 2, or (at your option) any later
version.
In addition to the permissions in the GNU General Public License,
the Free Software Foundation gives you unlimited permission to link
the compiled version of this file into combinations with other
programs, and to distribute those combinations without any
restriction coming from the use of this file. (The General Public
License restrictions do apply in other respects; for example, they
cover modification of the file, and distribution when not linked
into a combine executable.)
GCC 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.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
/* ------------------------------------------------------------------ */
/* Packed Decimal conversion module */
/* ------------------------------------------------------------------ */
/* This module comprises the routines for Packed Decimal format */
/* numbers. Conversions are supplied to and from decNumber, which in */
/* turn supports: */
/* conversions to and from string */
/* arithmetic routines */
/* utilities. */
/* Conversions from decNumber to and from densely packed decimal */
/* formats are provided by the decimal32 through decimal128 modules. */
/* ------------------------------------------------------------------ */
#include <string.h> /* for NULL */
#include "decNumber.h" /* base number library */
#include "decPacked.h" /* packed decimal */
#include "decNumberLocal.h" /* decNumber local types, etc. */
/* ------------------------------------------------------------------ */
/* decPackedFromNumber -- convert decNumber to BCD Packed Decimal */
/* */
/* bcd is the BCD bytes */
/* length is the length of the BCD array */
/* scale is the scale result */
/* dn is the decNumber */
/* returns bcd, or NULL if error */
/* */
/* The number is converted to a BCD packed decimal byte array, */
/* right aligned in the bcd array, whose length is indicated by the */
/* second parameter. The final 4-bit nibble in the array will be a */
/* sign nibble, C (1100) for + and D (1101) for -. Unused bytes and */
/* nibbles to the left of the number are set to 0. */
/* */
/* scale is set to the scale of the number (this is the exponent, */
/* negated). To force the number to a specified scale, first use the */
/* decNumberRescale routine, which will round and change the exponent */
/* as necessary. */
/* */
/* If there is an error (that is, the decNumber has too many digits */
/* to fit in length bytes, or it is a NaN or Infinity), NULL is */
/* returned and the bcd and scale results are unchanged. Otherwise */
/* bcd is returned. */
/* ------------------------------------------------------------------ */
uByte * decPackedFromNumber(uByte *bcd, Int length, Int *scale,
const decNumber *dn) {
const Unit *up=dn->lsu; /* Unit array pointer */
uByte obyte, *out; /* current output byte, and where it goes */
Int indigs=dn->digits; /* digits processed */
uInt cut=DECDPUN; /* downcounter per Unit */
uInt u=*up; /* work */
uInt nib; /* .. */
#if DECDPUN<=4
uInt temp; /* .. */
#endif
if (dn->digits>length*2-1 /* too long .. */
||(dn->bits & DECSPECIAL)) return NULL; /* .. or special -- hopeless */
if (dn->bits&DECNEG) obyte=DECPMINUS; /* set the sign .. */
else obyte=DECPPLUS;
*scale=-dn->exponent; /* .. and scale */
/* loop from lowest (rightmost) byte */
out=bcd+length-1; /* -> final byte */
for (; out>=bcd; out--) {
if (indigs>0) {
if (cut==0) {
up++;
u=*up;
cut=DECDPUN;
}
#if DECDPUN<=4
temp=(u*6554)>>16; /* fast /10 */
nib=u-X10(temp);
u=temp;
#else
nib=u%10; /* cannot use *6554 trick :-( */
u=u/10;
#endif
obyte|=(nib<<4);
indigs--;
cut--;
}
*out=obyte;
obyte=0; /* assume 0 */
if (indigs>0) {
if (cut==0) {
up++;
u=*up;
cut=DECDPUN;
}
#if DECDPUN<=4
temp=(u*6554)>>16; /* as above */
obyte=(uByte)(u-X10(temp));
u=temp;
#else
obyte=(uByte)(u%10);
u=u/10;
#endif
indigs--;
cut--;
}
} /* loop */
return bcd;
} /* decPackedFromNumber */
/* ------------------------------------------------------------------ */
/* decPackedToNumber -- convert BCD Packed Decimal to a decNumber */
/* */
/* bcd is the BCD bytes */
/* length is the length of the BCD array */
/* scale is the scale associated with the BCD integer */
/* dn is the decNumber [with space for length*2 digits] */
/* returns dn, or NULL if error */
/* */
/* The BCD packed decimal byte array, together with an associated */
/* scale, is converted to a decNumber. The BCD array is assumed full */
/* of digits, and must be ended by a 4-bit sign nibble in the least */
/* significant four bits of the final byte. */
/* */
/* The scale is used (negated) as the exponent of the decNumber. */
/* Note that zeros may have a sign and/or a scale. */
/* */
/* The decNumber structure is assumed to have sufficient space to */
/* hold the converted number (that is, up to length*2-1 digits), so */
/* no error is possible unless the adjusted exponent is out of range, */
/* no sign nibble was found, or a sign nibble was found before the */
/* final nibble. In these error cases, NULL is returned and the */
/* decNumber will be 0. */
/* ------------------------------------------------------------------ */
decNumber * decPackedToNumber(const uByte *bcd, Int length,
const Int *scale, decNumber *dn) {
const uByte *last=bcd+length-1; /* -> last byte */
const uByte *first; /* -> first non-zero byte */
uInt nib; /* work nibble */
Unit *up=dn->lsu; /* output pointer */
Int digits; /* digits count */
Int cut=0; /* phase of output */
decNumberZero(dn); /* default result */
last=&bcd[length-1];
nib=*last & 0x0f; /* get the sign */
if (nib==DECPMINUS || nib==DECPMINUSALT) dn->bits=DECNEG;
else if (nib<=9) return NULL; /* not a sign nibble */
/* skip leading zero bytes [final byte is always non-zero, due to sign] */
for (first=bcd; *first==0;) first++;
digits=(last-first)*2+1; /* calculate digits .. */
if ((*first & 0xf0)==0) digits--; /* adjust for leading zero nibble */
if (digits!=0) dn->digits=digits; /* count of actual digits [if 0, */
/* leave as 1] */
/* check the adjusted exponent; note that scale could be unbounded */
dn->exponent=-*scale; /* set the exponent */
if (*scale>=0) { /* usual case */
if ((dn->digits-*scale-1)<-DECNUMMAXE) { /* underflow */
decNumberZero(dn);
return NULL;}
}
else { /* -ve scale; +ve exponent */
/* need to be careful to avoid wrap, here, also BADINT case */
if ((*scale<-DECNUMMAXE) /* overflow even without digits */
|| ((dn->digits-*scale-1)>DECNUMMAXE)) { /* overflow */
decNumberZero(dn);
return NULL;}
}
if (digits==0) return dn; /* result was zero */
/* copy the digits to the number's units, starting at the lsu */
/* [unrolled] */
for (;;) { /* forever */
/* left nibble first */
nib=(unsigned)(*last & 0xf0)>>4;
/* got a digit, in nib */
if (nib>9) {decNumberZero(dn); return NULL;}
if (cut==0) *up=(Unit)nib;
else *up=(Unit)(*up+nib*DECPOWERS[cut]);
digits--;
if (digits==0) break; /* got them all */
cut++;
if (cut==DECDPUN) {
up++;
cut=0;
}
last--; /* ready for next */
nib=*last & 0x0f; /* get right nibble */
if (nib>9) {decNumberZero(dn); return NULL;}
/* got a digit, in nib */
if (cut==0) *up=(Unit)nib;
else *up=(Unit)(*up+nib*DECPOWERS[cut]);
digits--;
if (digits==0) break; /* got them all */
cut++;
if (cut==DECDPUN) {
up++;
cut=0;
}
} /* forever */
return dn;
} /* decPackedToNumber */
/* Packed decimal conversion module header for the decNumber C Library.
Copyright (C) 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
This file is part of GCC.
GCC 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 2, or (at your option) any later
version.
In addition to the permissions in the GNU General Public License,
the Free Software Foundation gives you unlimited permission to link
the compiled version of this file into combinations with other
programs, and to distribute those combinations without any
restriction coming from the use of this file. (The General Public
License restrictions do apply in other respects; for example, they
cover modification of the file, and distribution when not linked
into a combine executable.)
GCC 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.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
/* ------------------------------------------------------------------ */
/* Packed Decimal conversion module header */
/* ------------------------------------------------------------------ */
#if !defined(DECPACKED)
#define DECPACKED
#define DECPNAME "decPacked" /* Short name */
#define DECPFULLNAME "Packed Decimal conversions" /* Verbose name */
#define DECPAUTHOR "Mike Cowlishaw" /* Who to blame */
#define DECPACKED_DefP 32 /* default precision */
#ifndef DECNUMDIGITS
#define DECNUMDIGITS DECPACKED_DefP /* size if not already defined*/
#endif
#include "decNumber.h" /* context and number library */
/* Sign nibble constants */
#if !defined(DECPPLUSALT)
#define DECPPLUSALT 0x0A /* alternate plus nibble */
#define DECPMINUSALT 0x0B /* alternate minus nibble */
#define DECPPLUS 0x0C /* preferred plus nibble */
#define DECPMINUS 0x0D /* preferred minus nibble */
#define DECPPLUSALT2 0x0E /* alternate plus nibble */
#define DECPUNSIGNED 0x0F /* alternate plus nibble (unsigned) */
#endif
/* ---------------------------------------------------------------- */
/* decPacked public routines */
/* ---------------------------------------------------------------- */
#include "decPackedSymbols.h"
/* Conversions */
uint8_t * decPackedFromNumber(uint8_t *, int32_t, int32_t *,
const decNumber *);
decNumber * decPackedToNumber(const uint8_t *, int32_t, const int32_t *,
decNumber *);
#endif
#if !defined(DECPACKEDSYMBOLS)
#define DECPACKEDSYMBOLS
#ifdef IN_LIBGCC2
#define decPackedFromNumber __decPackedFromNumber
#define decPackedToNumber __decPackedToNumber
#endif
#endif
/* decQuad module for the decNumber C Library.
Copyright (C) 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
This file is part of GCC.
GCC 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 2, or (at your option) any later
version.
In addition to the permissions in the GNU General Public License,
the Free Software Foundation gives you unlimited permission to link
the compiled version of this file into combinations with other
programs, and to distribute those combinations without any
restriction coming from the use of this file. (The General Public
License restrictions do apply in other respects; for example, they
cover modification of the file, and distribution when not linked
into a combine executable.)
GCC 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.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
/* ------------------------------------------------------------------ */
/* decQuad.c -- decQuad operations module */
/* ------------------------------------------------------------------ */
/* This module comprises decQuad operations (including conversions) */
/* ------------------------------------------------------------------ */
#include "decContext.h" /* public includes */
#include "decQuad.h" /* .. */
/* Constant mappings for shared code */
#define DECPMAX DECQUAD_Pmax
#define DECEMIN DECQUAD_Emin
#define DECEMAX DECQUAD_Emax
#define DECEMAXD DECQUAD_EmaxD
#define DECBYTES DECQUAD_Bytes
#define DECSTRING DECQUAD_String
#define DECECONL DECQUAD_EconL
#define DECBIAS DECQUAD_Bias
#define DECLETS DECQUAD_Declets
#define DECQTINY (-DECQUAD_Bias)
/* Type and function mappings for shared code */
#define decFloat decQuad /* Type name */
/* Utilities and conversions (binary results, extractors, etc.) */
#define decFloatFromBCD decQuadFromBCD
#define decFloatFromInt32 decQuadFromInt32
#define decFloatFromPacked decQuadFromPacked
#define decFloatFromString decQuadFromString
#define decFloatFromUInt32 decQuadFromUInt32
#define decFloatFromWider decQuadFromWider
#define decFloatGetCoefficient decQuadGetCoefficient
#define decFloatGetExponent decQuadGetExponent
#define decFloatSetCoefficient decQuadSetCoefficient
#define decFloatSetExponent decQuadSetExponent
#define decFloatShow decQuadShow
#define decFloatToBCD decQuadToBCD
#define decFloatToEngString decQuadToEngString
#define decFloatToInt32 decQuadToInt32
#define decFloatToInt32Exact decQuadToInt32Exact
#define decFloatToPacked decQuadToPacked
#define decFloatToString decQuadToString
#define decFloatToUInt32 decQuadToUInt32
#define decFloatToUInt32Exact decQuadToUInt32Exact
#define decFloatToWider decQuadToWider
#define decFloatZero decQuadZero
/* Computational (result is a decFloat) */
#define decFloatAbs decQuadAbs
#define decFloatAdd decQuadAdd
#define decFloatAnd decQuadAnd
#define decFloatDivide decQuadDivide
#define decFloatDivideInteger decQuadDivideInteger
#define decFloatFMA decQuadFMA
#define decFloatInvert decQuadInvert
#define decFloatLogB decQuadLogB
#define decFloatMax decQuadMax
#define decFloatMaxMag decQuadMaxMag
#define decFloatMin decQuadMin
#define decFloatMinMag decQuadMinMag
#define decFloatMinus decQuadMinus
#define decFloatMultiply decQuadMultiply
#define decFloatNextMinus decQuadNextMinus
#define decFloatNextPlus decQuadNextPlus
#define decFloatNextToward decQuadNextToward
#define decFloatOr decQuadOr
#define decFloatPlus decQuadPlus
#define decFloatQuantize decQuadQuantize
#define decFloatReduce decQuadReduce
#define decFloatRemainder decQuadRemainder
#define decFloatRemainderNear decQuadRemainderNear
#define decFloatRotate decQuadRotate
#define decFloatScaleB decQuadScaleB
#define decFloatShift decQuadShift
#define decFloatSubtract decQuadSubtract
#define decFloatToIntegralValue decQuadToIntegralValue
#define decFloatToIntegralExact decQuadToIntegralExact
#define decFloatXor decQuadXor
/* Comparisons */
#define decFloatCompare decQuadCompare
#define decFloatCompareSignal decQuadCompareSignal
#define decFloatCompareTotal decQuadCompareTotal
#define decFloatCompareTotalMag decQuadCompareTotalMag
/* Copies */
#define decFloatCanonical decQuadCanonical
#define decFloatCopy decQuadCopy
#define decFloatCopyAbs decQuadCopyAbs
#define decFloatCopyNegate decQuadCopyNegate
#define decFloatCopySign decQuadCopySign
/* Non-computational */
#define decFloatClass decQuadClass
#define decFloatClassString decQuadClassString
#define decFloatDigits decQuadDigits
#define decFloatIsCanonical decQuadIsCanonical
#define decFloatIsFinite decQuadIsFinite
#define decFloatIsInfinite decQuadIsInfinite
#define decFloatIsInteger decQuadIsInteger
#define decFloatIsNaN decQuadIsNaN
#define decFloatIsNormal decQuadIsNormal
#define decFloatIsSignaling decQuadIsSignaling
#define decFloatIsSignalling decQuadIsSignalling
#define decFloatIsSigned decQuadIsSigned
#define decFloatIsSubnormal decQuadIsSubnormal
#define decFloatIsZero decQuadIsZero
#define decFloatRadix decQuadRadix
#define decFloatSameQuantum decQuadSameQuantum
#define decFloatVersion decQuadVersion
#include "decNumberLocal.h" /* local includes (need DECPMAX) */
#include "decCommon.c" /* non-arithmetic decFloat routines */
#include "decBasic.c" /* basic formats routines */
/* decQuad module header for the decNumber C Library.
Copyright (C) 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
This file is part of GCC.
GCC 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 2, or (at your option) any later
version.
In addition to the permissions in the GNU General Public License,
the Free Software Foundation gives you unlimited permission to link
the compiled version of this file into combinations with other
programs, and to distribute those combinations without any
restriction coming from the use of this file. (The General Public
License restrictions do apply in other respects; for example, they
cover modification of the file, and distribution when not linked
into a combine executable.)
GCC 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.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
/* ------------------------------------------------------------------ */
/* decQuad.h -- Decimal 128-bit format module header */
/* ------------------------------------------------------------------ */
/* Please see decFloats.h for an overview and documentation details. */
/* ------------------------------------------------------------------ */
/* This include file is always included by decSingle and decDouble, */
/* and therefore also holds useful constants used by all three. */
#if !defined(DECQUAD)
#define DECQUAD
#define DECQUADNAME "decimalQuad" /* Short name */
#define DECQUADTITLE "Decimal 128-bit datum" /* Verbose name */
#define DECQUADAUTHOR "Mike Cowlishaw" /* Who to blame */
/* parameters for decQuads */
#define DECQUAD_Bytes 16 /* length */
#define DECQUAD_Pmax 34 /* maximum precision (digits) */
#define DECQUAD_Emin -6143 /* minimum adjusted exponent */
#define DECQUAD_Emax 6144 /* maximum adjusted exponent */
#define DECQUAD_EmaxD 4 /* maximum exponent digits */
#define DECQUAD_Bias 6176 /* bias for the exponent */
#define DECQUAD_String 43 /* maximum string length, +1 */
#define DECQUAD_EconL 12 /* exponent continuation length */
#define DECQUAD_Declets 11 /* count of declets */
/* highest biased exponent (Elimit-1) */
#define DECQUAD_Ehigh (DECQUAD_Emax + DECQUAD_Bias - (DECQUAD_Pmax-1))
/* Required include */
#include "decContext.h"
/* The decQuad decimal 128-bit type, accessible by bytes */
typedef struct {
uint8_t bytes[DECQUAD_Bytes]; /* fields: 1, 5, 12, 110 bits */
} decQuad;
/* ---------------------------------------------------------------- */
/* Shared constants */
/* ---------------------------------------------------------------- */
/* sign and special values [top 32-bits; last two bits are don't-care
for Infinity on input, last bit don't-care for NaNs] */
#define DECFLOAT_Sign 0x80000000 /* 1 00000 00 Sign */
#define DECFLOAT_NaN 0x7c000000 /* 0 11111 00 NaN generic */
#define DECFLOAT_qNaN 0x7c000000 /* 0 11111 00 qNaN */
#define DECFLOAT_sNaN 0x7e000000 /* 0 11111 10 sNaN */
#define DECFLOAT_Inf 0x78000000 /* 0 11110 00 Infinity */
#define DECFLOAT_MinSp 0x78000000 /* minimum special value */
/* [specials are all >=MinSp] */
/* Sign nibble constants */
#if !defined(DECPPLUSALT)
#define DECPPLUSALT 0x0A /* alternate plus nibble */
#define DECPMINUSALT 0x0B /* alternate minus nibble */
#define DECPPLUS 0x0C /* preferred plus nibble */
#define DECPMINUS 0x0D /* preferred minus nibble */
#define DECPPLUSALT2 0x0E /* alternate plus nibble */
#define DECPUNSIGNED 0x0F /* alternate plus nibble (unsigned) */
#endif
/* ---------------------------------------------------------------- */
/* Routines -- implemented as decFloat routines in common files */
/* ---------------------------------------------------------------- */
#include "decQuadSymbols.h"
/* Utilities and conversions, extractors, etc.) */
extern decQuad * decQuadFromBCD(decQuad *, int32_t, const uint8_t *, int32_t);
extern decQuad * decQuadFromInt32(decQuad *, int32_t);
extern decQuad * decQuadFromPacked(decQuad *, int32_t, const uint8_t *);
extern decQuad * decQuadFromString(decQuad *, const char *, decContext *);
extern decQuad * decQuadFromUInt32(decQuad *, uint32_t);
extern int32_t decQuadGetCoefficient(const decQuad *, uint8_t *);
extern int32_t decQuadGetExponent(const decQuad *);
extern decQuad * decQuadSetCoefficient(decQuad *, const uint8_t *, int32_t);
extern decQuad * decQuadSetExponent(decQuad *, decContext *, int32_t);
extern void decQuadShow(const decQuad *, const char *);
extern int32_t decQuadToBCD(const decQuad *, int32_t *, uint8_t *);
extern char * decQuadToEngString(const decQuad *, char *);
extern int32_t decQuadToInt32(const decQuad *, decContext *, enum rounding);
extern int32_t decQuadToInt32Exact(const decQuad *, decContext *, enum rounding);
extern int32_t decQuadToPacked(const decQuad *, int32_t *, uint8_t *);
extern char * decQuadToString(const decQuad *, char *);
extern uint32_t decQuadToUInt32(const decQuad *, decContext *, enum rounding);
extern uint32_t decQuadToUInt32Exact(const decQuad *, decContext *, enum rounding);
extern decQuad * decQuadZero(decQuad *);
/* Computational (result is a decQuad) */
extern decQuad * decQuadAbs(decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadAdd(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadAnd(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadDivide(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadDivideInteger(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadFMA(decQuad *, const decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadInvert(decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadLogB(decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadMax(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadMaxMag(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadMin(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadMinMag(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadMinus(decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadMultiply(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadNextMinus(decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadNextPlus(decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadNextToward(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadOr(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadPlus(decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadQuantize(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadReduce(decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadRemainder(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadRemainderNear(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadRotate(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadScaleB(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadShift(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadSubtract(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadToIntegralValue(decQuad *, const decQuad *, decContext *, enum rounding);
extern decQuad * decQuadToIntegralExact(decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadXor(decQuad *, const decQuad *, const decQuad *, decContext *);
/* Comparisons */
extern decQuad * decQuadCompare(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadCompareSignal(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadCompareTotal(decQuad *, const decQuad *, const decQuad *);
extern decQuad * decQuadCompareTotalMag(decQuad *, const decQuad *, const decQuad *);
/* Copies */
extern decQuad * decQuadCanonical(decQuad *, const decQuad *);
extern decQuad * decQuadCopy(decQuad *, const decQuad *);
extern decQuad * decQuadCopyAbs(decQuad *, const decQuad *);
extern decQuad * decQuadCopyNegate(decQuad *, const decQuad *);
extern decQuad * decQuadCopySign(decQuad *, const decQuad *, const decQuad *);
/* Non-computational */
extern enum decClass decQuadClass(const decQuad *);
extern const char * decQuadClassString(const decQuad *);
extern uint32_t decQuadDigits(const decQuad *);
extern uint32_t decQuadIsCanonical(const decQuad *);
extern uint32_t decQuadIsFinite(const decQuad *);
extern uint32_t decQuadIsInteger(const decQuad *);
extern uint32_t decQuadIsInfinite(const decQuad *);
extern uint32_t decQuadIsNaN(const decQuad *);
extern uint32_t decQuadIsNormal(const decQuad *);
extern uint32_t decQuadIsSignaling(const decQuad *);
extern uint32_t decQuadIsSignalling(const decQuad *);
extern uint32_t decQuadIsSigned(const decQuad *);
extern uint32_t decQuadIsSubnormal(const decQuad *);
extern uint32_t decQuadIsZero(const decQuad *);
extern uint32_t decQuadRadix(const decQuad *);
extern uint32_t decQuadSameQuantum(const decQuad *, const decQuad *);
extern const char * decQuadVersion(void);
/* decNumber conversions; these are implemented as macros so as not */
/* to force a dependency on decimal128 and decNumber in decQuad. */
#define decQuadToNumber(dq, dn) decimal128ToNumber((decimal128 *)(dq), dn)
#define decQuadFromNumber(dq, dn, set) (decQuad *)decimal128FromNumber((decimal128 *)(dq), dn, set)
#endif
#if !defined(DECQUADSYMBOLS)
#define DECQUADSYMBOLS
#ifdef IN_LIBGCC2
#define decQuadAbs __decQuadAbs
#define decQuadAdd __decQuadAdd
#define decQuadAnd __decQuadAnd
#define decQuadCanonical __decQuadCanonical
#define decQuadClass __decQuadClass
#define decQuadClassString __decQuadClassString
#define decQuadCompare __decQuadCompare
#define decQuadCompareSignal __decQuadCompareSignal
#define decQuadCompareTotal __decQuadCompareTotal
#define decQuadCompareTotalMag __decQuadCompareTotalMag
#define decQuadCopy __decQuadCopy
#define decQuadCopyAbs __decQuadCopyAbs
#define decQuadCopyNegate __decQuadCopyNegate
#define decQuadCopySign __decQuadCopySign
#define decQuadDigits __decQuadDigits
#define decQuadDivide __decQuadDivide
#define decQuadDivideInteger __decQuadDivideInteger
#define decQuadFMA __decQuadFMA
#define decQuadFromBCD __decQuadFromBCD
#define decQuadFromInt32 __decQuadFromInt32
#define decQuadFromPacked __decQuadFromPacked
#define decQuadFromString __decQuadFromString
#define decQuadFromUInt32 __decQuadFromUInt32
#define decQuadGetCoefficient __decQuadGetCoefficient
#define decQuadGetExponent __decQuadGetExponent
#define decQuadInvert __decQuadInvert
#define decQuadIsCanonical __decQuadIsCanonical
#define decQuadIsFinite __decQuadIsFinite
#define decQuadIsInfinite __decQuadIsInfinite
#define decQuadIsInteger __decQuadIsInteger
#define decQuadIsNaN __decQuadIsNaN
#define decQuadIsNormal __decQuadIsNormal
#define decQuadIsSignaling __decQuadIsSignaling
#define decQuadIsSignalling __decQuadIsSignalling
#define decQuadIsSigned __decQuadIsSigned
#define decQuadIsSubnormal __decQuadIsSubnormal
#define decQuadIsZero __decQuadIsZero
#define decQuadLogB __decQuadLogB
#define decQuadMax __decQuadMax
#define decQuadMaxMag __decQuadMaxMag
#define decQuadMin __decQuadMin
#define decQuadMinMag __decQuadMinMag
#define decQuadMinus __decQuadMinus
#define decQuadMultiply __decQuadMultiply
#define decQuadNextMinus __decQuadNextMinus
#define decQuadNextPlus __decQuadNextPlus
#define decQuadNextToward __decQuadNextToward
#define decQuadOr __decQuadOr
#define decQuadPlus __decQuadPlus
#define decQuadQuantize __decQuadQuantize
#define decQuadRadix __decQuadRadix
#define decQuadReduce __decQuadReduce
#define decQuadRemainder __decQuadRemainder
#define decQuadRemainderNear __decQuadRemainderNear
#define decQuadRotate __decQuadRotate
#define decQuadSameQuantum __decQuadSameQuantum
#define decQuadScaleB __decQuadScaleB
#define decQuadSetCoefficient __decQuadSetCoefficient
#define decQuadSetExponent __decQuadSetExponent
#define decQuadShift __decQuadShift
#define decQuadShow __decQuadShow
#define decQuadSubtract __decQuadSubtract
#define decQuadToBCD __decQuadToBCD
#define decQuadToEngString __decQuadToEngString
#define decQuadToInt32 __decQuadToInt32
#define decQuadToInt32Exact __decQuadToInt32Exact
#define decQuadToIntegralExact __decQuadToIntegralExact
#define decQuadToIntegralValue __decQuadToIntegralValue
#define decQuadToPacked __decQuadToPacked
#define decQuadToString __decQuadToString
#define decQuadToUInt32 __decQuadToUInt32
#define decQuadToUInt32Exact __decQuadToUInt32Exact
#define decQuadVersion __decQuadVersion
#define decQuadXor __decQuadXor
#define decQuadZero __decQuadZero
#endif
#endif
/* decSingle module for the decNumber C Library.
Copyright (C) 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
This file is part of GCC.
GCC 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 2, or (at your option) any later
version.
In addition to the permissions in the GNU General Public License,
the Free Software Foundation gives you unlimited permission to link
the compiled version of this file into combinations with other
programs, and to distribute those combinations without any
restriction coming from the use of this file. (The General Public
License restrictions do apply in other respects; for example, they
cover modification of the file, and distribution when not linked
into a combine executable.)
GCC 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.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
/* ------------------------------------------------------------------ */
/* decSingle.c -- decSingle operations module */
/* ------------------------------------------------------------------ */
/* This module comprises decSingle operations (including conversions) */
/* ------------------------------------------------------------------ */
#include "decContext.h" /* public includes */
#include "decSingle.h" /* public includes */
/* Constant mappings for shared code */
#define DECPMAX DECSINGLE_Pmax
#define DECEMIN DECSINGLE_Emin
#define DECEMAX DECSINGLE_Emax
#define DECEMAXD DECSINGLE_EmaxD
#define DECBYTES DECSINGLE_Bytes
#define DECSTRING DECSINGLE_String
#define DECECONL DECSINGLE_EconL
#define DECBIAS DECSINGLE_Bias
#define DECLETS DECSINGLE_Declets
#define DECQTINY (-DECSINGLE_Bias)
/* parameters of next-wider format */
#define DECWBYTES DECDOUBLE_Bytes
#define DECWPMAX DECDOUBLE_Pmax
#define DECWECONL DECDOUBLE_EconL
#define DECWBIAS DECDOUBLE_Bias
/* Type and function mappings for shared code */
#define decFloat decSingle /* Type name */
#define decFloatWider decDouble /* Type name */
/* Utility (binary results, extractors, etc.) */
#define decFloatFromBCD decSingleFromBCD
#define decFloatFromPacked decSingleFromPacked
#define decFloatFromString decSingleFromString
#define decFloatFromWider decSingleFromWider
#define decFloatGetCoefficient decSingleGetCoefficient
#define decFloatGetExponent decSingleGetExponent
#define decFloatSetCoefficient decSingleSetCoefficient
#define decFloatSetExponent decSingleSetExponent
#define decFloatShow decSingleShow
#define decFloatToBCD decSingleToBCD
#define decFloatToEngString decSingleToEngString
#define decFloatToPacked decSingleToPacked
#define decFloatToString decSingleToString
#define decFloatToWider decSingleToWider
#define decFloatZero decSingleZero
/* Non-computational */
#define decFloatRadix decSingleRadix
#define decFloatVersion decSingleVersion
#include "decNumberLocal.h" /* local includes (need DECPMAX) */
#include "decCommon.c" /* non-basic decFloat routines */
/* [Do not include decBasic.c for decimal32] */
/* decSingle module header for the decNumber C Library.
Copyright (C) 2005 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
This file is part of GCC.
GCC 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 2, or (at your option) any later
version.
In addition to the permissions in the GNU General Public License,
the Free Software Foundation gives you unlimited permission to link
the compiled version of this file into combinations with other
programs, and to distribute those combinations without any
restriction coming from the use of this file. (The General Public
License restrictions do apply in other respects; for example, they
cover modification of the file, and distribution when not linked
into a combine executable.)
GCC 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.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
/* ------------------------------------------------------------------ */
/* decSingle.h -- Decimal 32-bit format module header */
/* ------------------------------------------------------------------ */
/* Please see decFloats.h for an overview and documentation details. */
/* ------------------------------------------------------------------ */
#if !defined(DECSINGLE)
#define DECSINGLE
#define DECSINGLENAME "decSingle" /* Short name */
#define DECSINGLETITLE "Decimal 32-bit datum" /* Verbose name */
#define DECSINGLEAUTHOR "Mike Cowlishaw" /* Who to blame */
/* parameters for decSingles */
#define DECSINGLE_Bytes 4 /* length */
#define DECSINGLE_Pmax 7 /* maximum precision (digits) */
#define DECSINGLE_Emin -95 /* minimum adjusted exponent */
#define DECSINGLE_Emax 96 /* maximum adjusted exponent */
#define DECSINGLE_EmaxD 3 /* maximum exponent digits */
#define DECSINGLE_Bias 101 /* bias for the exponent */
#define DECSINGLE_String 16 /* maximum string length, +1 */
#define DECSINGLE_EconL 6 /* exponent continuation length */
#define DECSINGLE_Declets 2 /* count of declets */
/* highest biased exponent (Elimit-1) */
#define DECSINGLE_Ehigh (DECSINGLE_Emax + DECSINGLE_Bias - (DECSINGLE_Pmax-1))
/* Required includes */
#include "decContext.h"
#include "decQuad.h"
#include "decDouble.h"
/* The decSingle decimal 32-bit type, accessible by bytes */
typedef struct {
uint8_t bytes[DECSINGLE_Bytes]; /* fields: 1, 5, 6, 20 bits */
} decSingle;
/* ---------------------------------------------------------------- */
/* Routines -- implemented as decFloat routines in common files */
/* ---------------------------------------------------------------- */
#include "decSingleSymbols.h"
/* Utilities (binary argument(s) or result, extractors, etc.) */
extern decSingle * decSingleFromBCD(decSingle *, int32_t, const uint8_t *, int32_t);
extern decSingle * decSingleFromPacked(decSingle *, int32_t, const uint8_t *);
extern decSingle * decSingleFromString(decSingle *, const char *, decContext *);
extern decSingle * decSingleFromWider(decSingle *, const decDouble *, decContext *);
extern int32_t decSingleGetCoefficient(const decSingle *, uint8_t *);
extern int32_t decSingleGetExponent(const decSingle *);
extern decSingle * decSingleSetCoefficient(decSingle *, const uint8_t *, int32_t);
extern decSingle * decSingleSetExponent(decSingle *, decContext *, int32_t);
extern void decSingleShow(const decSingle *, const char *);
extern int32_t decSingleToBCD(const decSingle *, int32_t *, uint8_t *);
extern char * decSingleToEngString(const decSingle *, char *);
extern int32_t decSingleToPacked(const decSingle *, int32_t *, uint8_t *);
extern char * decSingleToString(const decSingle *, char *);
extern decDouble * decSingleToWider(const decSingle *, decDouble *);
extern decSingle * decSingleZero(decSingle *);
/* (No Arithmetic routines for decSingle) */
/* Non-computational */
extern uint32_t decSingleRadix(const decSingle *);
extern const char * decSingleVersion(void);
/* decNumber conversions; these are implemented as macros so as not */
/* to force a dependency on decimal32 and decNumber in decSingle. */
#define decSingleToNumber(dq, dn) decimal32ToNumber((decimal32 *)(dq), dn)
#define decSingleFromNumber(dq, dn, set) (decSingle *)decimal32FromNumber((decimal32 *)(dq), dn, set)
#endif
#if !defined(DECSINGLESYMBOLS)
#define DECSINGLESYMBOLS
#ifdef IN_LIBGCC2
#define decSingleFromBCD __decSingleFromBCD
#define decSingleFromPacked __decSingleFromPacked
#define decSingleFromString __decSingleFromString
#define decSingleFromWider __decSingleFromWider
#define decSingleGetCoefficient __decSingleGetCoefficient
#define decSingleGetExponent __decSingleGetExponent
#define decSingleRadix __decSingleRadix
#define decSingleSetCoefficient __decSingleSetCoefficient
#define decSingleSetExponent __decSingleSetExponent
#define decSingleShow __decSingleShow
#define decSingleToBCD __decSingleToBCD
#define decSingleToEngString __decSingleToEngString
#define decSingleToPacked __decSingleToPacked
#define decSingleToString __decSingleToString
#define decSingleToWider __decSingleToWider
#define decSingleVersion __decSingleVersion
#define decSingleZero __decSingleZero
#endif
#endif
/* Utility functions for decimal floating point support via decNumber.
Copyright (C) 2005 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
This file is part of GCC.
GCC 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 2, or (at your option) any later
version.
In addition to the permissions in the GNU General Public License,
the Free Software Foundation gives you unlimited permission to link
the compiled version of this file into combinations with other
programs, and to distribute those combinations without any
restriction coming from the use of this file. (The General Public
License restrictions do apply in other respects; for example, they
cover modification of the file, and distribution when not linked
into a combine executable.)
GCC 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.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
#include "config.h"
#include "decNumber.h" /* base number library */
#include "decNumberLocal.h" /* decNumber local types, etc. */
#include "decUtility.h" /* utility routines */
/* ================================================================== */
/* Shared utility routines */
/* ================================================================== */
/* define and include the conversion tables to use */
#define DEC_BIN2DPD 1 /* used for all sizes */
#if DECDPUN==3
#define DEC_DPD2BIN 1
#else
#define DEC_DPD2BCD 1
#endif
#include "decDPD.h" /* lookup tables */
/* The maximum number of decNumberUnits we need for a working copy of */
/* the units array is the ceiling of digits/DECDPUN, where digits is */
/* the maximum number of digits in any of the formats for which this */
/* is used. We do not want to include decimal128.h, so, as a very */
/* special case, that number is defined here. */
#define DECMAX754 34
#define DECMAXUNITS ((DECMAX754+DECDPUN-1)/DECDPUN)
/* ------------------------------------------------------------------ */
/* decDensePackCoeff -- densely pack coefficient into DPD form */
/* */
/* dn is the source number (assumed valid, max DECMAX754 digits) */
/* bytes is the target's byte array */
/* len is length of target format's byte array */
/* shift is the number of 0 digits to add on the right (normally 0) */
/* */
/* The coefficient must be known small enough to fit, and is filled */
/* in from the right (least significant first). Note that the full */
/* coefficient is copied, including the leading 'odd' digit. This */
/* digit is retrieved and packed into the combination field by the */
/* caller. */
/* */
/* shift is used for 'fold-down' padding. */
/* */
/* No error is possible. */
/* ------------------------------------------------------------------ */
void
decDensePackCoeff (const decNumber * dn, uByte * bytes, Int len, Int shift)
{
Int cut; /* work */
Int n; /* output bunch counter */
Int digits = dn->digits; /* digit countdown */
uInt dpd; /* densely packed decimal value */
uInt bin; /* binary value 0-999 */
uByte *bout; /* -> current output byte */
const Unit *inu = dn->lsu; /* -> current input unit */
Unit uar[DECMAXUNITS]; /* working copy of units, iff shifted */
#if DECDPUN!=3 /* not fast path */
Unit in; /* current input unit */
#endif
if (shift != 0)
{ /* shift towards most significant required */
/* shift the units array to the left by pad digits and copy */
/* [this code is a special case of decShiftToMost, which could */
/* be used instead if exposed and the array were copied first] */
Unit *target, *first; /* work */
const Unit *source; /* work */
uInt next = 0; /* work */
source = dn->lsu + D2U (digits) - 1; /* where msu comes from */
first = uar + D2U (digits + shift) - 1; /* where msu will end up */
target = uar + D2U (digits) - 1 + D2U (shift); /* where upper part of first cut goes */
cut = (DECDPUN - shift % DECDPUN) % DECDPUN;
for (; source >= dn->lsu; source--, target--)
{
/* split the source Unit and accumulate remainder for next */
uInt rem = *source % powers[cut];
next += *source / powers[cut];
if (target <= first)
*target = (Unit) next; /* write to target iff valid */
next = rem * powers[DECDPUN - cut]; /* save remainder for next Unit */
}
/* propagate remainder to one below and clear the rest */
for (; target >= uar; target--)
{
*target = (Unit) next;
next = 0;
}
digits += shift; /* add count (shift) of zeros added */
inu = uar; /* use units in working array */
}
/* densely pack the coefficient into the byte array, starting from
the right (optionally padded) */
bout = &bytes[len - 1]; /* rightmost result byte for phase */
#if DECDPUN!=3 /* not fast path */
in = *inu; /* prime */
cut = 0; /* at lowest digit */
bin = 0; /* [keep compiler quiet] */
#endif
for (n = 0; digits > 0; n++)
{ /* each output bunch */
#if DECDPUN==3 /* fast path, 3-at-a-time */
bin = *inu; /* 3 ready for convert */
digits -= 3; /* [may go negative] */
inu++; /* may need another */
#else /* must collect digit-by-digit */
Unit dig; /* current digit */
Int j; /* digit-in-bunch count */
for (j = 0; j < 3; j++)
{
#if DECDPUN<=4
Unit temp = (Unit) ((uInt) (in * 6554) >> 16);
dig = (Unit) (in - X10 (temp));
in = temp;
#else
dig = in % 10;
in = in / 10;
#endif
if (j == 0)
bin = dig;
else if (j == 1)
bin += X10 (dig);
else /* j==2 */
bin += X100 (dig);
digits--;
if (digits == 0)
break; /* [also protects *inu below] */
cut++;
if (cut == DECDPUN)
{
inu++;
in = *inu;
cut = 0;
}
}
#endif
/* here we have 3 digits in bin, or have used all input digits */
dpd = BIN2DPD[bin];
/* write bunch (bcd) to byte array */
switch (n & 0x03)
{ /* phase 0-3 */
case 0:
*bout = (uByte) dpd; /* [top 2 bits truncated] */
bout--;
*bout = (uByte) (dpd >> 8);
break;
case 1:
*bout |= (uByte) (dpd << 2);
bout--;
*bout = (uByte) (dpd >> 6);
break;
case 2:
*bout |= (uByte) (dpd << 4);
bout--;
*bout = (uByte) (dpd >> 4);
break;
case 3:
*bout |= (uByte) (dpd << 6);
bout--;
*bout = (uByte) (dpd >> 2);
bout--;
break;
} /* switch */
} /* n bunches */
return;
}
/* ------------------------------------------------------------------ */
/* decDenseUnpackCoeff -- unpack a format's coefficient */
/* */
/* byte is the source's byte array */
/* len is length of the source's byte array */
/* dn is the target number, with 7, 16, or 34-digit space. */
/* bunches is the count of DPD groups in the decNumber (2, 5, or 11)*/
/* odd is 1 if there is a non-zero leading 10-bit group containing */
/* a single digit, 0 otherwise */
/* */
/* (This routine works on a copy of the number, if necessary, where */
/* an extra 10-bit group is prefixed to the coefficient continuation */
/* to hold the most significant digit if the latter is non-0.) */
/* */
/* dn->digits is set, but not the sign or exponent. */
/* No error is possible [the redundant 888 codes are allowed]. */
/* ------------------------------------------------------------------ */
void
decDenseUnpackCoeff (const uByte * bytes, Int len, decNumber * dn,
Int bunches, Int odd)
{
uInt dpd = 0; /* collector for 10 bits */
Int n; /* counter */
const uByte *bin; /* -> current input byte */
Unit *uout = dn->lsu; /* -> current output unit */
Unit out = 0; /* accumulator */
Int cut = 0; /* power of ten in current unit */
Unit *last = uout; /* will be unit containing msd */
#if DECDPUN!=3
uInt bcd; /* BCD result */
uInt nibble; /* work */
#endif
/* Expand the densely-packed integer, right to left */
bin = &bytes[len - 1]; /* next input byte to use */
for (n = 0; n < bunches + odd; n++)
{ /* N bunches of 10 bits */
/* assemble the 10 bits */
switch (n & 0x03)
{ /* phase 0-3 */
case 0:
dpd = *bin;
bin--;
dpd |= (*bin & 0x03) << 8;
break;
case 1:
dpd = (unsigned) *bin >> 2;
bin--;
dpd |= (*bin & 0x0F) << 6;
break;
case 2:
dpd = (unsigned) *bin >> 4;
bin--;
dpd |= (*bin & 0x3F) << 4;
break;
case 3:
dpd = (unsigned) *bin >> 6;
bin--;
dpd |= (*bin) << 2;
bin--;
break;
} /*switch */
#if DECDPUN==3
if (dpd == 0)
*uout = 0;
else
{
*uout = DPD2BIN[dpd]; /* convert 10 bits to binary 0-999 */
last = uout; /* record most significant unit */
}
uout++;
#else /* DECDPUN!=3 */
if (dpd == 0)
{ /* fastpath [e.g., leading zeros] */
cut += 3;
for (; cut >= DECDPUN;)
{
cut -= DECDPUN;
*uout = out;
uout++;
out = 0;
}
continue;
}
bcd = DPD2BCD[dpd]; /* convert 10 bits to 12 bits BCD */
/* now split the 3 BCD nibbles into bytes, and accumulate into units */
/* If this is the last bunch and it is an odd one, we only have one */
/* nibble to handle [extras could overflow a Unit] */
nibble = bcd & 0x000f;
if (nibble)
{
last = uout;
out = (Unit) (out + nibble * powers[cut]);
}
cut++;
if (cut == DECDPUN)
{
*uout = out;
uout++;
cut = 0;
out = 0;
}
if (n < bunches)
{
nibble = bcd & 0x00f0;
if (nibble)
{
nibble >>= 4;
last = uout;
out = (Unit) (out + nibble * powers[cut]);
}
cut++;
if (cut == DECDPUN)
{
*uout = out;
uout++;
cut = 0;
out = 0;
}
nibble = bcd & 0x0f00;
if (nibble)
{
nibble >>= 8;
last = uout;
out = (Unit) (out + nibble * powers[cut]);
}
cut++;
if (cut == DECDPUN)
{
*uout = out;
uout++;
cut = 0;
out = 0;
}
}
#endif
} /* n */
if (cut != 0)
*uout = out; /* write out final unit */
/* here, last points to the most significant unit with digits */
/* we need to inspect it to get final digits count */
dn->digits = (last - dn->lsu) * DECDPUN; /* floor of digits */
for (cut = 0; cut < DECDPUN; cut++)
{
if (*last < powers[cut])
break;
dn->digits++;
}
if (dn->digits == 0)
dn->digits++; /* zero has one digit */
return;
}
/* Decimal 128-bit format module from the decNumber C Library. /* Decimal 128-bit format module for the decNumber C Library.
Copyright (C) 2005 Free Software Foundation, Inc. Copyright (C) 2005, 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw. Contributed by IBM Corporation. Author Mike Cowlishaw.
This file is part of GCC. This file is part of GCC.
...@@ -29,26 +29,41 @@ ...@@ -29,26 +29,41 @@
02110-1301, USA. */ 02110-1301, USA. */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* Decimal 128-bit format module */
/* ------------------------------------------------------------------ */
/* This module comprises the routines for decimal128 format numbers. */ /* This module comprises the routines for decimal128 format numbers. */
/* Conversions are supplied to and from decNumber and String. */ /* Conversions are supplied to and from decNumber and String. */
/* */ /* */
/* No arithmetic routines are included; decNumber provides these. */ /* This is used when decNumber provides operations, either for all */
/* operations or as a proxy between decNumber and decSingle. */
/* */ /* */
/* Error handling is the same as decNumber (qv.). */ /* Error handling is the same as decNumber (qv.). */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
#include <string.h> /* [for memset/memcpy] */ #include <string.h> /* [for memset/memcpy] */
#include <stdio.h> /* [for printf] */ #include <stdio.h> /* [for printf] */
#define DECNUMDIGITS 34 /* we need decNumbers with space for 34 */ #include "config.h" /* GCC definitions */
#include "config.h" #define DECNUMDIGITS 34 /* make decNumbers with space for 34 */
#include "decNumber.h" /* base number library */ #include "decNumber.h" /* base number library */
#include "decNumberLocal.h" /* decNumber local types, etc. */ #include "decNumberLocal.h" /* decNumber local types, etc. */
#include "decimal128.h" /* our primary include */ #include "decimal128.h" /* our primary include */
#include "decUtility.h" /* utility routines */
/* Utility routines and tables [in decimal64.c] */
/* DPD2BIN and the reverse are renamed to prevent link-time conflict */
/* if decQuad is also built in the same executable */
#define DPD2BIN DPD2BINx
#define BIN2DPD BIN2DPDx
extern const uInt COMBEXP[32], COMBMSD[32];
extern const uShort DPD2BIN[1024];
extern const uShort BIN2DPD[1000]; /* [not used] */
extern const uByte BIN2CHAR[4001];
extern void decDigitsFromDPD(decNumber *, const uInt *, Int);
extern void decDigitsToDPD(const decNumber *, uInt *, Int);
#if DECTRACE || DECCHECK #if DECTRACE || DECCHECK
void decimal128Show (const decimal128 *); /* for debug */ void decimal128Show(const decimal128 *); /* for debug */
void decNumberShow (const decNumber *); /* .. */ extern void decNumberShow(const decNumber *); /* .. */
#endif #endif
/* Useful macro */ /* Useful macro */
...@@ -72,119 +87,113 @@ void decNumberShow (const decNumber *); /* .. */ ...@@ -72,119 +87,113 @@ void decNumberShow (const decNumber *); /* .. */
/* by reducing its exponent and multiplying the coefficient by a */ /* by reducing its exponent and multiplying the coefficient by a */
/* power of ten, or if the exponent on a zero had to be clamped. */ /* power of ten, or if the exponent on a zero had to be clamped. */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
decimal128 * decimal128 * decimal128FromNumber(decimal128 *d128, const decNumber *dn,
decimal128FromNumber (decimal128 * d128, const decNumber * dn, decContext * set) decContext *set) {
{ uInt status=0; /* status accumulator */
uInt status = 0; /* status accumulator */ Int ae; /* adjusted exponent */
Int pad = 0; /* coefficient pad digits */
decNumber dw; /* work */ decNumber dw; /* work */
decContext dc; /* .. */ decContext dc; /* .. */
uByte isneg = dn->bits & DECNEG; /* non-0 if original sign set */ uInt *pu; /* .. */
uInt comb, exp; /* work */ uInt comb, exp; /* .. */
uInt targar[4]={0,0,0,0}; /* target 128-bit */
/* If the number is finite, and has too many digits, or the exponent */ #define targhi targar[3] /* name the word with the sign */
/* could be out of range then we reduce the number under the */ #define targmh targar[2] /* name the words */
/* appropriate constraints */ #define targml targar[1] /* .. */
if (!(dn->bits & DECSPECIAL)) #define targlo targar[0] /* .. */
{ /* not a special value */
Int ae = dn->exponent + dn->digits - 1; /* adjusted exponent */
if (dn->digits > DECIMAL128_Pmax /* too many digits */
|| ae > DECIMAL128_Emax /* likely overflow */
|| ae < DECIMAL128_Emin)
{ /* likely underflow */
decContextDefault (&dc, DEC_INIT_DECIMAL128); /* [no traps] */
dc.round = set->round; /* use supplied rounding */
decNumberPlus (&dw, dn, &dc); /* (round and check) */
/* [this changes -0 to 0, but it will be restored below] */
status |= dc.status; /* save status */
dn = &dw; /* use the work number */
}
/* [this could have pushed number to Infinity or zero, so this */
/* rounding must be done before we generate the decimal128] */
}
DEC_clear (d128); /* clean the target */ /* If the number has too many digits, or the exponent could be */
if (dn->bits & DECSPECIAL) /* out of range then reduce the number under the appropriate */
{ /* a special value */ /* constraints. This could push the number to Infinity or zero, */
uByte top; /* work */ /* so this check and rounding must be done before generating the */
if (dn->bits & DECINF) /* decimal128] */
top = DECIMAL_Inf; ae=dn->exponent+dn->digits-1; /* [0 if special] */
else if (dn->digits>DECIMAL128_Pmax /* too many digits */
{ /* sNaN or qNaN */ || ae>DECIMAL128_Emax /* likely overflow */
if ((*dn->lsu != 0 || dn->digits > 1) /* non-zero coefficient */ || ae<DECIMAL128_Emin) { /* likely underflow */
&& (dn->digits < DECIMAL128_Pmax)) decContextDefault(&dc, DEC_INIT_DECIMAL128); /* [no traps] */
{ /* coefficient fits */ dc.round=set->round; /* use supplied rounding */
decDensePackCoeff (dn, d128->bytes, sizeof (d128->bytes), 0); decNumberPlus(&dw, dn, &dc); /* (round and check) */
} /* [this changes -0 to 0, so enforce the sign...] */
if (dn->bits & DECNAN) dw.bits|=dn->bits&DECNEG;
top = DECIMAL_NaN; status=dc.status; /* save status */
else dn=&dw; /* use the work number */
top = DECIMAL_sNaN; } /* maybe out of range */
}
d128->bytes[0] = top; if (dn->bits&DECSPECIAL) { /* a special value */
if (dn->bits&DECINF) targhi=DECIMAL_Inf<<24;
else { /* sNaN or qNaN */
if ((*dn->lsu!=0 || dn->digits>1) /* non-zero coefficient */
&& (dn->digits<DECIMAL128_Pmax)) { /* coefficient fits */
decDigitsToDPD(dn, targar, 0);
} }
else if (decNumberIsZero (dn)) if (dn->bits&DECNAN) targhi|=DECIMAL_NaN<<24;
{ /* a zero */ else targhi|=DECIMAL_sNaN<<24;
} /* a NaN */
} /* special */
else { /* is finite */
if (decNumberIsZero(dn)) { /* is a zero */
/* set and clamp exponent */ /* set and clamp exponent */
if (dn->exponent < -DECIMAL128_Bias) if (dn->exponent<-DECIMAL128_Bias) {
{ exp=0; /* low clamp */
exp = 0; status|=DEC_Clamped;
status |= DEC_Clamped;
} }
else else {
{ exp=dn->exponent+DECIMAL128_Bias; /* bias exponent */
exp = dn->exponent + DECIMAL128_Bias; /* bias exponent */ if (exp>DECIMAL128_Ehigh) { /* top clamp */
if (exp > DECIMAL128_Ehigh) exp=DECIMAL128_Ehigh;
{ /* top clamp */ status|=DEC_Clamped;
exp = DECIMAL128_Ehigh;
status |= DEC_Clamped;
} }
} }
comb = (exp >> 9) & 0x18; /* combination field */ comb=(exp>>9) & 0x18; /* msd=0, exp top 2 bits .. */
d128->bytes[0] = (uByte) (comb << 2);
exp &= 0xfff; /* remaining exponent bits */
decimal128SetExpCon (d128, exp);
} }
else else { /* non-zero finite number */
{ /* non-zero finite number */
uInt msd; /* work */ uInt msd; /* work */
Int pad=0; /* coefficient pad digits */
/* we have a dn that fits, but it may need to be padded */ /* the dn is known to fit, but it may need to be padded */
exp = (uInt) (dn->exponent + DECIMAL128_Bias); /* bias exponent */ exp=(uInt)(dn->exponent+DECIMAL128_Bias); /* bias exponent */
if (exp>DECIMAL128_Ehigh) { /* fold-down case */
if (exp > DECIMAL128_Ehigh) pad=exp-DECIMAL128_Ehigh;
{ /* fold-down case */ exp=DECIMAL128_Ehigh; /* [to maximum] */
pad = exp - DECIMAL128_Ehigh; status|=DEC_Clamped;
exp = DECIMAL128_Ehigh; /* [to maximum] */
status |= DEC_Clamped;
} }
decDensePackCoeff (dn, d128->bytes, sizeof (d128->bytes), pad); /* [fastpath for common case is not a win, here] */
decDigitsToDPD(dn, targar, pad);
/* save and clear the top digit */ /* save and clear the top digit */
msd = ((unsigned) d128->bytes[1] << 2) & 0x0c; /* top 2 bits */ msd=targhi>>14;
msd |= ((unsigned) d128->bytes[2] >> 6); /* low 2 bits */ targhi&=0x00003fff;
d128->bytes[1] &= 0xfc;
d128->bytes[2] &= 0x3f;
/* create the combination field */ /* create the combination field */
if (msd >= 8) if (msd>=8) comb=0x18 | ((exp>>11) & 0x06) | (msd & 0x01);
comb = 0x18 | (msd & 0x01) | ((exp >> 11) & 0x06); else comb=((exp>>9) & 0x18) | msd;
else
comb = (msd & 0x07) | ((exp >> 9) & 0x18);
d128->bytes[0] = (uByte) (comb << 2);
exp &= 0xfff; /* remaining exponent bits */
decimal128SetExpCon (d128, exp);
} }
targhi|=comb<<26; /* add combination field .. */
targhi|=(exp&0xfff)<<14; /* .. and exponent continuation */
} /* finite */
if (dn->bits&DECNEG) targhi|=0x80000000; /* add sign bit */
if (isneg) /* now write to storage; this is endian */
decimal128SetSign (d128, 1); pu=(uInt *)d128->bytes; /* overlay */
if (status != 0) if (DECLITEND) {
decContextSetStatus (set, status); /* pass on status */ pu[0]=targlo; /* directly store the low int */
pu[1]=targml; /* then the mid-low */
pu[2]=targmh; /* then the mid-high */
pu[3]=targhi; /* then the high int */
}
else {
pu[0]=targhi; /* directly store the high int */
pu[1]=targmh; /* then the mid-high */
pu[2]=targml; /* then the mid-low */
pu[3]=targlo; /* then the low int */
}
if (status!=0) decContextSetStatus(set, status); /* pass on status */
/* decimal128Show(d128); */ /* decimal128Show(d128); */
return d128; return d128;
} } /* decimal128FromNumber */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* decimal128ToNumber -- convert decimal128 to decNumber */ /* decimal128ToNumber -- convert decimal128 to decNumber */
...@@ -192,70 +201,72 @@ decimal128FromNumber (decimal128 * d128, const decNumber * dn, decContext * set) ...@@ -192,70 +201,72 @@ decimal128FromNumber (decimal128 * d128, const decNumber * dn, decContext * set)
/* dn is the target number, with appropriate space */ /* dn is the target number, with appropriate space */
/* No error is possible. */ /* No error is possible. */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
decNumber * decNumber * decimal128ToNumber(const decimal128 *d128, decNumber *dn) {
decimal128ToNumber (const decimal128 * d128, decNumber * dn)
{
uInt msd; /* coefficient MSD */ uInt msd; /* coefficient MSD */
decimal128 wk; /* working copy, if needed */ uInt exp; /* exponent top two bits */
uInt top = d128->bytes[0] & 0x7f; /* top byte, less sign bit */ uInt comb; /* combination field */
decNumberZero (dn); /* clean target */ const uInt *pu; /* work */
/* set the sign if negative */ Int need; /* .. */
if (decimal128Sign (d128)) uInt sourar[4]; /* source 128-bit */
dn->bits = DECNEG; #define sourhi sourar[3] /* name the word with the sign */
#define sourmh sourar[2] /* and the mid-high word */
if (top >= 0x78) #define sourml sourar[1] /* and the mod-low word */
{ /* is a special */ #define sourlo sourar[0] /* and the lowest word */
if ((top & 0x7c) == (DECIMAL_Inf & 0x7c))
dn->bits |= DECINF; /* load source from storage; this is endian */
else if ((top & 0x7e) == (DECIMAL_NaN & 0x7e)) pu=(const uInt *)d128->bytes; /* overlay */
dn->bits |= DECNAN; if (DECLITEND) {
else sourlo=pu[0]; /* directly load the low int */
dn->bits |= DECSNAN; sourml=pu[1]; /* then the mid-low */
msd = 0; /* no top digit */ sourmh=pu[2]; /* then the mid-high */
sourhi=pu[3]; /* then the high int */
}
else {
sourhi=pu[0]; /* directly load the high int */
sourmh=pu[1]; /* then the mid-high */
sourml=pu[2]; /* then the mid-low */
sourlo=pu[3]; /* then the low int */
} }
else
{ /* have a finite number */ comb=(sourhi>>26)&0x1f; /* combination field */
uInt comb = top >> 2; /* combination field */
uInt exp; /* exponent */ decNumberZero(dn); /* clean number */
if (sourhi&0x80000000) dn->bits=DECNEG; /* set sign if negative */
if (comb >= 0x18)
{ msd=COMBMSD[comb]; /* decode the combination field */
msd = 8 + (comb & 0x01); exp=COMBEXP[comb]; /* .. */
exp = (comb & 0x06) << 11; /* MSBs */
if (exp==3) { /* is a special */
if (msd==0) {
dn->bits|=DECINF;
return dn; /* no coefficient needed */
} }
else else if (sourhi&0x02000000) dn->bits|=DECSNAN;
{ else dn->bits|=DECNAN;
msd = comb & 0x07; msd=0; /* no top digit */
exp = (comb & 0x18) << 9;
} }
dn->exponent = exp + decimal128ExpCon (d128) - DECIMAL128_Bias; /* remove bias */ else { /* is a finite number */
dn->exponent=(exp<<12)+((sourhi>>14)&0xfff)-DECIMAL128_Bias; /* unbiased */
} }
/* get the coefficient, unless infinite */ /* get the coefficient */
if (!(dn->bits & DECINF)) sourhi&=0x00003fff; /* clean coefficient continuation */
{ if (msd) { /* non-zero msd */
Int bunches = DECIMAL128_Pmax / 3; /* coefficient full bunches to convert */ sourhi|=msd<<14; /* prefix to coefficient */
Int odd = 0; /* assume MSD is 0 (no odd bunch) */ need=12; /* process 12 declets */
if (msd != 0)
{ /* coefficient has leading non-0 digit */
/* make a copy of the decimal128, with an extra bunch which has */
/* the top digit ready for conversion */
wk = *d128; /* take a copy */
wk.bytes[0] = 0; /* clear all but coecon */
wk.bytes[1] = 0; /* .. */
wk.bytes[2] &= 0x3f; /* .. */
wk.bytes[1] |= (msd >> 2); /* and prefix MSD */
wk.bytes[2] |= (msd << 6); /* .. */
odd++; /* indicate the extra */
d128 = &wk; /* use the work copy */
}
decDenseUnpackCoeff (d128->bytes, sizeof (d128->bytes), dn, bunches,
odd);
} }
else { /* msd=0 */
if (sourhi) need=11; /* declets to process */
else if (sourmh) need=10;
else if (sourml) need=7;
else if (sourlo) need=4;
else return dn; /* easy: coefficient is 0 */
} /*msd=0 */
decDigitsFromDPD(dn, sourar, need); /* process declets */
/* decNumberShow(dn); */ /* decNumberShow(dn); */
return dn; return dn;
} } /* decimal128ToNumber */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* to-scientific-string -- conversion to numeric string */ /* to-scientific-string -- conversion to numeric string */
...@@ -271,23 +282,173 @@ decimal128ToNumber (const decimal128 * d128, decNumber * dn) ...@@ -271,23 +282,173 @@ decimal128ToNumber (const decimal128 * d128, decNumber * dn)
/* */ /* */
/* No error is possible, and no status can be set. */ /* No error is possible, and no status can be set. */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
char * char * decimal128ToEngString(const decimal128 *d128, char *string){
decimal128ToString (const decimal128 * d128, char *string)
{
decNumber dn; /* work */ decNumber dn; /* work */
decimal128ToNumber (d128, &dn); decimal128ToNumber(d128, &dn);
decNumberToString (&dn, string); decNumberToEngString(&dn, string);
return string; return string;
} } /* decimal128ToEngString */
char * char * decimal128ToString(const decimal128 *d128, char *string){
decimal128ToEngString (const decimal128 * d128, char *string) uInt msd; /* coefficient MSD */
{ Int exp; /* exponent top two bits or full */
decNumber dn; /* work */ uInt comb; /* combination field */
decimal128ToNumber (d128, &dn); char *cstart; /* coefficient start */
decNumberToEngString (&dn, string); char *c; /* output pointer in string */
const uInt *pu; /* work */
char *s, *t; /* .. (source, target) */
Int dpd; /* .. */
Int pre, e; /* .. */
const uByte *u; /* .. */
uInt sourar[4]; /* source 128-bit */
#define sourhi sourar[3] /* name the word with the sign */
#define sourmh sourar[2] /* and the mid-high word */
#define sourml sourar[1] /* and the mod-low word */
#define sourlo sourar[0] /* and the lowest word */
/* load source from storage; this is endian */
pu=(const uInt *)d128->bytes; /* overlay */
if (DECLITEND) {
sourlo=pu[0]; /* directly load the low int */
sourml=pu[1]; /* then the mid-low */
sourmh=pu[2]; /* then the mid-high */
sourhi=pu[3]; /* then the high int */
}
else {
sourhi=pu[0]; /* directly load the high int */
sourmh=pu[1]; /* then the mid-high */
sourml=pu[2]; /* then the mid-low */
sourlo=pu[3]; /* then the low int */
}
c=string; /* where result will go */
if (((Int)sourhi)<0) *c++='-'; /* handle sign */
comb=(sourhi>>26)&0x1f; /* combination field */
msd=COMBMSD[comb]; /* decode the combination field */
exp=COMBEXP[comb]; /* .. */
if (exp==3) {
if (msd==0) { /* infinity */
strcpy(c, "Inf");
strcpy(c+3, "inity");
return string; /* easy */
}
if (sourhi&0x02000000) *c++='s'; /* sNaN */
strcpy(c, "NaN"); /* complete word */
c+=3; /* step past */
if (sourlo==0 && sourml==0 && sourmh==0
&& (sourhi&0x0003ffff)==0) return string; /* zero payload */
/* otherwise drop through to add integer; set correct exp */
exp=0; msd=0; /* setup for following code */
}
else exp=(exp<<12)+((sourhi>>14)&0xfff)-DECIMAL128_Bias; /* unbiased */
/* convert 34 digits of significand to characters */
cstart=c; /* save start of coefficient */
if (msd) *c++='0'+(char)msd; /* non-zero most significant digit */
/* Now decode the declets. After extracting each one, it is */
/* decoded to binary and then to a 4-char sequence by table lookup; */
/* the 4-chars are a 1-char length (significant digits, except 000 */
/* has length 0). This allows us to left-align the first declet */
/* with non-zero content, then remaining ones are full 3-char */
/* length. We use fixed-length memcpys because variable-length */
/* causes a subroutine call in GCC. (These are length 4 for speed */
/* and are safe because the array has an extra terminator byte.) */
#define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; \
if (c!=cstart) {memcpy(c, u+1, 4); c+=3;} \
else if (*u) {memcpy(c, u+4-*u, 4); c+=*u;}
dpd=(sourhi>>4)&0x3ff; /* declet 1 */
dpd2char;
dpd=((sourhi&0xf)<<6) | (sourmh>>26); /* declet 2 */
dpd2char;
dpd=(sourmh>>16)&0x3ff; /* declet 3 */
dpd2char;
dpd=(sourmh>>6)&0x3ff; /* declet 4 */
dpd2char;
dpd=((sourmh&0x3f)<<4) | (sourml>>28); /* declet 5 */
dpd2char;
dpd=(sourml>>18)&0x3ff; /* declet 6 */
dpd2char;
dpd=(sourml>>8)&0x3ff; /* declet 7 */
dpd2char;
dpd=((sourml&0xff)<<2) | (sourlo>>30); /* declet 8 */
dpd2char;
dpd=(sourlo>>20)&0x3ff; /* declet 9 */
dpd2char;
dpd=(sourlo>>10)&0x3ff; /* declet 10 */
dpd2char;
dpd=(sourlo)&0x3ff; /* declet 11 */
dpd2char;
if (c==cstart) *c++='0'; /* all zeros -- make 0 */
if (exp==0) { /* integer or NaN case -- easy */
*c='\0'; /* terminate */
return string; return string;
} }
/* non-0 exponent */
e=0; /* assume no E */
pre=c-cstart+exp;
/* [here, pre-exp is the digits count (==1 for zero)] */
if (exp>0 || pre<-5) { /* need exponential form */
e=pre-1; /* calculate E value */
pre=1; /* assume one digit before '.' */
} /* exponential form */
/* modify the coefficient, adding 0s, '.', and E+nn as needed */
s=c-1; /* source (LSD) */
if (pre>0) { /* ddd.ddd (plain), perhaps with E */
char *dotat=cstart+pre;
if (dotat<c) { /* if embedded dot needed... */
t=c; /* target */
for (; s>=dotat; s--, t--) *t=*s; /* open the gap; leave t at gap */
*t='.'; /* insert the dot */
c++; /* length increased by one */
}
/* finally add the E-part, if needed; it will never be 0, and has */
/* a maximum length of 4 digits */
if (e!=0) {
*c++='E'; /* starts with E */
*c++='+'; /* assume positive */
if (e<0) {
*(c-1)='-'; /* oops, need '-' */
e=-e; /* uInt, please */
}
if (e<1000) { /* 3 (or fewer) digits case */
u=&BIN2CHAR[e*4]; /* -> length byte */
memcpy(c, u+4-*u, 4); /* copy fixed 4 characters [is safe] */
c+=*u; /* bump pointer appropriately */
}
else { /* 4-digits */
Int thou=((e>>3)*1049)>>17; /* e/1000 */
Int rem=e-(1000*thou); /* e%1000 */
*c++='0'+(char)thou;
u=&BIN2CHAR[rem*4]; /* -> length byte */
memcpy(c, u+1, 4); /* copy fixed 3+1 characters [is safe] */
c+=3; /* bump pointer, always 3 digits */
}
}
*c='\0'; /* add terminator */
/*printf("res %s\n", string); */
return string;
} /* pre>0 */
/* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (can never have E) */
t=c+1-pre;
*(t+1)='\0'; /* can add terminator now */
for (; s>=cstart; s--, t--) *t=*s; /* shift whole coefficient right */
c=cstart;
*c++='0'; /* always starts with 0. */
*c++='.';
for (; pre<0; pre++) *c++='0'; /* add any 0's after '.' */
/*printf("res %s\n", string); */
return string;
} /* decimal128ToString */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* to-number -- conversion from numeric string */ /* to-number -- conversion from numeric string */
...@@ -304,44 +465,106 @@ decimal128ToEngString (const decimal128 * d128, char *string) ...@@ -304,44 +465,106 @@ decimal128ToEngString (const decimal128 * d128, char *string)
/* (setting of status and traps) and for the rounding mode, only. */ /* (setting of status and traps) and for the rounding mode, only. */
/* If an error occurs, the result will be a valid decimal128 NaN. */ /* If an error occurs, the result will be a valid decimal128 NaN. */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
decimal128 * decimal128 * decimal128FromString(decimal128 *result, const char *string,
decimal128FromString (decimal128 * result, const char *string, decContext * set) decContext *set) {
{
decContext dc; /* work */ decContext dc; /* work */
decNumber dn; /* .. */ decNumber dn; /* .. */
decContextDefault (&dc, DEC_INIT_DECIMAL128); /* no traps, please */ decContextDefault(&dc, DEC_INIT_DECIMAL128); /* no traps, please */
dc.round = set->round; /* use supplied rounding */ dc.round=set->round; /* use supplied rounding */
decNumberFromString (&dn, string, &dc); /* will round if needed */ decNumberFromString(&dn, string, &dc); /* will round if needed */
decimal128FromNumber (result, &dn, &dc); decimal128FromNumber(result, &dn, &dc);
if (dc.status != 0) if (dc.status!=0) { /* something happened */
{ /* something happened */ decContextSetStatus(set, dc.status); /* .. pass it on */
decContextSetStatus (set, dc.status); /* .. pass it on */
} }
return result; return result;
} } /* decimal128FromString */
/* ------------------------------------------------------------------ */
/* decimal128IsCanonical -- test whether encoding is canonical */
/* d128 is the source decimal128 */
/* returns 1 if the encoding of d128 is canonical, 0 otherwise */
/* No error is possible. */
/* ------------------------------------------------------------------ */
uint32_t decimal128IsCanonical(const decimal128 *d128) {
decNumber dn; /* work */
decimal128 canon; /* .. */
decContext dc; /* .. */
decContextDefault(&dc, DEC_INIT_DECIMAL128);
decimal128ToNumber(d128, &dn);
decimal128FromNumber(&canon, &dn, &dc);/* canon will now be canonical */
return memcmp(d128, &canon, DECIMAL128_Bytes)==0;
} /* decimal128IsCanonical */
/* ------------------------------------------------------------------ */
/* decimal128Canonical -- copy an encoding, ensuring it is canonical */
/* d128 is the source decimal128 */
/* result is the target (may be the same decimal128) */
/* returns result */
/* No error is possible. */
/* ------------------------------------------------------------------ */
decimal128 * decimal128Canonical(decimal128 *result, const decimal128 *d128) {
decNumber dn; /* work */
decContext dc; /* .. */
decContextDefault(&dc, DEC_INIT_DECIMAL128);
decimal128ToNumber(d128, &dn);
decimal128FromNumber(result, &dn, &dc);/* result will now be canonical */
return result;
} /* decimal128Canonical */
#if DECTRACE || DECCHECK #if DECTRACE || DECCHECK
/* Macros for accessing decimal128 fields. These assume the argument
is a reference (pointer) to the decimal128 structure, and the
decimal128 is in network byte order (big-endian) */
/* Get sign */
#define decimal128Sign(d) ((unsigned)(d)->bytes[0]>>7)
/* Get combination field */
#define decimal128Comb(d) (((d)->bytes[0] & 0x7c)>>2)
/* Get exponent continuation [does not remove bias] */
#define decimal128ExpCon(d) ((((d)->bytes[0] & 0x03)<<10) \
| ((unsigned)(d)->bytes[1]<<2) \
| ((unsigned)(d)->bytes[2]>>6))
/* Set sign [this assumes sign previously 0] */
#define decimal128SetSign(d, b) { \
(d)->bytes[0]|=((unsigned)(b)<<7);}
/* Set exponent continuation [does not apply bias] */
/* This assumes range has been checked and exponent previously 0; */
/* type of exponent must be unsigned */
#define decimal128SetExpCon(d, e) { \
(d)->bytes[0]|=(uint8_t)((e)>>10); \
(d)->bytes[1] =(uint8_t)(((e)&0x3fc)>>2); \
(d)->bytes[2]|=(uint8_t)(((e)&0x03)<<6);}
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* decimal128Show -- display a single in hexadecimal [debug aid] */ /* decimal128Show -- display a decimal128 in hexadecimal [debug aid] */
/* d128 -- the number to show */ /* d128 -- the number to show */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* Also shows sign/cob/expconfields extracted */ /* Also shows sign/cob/expconfields extracted */
void void decimal128Show(const decimal128 *d128) {
decimal128Show (const decimal128 * d128) char buf[DECIMAL128_Bytes*2+1];
{ Int i, j=0;
char buf[DECIMAL128_Bytes * 2 + 1];
Int i, j; if (DECLITEND) {
j = 0; for (i=0; i<DECIMAL128_Bytes; i++, j+=2) {
for (i = 0; i < DECIMAL128_Bytes; i++) sprintf(&buf[j], "%02x", d128->bytes[15-i]);
{ }
sprintf (&buf[j], "%02x", d128->bytes[i]); printf(" D128> %s [S:%d Cb:%02x Ec:%02x] LittleEndian\n", buf,
j = j + 2; d128->bytes[15]>>7, (d128->bytes[15]>>2)&0x1f,
((d128->bytes[15]&0x3)<<10)|(d128->bytes[14]<<2)|
(d128->bytes[13]>>6));
}
else {
for (i=0; i<DECIMAL128_Bytes; i++, j+=2) {
sprintf(&buf[j], "%02x", d128->bytes[i]);
}
printf(" D128> %s [S:%d Cb:%02x Ec:%02x] BigEndian\n", buf,
decimal128Sign(d128), decimal128Comb(d128),
decimal128ExpCon(d128));
} }
printf (" D128> %s [S:%d Cb:%02x E:%d]\n", buf, } /* decimal128Show */
decimal128Sign (d128), decimal128Comb (d128),
decimal128ExpCon (d128));
}
#endif #endif
/* Decimal 128-bit format module header for the decNumber C Library /* Decimal 128-bit format module header for the decNumber C Library.
Copyright (C) 2005 Free Software Foundation, Inc. Copyright (C) 2005, 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw. Contributed by IBM Corporation. Author Mike Cowlishaw.
This file is part of GCC. This file is part of GCC.
...@@ -28,103 +28,74 @@ ...@@ -28,103 +28,74 @@
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */ 02110-1301, USA. */
/* ------------------------------------------------------------------ */
/* Decimal 128-bit format module header */
/* ------------------------------------------------------------------ */
#if !defined(DECIMAL128) #if !defined(DECIMAL128)
#define DECIMAL128 #define DECIMAL128
#define DEC128NAME "decimal128" /* Short name */ #define DEC128NAME "decimal128" /* Short name */
#define DEC128FULLNAME "Decimal 128-bit Number" /* Verbose name */ #define DEC128FULLNAME "Decimal 128-bit Number" /* Verbose name */
#define DEC128AUTHOR "Mike Cowlishaw" /* Who to blame */ #define DEC128AUTHOR "Mike Cowlishaw" /* Who to blame */
#if defined(DECIMAL32)
#error decimal128.h must precede decimal32.h for correct DECNUMDIGITS
#else
#if defined(DECIMAL64)
#error decimal128.h must precede decimal64.h for correct DECNUMDIGITS
#endif
#endif
/* parameters for decimal128s */ /* parameters for decimal128s */
#define DECIMAL128_Bytes 16 /* length */ #define DECIMAL128_Bytes 16 /* length */
#define DECIMAL128_Pmax 34 /* maximum precision (digits) */ #define DECIMAL128_Pmax 34 /* maximum precision (digits) */
#define DECIMAL128_Emax 6144 /* maximum adjusted exponent */ #define DECIMAL128_Emax 6144 /* maximum adjusted exponent */
#define DECIMAL128_Emin -6143 /* minimum adjusted exponent */ #define DECIMAL128_Emin -6143 /* minimum adjusted exponent */
#define DECIMAL128_Bias 6176 /* bias for the exponent */ #define DECIMAL128_Bias 6176 /* bias for the exponent */
#define DECIMAL128_String 43 /* maximum string length, +1 */ #define DECIMAL128_String 43 /* maximum string length, +1 */
#define DECIMAL128_EconL 12 /* exp. continuation length */
/* highest biased exponent (Elimit-1) */ /* highest biased exponent (Elimit-1) */
#define DECIMAL128_Ehigh (DECIMAL128_Emax+DECIMAL128_Bias-DECIMAL128_Pmax+1) #define DECIMAL128_Ehigh (DECIMAL128_Emax+DECIMAL128_Bias-DECIMAL128_Pmax+1)
#ifndef DECNUMDIGITS /* check enough digits, if pre-defined */
#define DECNUMDIGITS DECIMAL128_Pmax /* size if not already defined */ #if defined(DECNUMDIGITS)
#endif #if (DECNUMDIGITS<DECIMAL128_Pmax)
#ifndef DECNUMBER #error decimal128.h needs pre-defined DECNUMDIGITS>=34 for safe use
#include "decNumber.h" /* context and number library */ #endif
#endif #endif
#ifndef DECNUMDIGITS
#define DECNUMDIGITS DECIMAL128_Pmax /* size if not already defined*/
#endif
#ifndef DECNUMBER
#include "decNumber.h" /* context and number library */
#endif
/* Decimal 128-bit type, accessible by bytes */ /* Decimal 128-bit type, accessible by bytes */
typedef struct typedef struct {
{ uint8_t bytes[DECIMAL128_Bytes]; /* decimal128: 1, 5, 12, 110 bits*/
uint8_t bytes[DECIMAL128_Bytes]; /* decimal128: 1, 5, 12, 110 bits */ } decimal128;
} decimal128;
/* special values [top byte excluding sign bit; last two bits are
don't-care for Infinity on input, last bit don't-care for NaN] */
#if !defined(DECIMAL_NaN)
#define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */
#define DECIMAL_sNaN 0x7e /* 0 11111 10 sNaN */
#define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */
#endif
/* Macros for accessing decimal128 fields. These assume the argument
is a reference (pointer) to the decimal128 structure */
/* Get sign */
#define decimal128Sign(d) ((unsigned)(d)->bytes[0]>>7)
/* Get combination field */ /* special values [top byte excluding sign bit; last two bits are */
#define decimal128Comb(d) (((d)->bytes[0] & 0x7c)>>2) /* don't-care for Infinity on input, last bit don't-care for NaN] */
#if !defined(DECIMAL_NaN)
#define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */
#define DECIMAL_sNaN 0x7e /* 0 11111 10 sNaN */
#define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */
#endif
/* Get exponent continuation [does not remove bias] */ #include "decimal128Local.h"
#define decimal128ExpCon(d) ((((d)->bytes[0] & 0x03)<<10) \
| ((unsigned)(d)->bytes[1]<<2) \
| ((unsigned)(d)->bytes[2]>>6))
/* Set sign [this assumes sign previously 0] */ /* ---------------------------------------------------------------- */
#define decimal128SetSign(d, b) { \
(d)->bytes[0]|=((unsigned)(b)<<7);}
/* Clear sign */
#define decimal128ClearSign(d) {(d)->bytes[0]&=~0x80;}
/* Flip sign */
#define decimal128FlipSign(d) {(d)->bytes[0]^=0x80;}
/* Set exponent continuation [does not apply bias] */
/* This assumes range has been checked and exponent previously 0; */
/* type of exponent must be unsigned */
#define decimal128SetExpCon(d, e) { \
(d)->bytes[0]|=(uint8_t)((e)>>10); \
(d)->bytes[1] =(uint8_t)(((e)&0x3fc)>>2); \
(d)->bytes[2]|=(uint8_t)(((e)&0x03)<<6);}
/* ------------------------------------------------------------------ */
/* Routines */ /* Routines */
/* ------------------------------------------------------------------ */ /* ---------------------------------------------------------------- */
#ifdef IN_LIBGCC2 #include "decimal128Symbols.h"
#ifndef decimal128FromString
#define decimal128FromString __decimal128FromString
#define decimal128ToString __decimal128ToString
#define decimal128ToEngString __decimal128ToEngString
#define decimal128FromNumber __decimal128FromNumber
#define decimal128ToNumber __decimal128ToNumber
#endif
#endif
/* String conversions */ /* String conversions */
decimal128 *decimal128FromString (decimal128 *, const char *, decContext *); decimal128 * decimal128FromString(decimal128 *, const char *, decContext *);
char *decimal128ToString (const decimal128 *, char *); char * decimal128ToString(const decimal128 *, char *);
char *decimal128ToEngString (const decimal128 *, char *); char * decimal128ToEngString(const decimal128 *, char *);
/* decNumber conversions */ /* decNumber conversions */
decimal128 *decimal128FromNumber (decimal128 *, const decNumber *, decContext *); decimal128 * decimal128FromNumber(decimal128 *, const decNumber *,
decNumber *decimal128ToNumber (const decimal128 *, decNumber *); decContext *);
decNumber * decimal128ToNumber(const decimal128 *, decNumber *);
/* Format-dependent utilities */
uint32_t decimal128IsCanonical(const decimal128 *);
decimal128 * decimal128Canonical(decimal128 *, const decimal128 *);
#endif #endif
/* Utility functions for decimal floating point support via decNumber. /* Local definitions for use with the decNumber C Library.
Copyright (C) 2005 Free Software Foundation, Inc. Copyright (C) 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
This file is part of GCC. This file is part of GCC.
...@@ -28,10 +27,21 @@ ...@@ -28,10 +27,21 @@
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */ 02110-1301, USA. */
#ifdef IN_LIBGCC2 #if !defined(DECIMAL128LOCAL)
#define decDensePackCoeff __decDensePackCoeff
#define decDenseUnpackCoeff __decDenseUnpackCoeff /* The compiler needs sign manipulation functions for decimal128 which
#endif are not part of the decNumber package. */
/* Set sign; this assumes the sign was previously zero. */
#define decimal128SetSign(d,b) \
{ (d)->bytes[FLOAT_WORDS_BIG_ENDIAN ? 0 : 15] |= ((unsigned) (b) << 7); }
extern void decDensePackCoeff (const decNumber *, uByte *, Int, Int); /* Clear sign. */
extern void decDenseUnpackCoeff (const uByte *, Int, decNumber *, Int, Int); #define decimal128ClearSign(d) \
{ (d)->bytes[FLOAT_WORDS_BIG_ENDIAN ? 0 : 15] &= ~0x80; }
/* Flip sign. */
#define decimal128FlipSign(d) \
{ (d)->bytes[FLOAT_WORDS_BIG_ENDIAN ? 0 : 15] ^= 0x80; }
#endif
#if !defined(DECIMAL128SYMBOLS)
#define DECIMAL128SYMBOLS
#ifdef IN_LIBGCC2
#define decDigitsFromDPD __decDigitsFromDPD
#define decDigitsToDPD __decDigitsToDPD
#define decimal128Canonical __decimal128Canonical
#define decimal128FromNumber __decimal128FromNumber
#define decimal128FromString __decimal128FromString
#define decimal128IsCanonical __decimal128IsCanonical
#define decimal128ToEngString __decimal128ToEngString
#define decimal128ToNumber __decimal128ToNumber
#define decimal128ToString __decimal128ToString
#endif
#endif
/* Decimal 32-bit format module for the decNumber C Library /* Decimal 32-bit format module for the decNumber C Library.
Copyright (C) 2005 Free Software Foundation, Inc. Copyright (C) 2005, 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw. Contributed by IBM Corporation. Author Mike Cowlishaw.
This file is part of GCC. This file is part of GCC.
...@@ -29,26 +29,41 @@ ...@@ -29,26 +29,41 @@
02110-1301, USA. */ 02110-1301, USA. */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* Decimal 32-bit format module */
/* ------------------------------------------------------------------ */
/* This module comprises the routines for decimal32 format numbers. */ /* This module comprises the routines for decimal32 format numbers. */
/* Conversions are supplied to and from decNumber and String. */ /* Conversions are supplied to and from decNumber and String. */
/* */ /* */
/* No arithmetic routines are included; decNumber provides these. */ /* This is used when decNumber provides operations, either for all */
/* operations or as a proxy between decNumber and decSingle. */
/* */ /* */
/* Error handling is the same as decNumber (qv.). */ /* Error handling is the same as decNumber (qv.). */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
#include <string.h> /* [for memset/memcpy] */ #include <string.h> /* [for memset/memcpy] */
#include <stdio.h> /* [for printf] */ #include <stdio.h> /* [for printf] */
#define DECNUMDIGITS 7 /* we need decNumbers with space for 7 */ #include "config.h" /* GCC definitions */
#include "config.h" #define DECNUMDIGITS 7 /* make decNumbers with space for 7 */
#include "decNumber.h" /* base number library */ #include "decNumber.h" /* base number library */
#include "decNumberLocal.h" /* decNumber local types, etc. */ #include "decNumberLocal.h" /* decNumber local types, etc. */
#include "decimal32.h" /* our primary include */ #include "decimal32.h" /* our primary include */
#include "decUtility.h" /* utility routines */
/* Utility tables and routines [in decimal64.c] */
/* DPD2BIN and the reverse are renamed to prevent link-time conflict */
/* if decQuad is also built in the same executable */
#define DPD2BIN DPD2BINx
#define BIN2DPD BIN2DPDx
extern const uInt COMBEXP[32], COMBMSD[32];
extern const uShort DPD2BIN[1024];
extern const uShort BIN2DPD[1000];
extern const uByte BIN2CHAR[4001];
extern void decDigitsToDPD(const decNumber *, uInt *, Int);
extern void decDigitsFromDPD(decNumber *, const uInt *, Int);
#if DECTRACE || DECCHECK #if DECTRACE || DECCHECK
void decimal32Show (const decimal32 *); /* for debug */ void decimal32Show(const decimal32 *); /* for debug */
void decNumberShow (const decNumber *); /* .. */ extern void decNumberShow(const decNumber *); /* .. */
#endif #endif
/* Useful macro */ /* Useful macro */
...@@ -72,116 +87,105 @@ void decNumberShow (const decNumber *); /* .. */ ...@@ -72,116 +87,105 @@ void decNumberShow (const decNumber *); /* .. */
/* by reducing its exponent and multiplying the coefficient by a */ /* by reducing its exponent and multiplying the coefficient by a */
/* power of ten, or if the exponent on a zero had to be clamped. */ /* power of ten, or if the exponent on a zero had to be clamped. */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
decimal32 * decimal32 * decimal32FromNumber(decimal32 *d32, const decNumber *dn,
decimal32FromNumber (decimal32 * d32, const decNumber * dn, decContext * set) decContext *set) {
{ uInt status=0; /* status accumulator */
uInt status = 0; /* status accumulator */ Int ae; /* adjusted exponent */
Int pad = 0; /* coefficient pad digits */
decNumber dw; /* work */ decNumber dw; /* work */
decContext dc; /* .. */ decContext dc; /* .. */
uByte isneg = dn->bits & DECNEG; /* non-0 if original sign set */ uInt *pu; /* .. */
uInt comb, exp; /* work */ uInt comb, exp; /* .. */
uInt targ=0; /* target 32-bit */
/* If the number is finite, and has too many digits, or the exponent */
/* could be out of range then we reduce the number under the */
/* appropriate constraints */
if (!(dn->bits & DECSPECIAL))
{ /* not a special value */
Int ae = dn->exponent + dn->digits - 1; /* adjusted exponent */
if (dn->digits > DECIMAL32_Pmax /* too many digits */
|| ae > DECIMAL32_Emax /* likely overflow */
|| ae < DECIMAL32_Emin)
{ /* likely underflow */
decContextDefault (&dc, DEC_INIT_DECIMAL32); /* [no traps] */
dc.round = set->round; /* use supplied rounding */
decNumberPlus (&dw, dn, &dc); /* (round and check) */
/* [this changes -0 to 0, but it will be restored below] */
status |= dc.status; /* save status */
dn = &dw; /* use the work number */
}
/* [this could have pushed number to Infinity or zero, so this */
/* rounding must be done before we generate the decimal32] */
}
DEC_clear (d32); /* clean the target */ /* If the number has too many digits, or the exponent could be */
if (dn->bits & DECSPECIAL) /* out of range then reduce the number under the appropriate */
{ /* a special value */ /* constraints. This could push the number to Infinity or zero, */
uByte top; /* work */ /* so this check and rounding must be done before generating the */
if (dn->bits & DECINF) /* decimal32] */
top = DECIMAL_Inf; ae=dn->exponent+dn->digits-1; /* [0 if special] */
else if (dn->digits>DECIMAL32_Pmax /* too many digits */
{ /* sNaN or qNaN */ || ae>DECIMAL32_Emax /* likely overflow */
if ((*dn->lsu != 0 || dn->digits > 1) /* non-zero coefficient */ || ae<DECIMAL32_Emin) { /* likely underflow */
&& (dn->digits < DECIMAL32_Pmax)) decContextDefault(&dc, DEC_INIT_DECIMAL32); /* [no traps] */
{ /* coefficient fits */ dc.round=set->round; /* use supplied rounding */
decDensePackCoeff (dn, d32->bytes, sizeof (d32->bytes), 0); decNumberPlus(&dw, dn, &dc); /* (round and check) */
} /* [this changes -0 to 0, so enforce the sign...] */
if (dn->bits & DECNAN) dw.bits|=dn->bits&DECNEG;
top = DECIMAL_NaN; status=dc.status; /* save status */
else dn=&dw; /* use the work number */
top = DECIMAL_sNaN; } /* maybe out of range */
}
d32->bytes[0] = top; if (dn->bits&DECSPECIAL) { /* a special value */
if (dn->bits&DECINF) targ=DECIMAL_Inf<<24;
else { /* sNaN or qNaN */
if ((*dn->lsu!=0 || dn->digits>1) /* non-zero coefficient */
&& (dn->digits<DECIMAL32_Pmax)) { /* coefficient fits */
decDigitsToDPD(dn, &targ, 0);
} }
else if (decNumberIsZero (dn)) if (dn->bits&DECNAN) targ|=DECIMAL_NaN<<24;
{ /* a zero */ else targ|=DECIMAL_sNaN<<24;
} /* a NaN */
} /* special */
else { /* is finite */
if (decNumberIsZero(dn)) { /* is a zero */
/* set and clamp exponent */ /* set and clamp exponent */
if (dn->exponent < -DECIMAL32_Bias) if (dn->exponent<-DECIMAL32_Bias) {
{ exp=0; /* low clamp */
exp = 0; status|=DEC_Clamped;
status |= DEC_Clamped;
} }
else else {
{ exp=dn->exponent+DECIMAL32_Bias; /* bias exponent */
exp = dn->exponent + DECIMAL32_Bias; /* bias exponent */ if (exp>DECIMAL32_Ehigh) { /* top clamp */
if (exp > DECIMAL32_Ehigh) exp=DECIMAL32_Ehigh;
{ /* top clamp */ status|=DEC_Clamped;
exp = DECIMAL32_Ehigh;
status |= DEC_Clamped;
} }
} }
comb = (exp >> 3) & 0x18; /* combination field */ comb=(exp>>3) & 0x18; /* msd=0, exp top 2 bits .. */
d32->bytes[0] = (uByte) (comb << 2);
exp &= 0x3f; /* remaining exponent bits */
decimal32SetExpCon (d32, exp);
} }
else else { /* non-zero finite number */
{ /* non-zero finite number */
uInt msd; /* work */ uInt msd; /* work */
Int pad=0; /* coefficient pad digits */
/* we have a dn that fits, but it may need to be padded */ /* the dn is known to fit, but it may need to be padded */
exp = (uInt) (dn->exponent + DECIMAL32_Bias); /* bias exponent */ exp=(uInt)(dn->exponent+DECIMAL32_Bias); /* bias exponent */
if (exp>DECIMAL32_Ehigh) { /* fold-down case */
if (exp > DECIMAL32_Ehigh) pad=exp-DECIMAL32_Ehigh;
{ /* fold-down case */ exp=DECIMAL32_Ehigh; /* [to maximum] */
pad = exp - DECIMAL32_Ehigh; status|=DEC_Clamped;
exp = DECIMAL32_Ehigh; /* [to maximum] */
status |= DEC_Clamped;
} }
decDensePackCoeff (dn, d32->bytes, sizeof (d32->bytes), pad); /* fastpath common case */
if (DECDPUN==3 && pad==0) {
targ=BIN2DPD[dn->lsu[0]];
if (dn->digits>3) targ|=(uInt)(BIN2DPD[dn->lsu[1]])<<10;
msd=(dn->digits==7 ? dn->lsu[2] : 0);
}
else { /* general case */
decDigitsToDPD(dn, &targ, pad);
/* save and clear the top digit */ /* save and clear the top digit */
msd = ((unsigned) d32->bytes[1] >> 4); msd=targ>>20;
d32->bytes[1] &= 0x0f; targ&=0x000fffff;
}
/* create the combination field */ /* create the combination field */
if (msd >= 8) if (msd>=8) comb=0x18 | ((exp>>5) & 0x06) | (msd & 0x01);
comb = 0x18 | (msd & 0x01) | ((exp >> 5) & 0x06); else comb=((exp>>3) & 0x18) | msd;
else
comb = (msd & 0x07) | ((exp >> 3) & 0x18);
d32->bytes[0] = (uByte) (comb << 2);
exp &= 0x3f; /* remaining exponent bits */
decimal32SetExpCon (d32, exp);
} }
targ|=comb<<26; /* add combination field .. */
targ|=(exp&0x3f)<<20; /* .. and exponent continuation */
} /* finite */
if (dn->bits&DECNEG) targ|=0x80000000; /* add sign bit */
if (isneg) /* now write to storage; this is endian */
decimal32SetSign (d32, 1); pu=(uInt *)d32->bytes; /* overlay */
if (status != 0) *pu=targ; /* directly store the int */
decContextSetStatus (set, status); /* pass on status */
/*decimal32Show(d32); */ if (status!=0) decContextSetStatus(set, status); /* pass on status */
/* decimal32Show(d32); */
return d32; return d32;
} } /* decimal32FromNumber */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* decimal32ToNumber -- convert decimal32 to decNumber */ /* decimal32ToNumber -- convert decimal32 to decNumber */
...@@ -189,65 +193,53 @@ decimal32FromNumber (decimal32 * d32, const decNumber * dn, decContext * set) ...@@ -189,65 +193,53 @@ decimal32FromNumber (decimal32 * d32, const decNumber * dn, decContext * set)
/* dn is the target number, with appropriate space */ /* dn is the target number, with appropriate space */
/* No error is possible. */ /* No error is possible. */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
decNumber * decNumber * decimal32ToNumber(const decimal32 *d32, decNumber *dn) {
decimal32ToNumber (const decimal32 * d32, decNumber * dn)
{
uInt msd; /* coefficient MSD */ uInt msd; /* coefficient MSD */
decimal32 wk; /* working copy, if needed */ uInt exp; /* exponent top two bits */
uInt top = d32->bytes[0] & 0x7f; /* top byte, less sign bit */ uInt comb; /* combination field */
decNumberZero (dn); /* clean target */ uInt sour; /* source 32-bit */
/* set the sign if negative */ const uInt *pu; /* work */
if (decimal32Sign (d32))
dn->bits = DECNEG; /* load source from storage; this is endian */
pu=(const uInt *)d32->bytes; /* overlay */
if (top >= 0x78) sour=*pu; /* directly load the int */
{ /* is a special */
if ((top & 0x7c) == (DECIMAL_Inf & 0x7c)) comb=(sour>>26)&0x1f; /* combination field */
dn->bits |= DECINF;
else if ((top & 0x7e) == (DECIMAL_NaN & 0x7e)) decNumberZero(dn); /* clean number */
dn->bits |= DECNAN; if (sour&0x80000000) dn->bits=DECNEG; /* set sign if negative */
else
dn->bits |= DECSNAN; msd=COMBMSD[comb]; /* decode the combination field */
msd = 0; /* no top digit */ exp=COMBEXP[comb]; /* .. */
}
else if (exp==3) { /* is a special */
{ /* have a finite number */ if (msd==0) {
uInt comb = top >> 2; /* combination field */ dn->bits|=DECINF;
uInt exp; /* working exponent */ return dn; /* no coefficient needed */
if (comb >= 0x18)
{
msd = 8 + (comb & 0x01);
exp = (comb & 0x06) << 5; /* MSBs */
} }
else else if (sour&0x02000000) dn->bits|=DECSNAN;
{ else dn->bits|=DECNAN;
msd = comb & 0x07; msd=0; /* no top digit */
exp = (comb & 0x18) << 3;
} }
dn->exponent = exp + decimal32ExpCon (d32) - DECIMAL32_Bias; /* remove bias */ else { /* is a finite number */
dn->exponent=(exp<<6)+((sour>>20)&0x3f)-DECIMAL32_Bias; /* unbiased */
} }
/* get the coefficient, unless infinite */ /* get the coefficient */
if (!(dn->bits & DECINF)) sour&=0x000fffff; /* clean coefficient continuation */
{ if (msd) { /* non-zero msd */
Int bunches = DECIMAL32_Pmax / 3; /* coefficient full bunches to convert */ sour|=msd<<20; /* prefix to coefficient */
Int odd = 0; /* assume MSD is 0 (no odd bunch) */ decDigitsFromDPD(dn, &sour, 3); /* process 3 declets */
if (msd != 0) return dn;
{ /* coefficient has leading non-0 digit */
/* make a copy of the decimal32, with an extra bunch which has */
/* the top digit ready for conversion */
wk = *d32; /* take a copy */
wk.bytes[0] = 0; /* clear all but coecon */
wk.bytes[1] &= 0x0f; /* .. */
wk.bytes[1] |= (msd << 4); /* and prefix MSD */
odd++; /* indicate the extra */
d32 = &wk; /* use the work copy */
}
decDenseUnpackCoeff (d32->bytes, sizeof (d32->bytes), dn, bunches, odd);
} }
/* msd=0 */
if (!sour) return dn; /* easy: coefficient is 0 */
if (sour&0x000ffc00) /* need 2 declets? */
decDigitsFromDPD(dn, &sour, 2); /* process 2 declets */
else
decDigitsFromDPD(dn, &sour, 1); /* process 1 declet */
return dn; return dn;
} } /* decimal32ToNumber */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* to-scientific-string -- conversion to numeric string */ /* to-scientific-string -- conversion to numeric string */
...@@ -263,23 +255,129 @@ decimal32ToNumber (const decimal32 * d32, decNumber * dn) ...@@ -263,23 +255,129 @@ decimal32ToNumber (const decimal32 * d32, decNumber * dn)
/* */ /* */
/* No error is possible, and no status can be set. */ /* No error is possible, and no status can be set. */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
char * char * decimal32ToEngString(const decimal32 *d32, char *string){
decimal32ToString (const decimal32 * d32, char *string)
{
decNumber dn; /* work */ decNumber dn; /* work */
decimal32ToNumber (d32, &dn); decimal32ToNumber(d32, &dn);
decNumberToString (&dn, string); decNumberToEngString(&dn, string);
return string; return string;
} } /* decimal32ToEngString */
char * char * decimal32ToString(const decimal32 *d32, char *string){
decimal32ToEngString (const decimal32 * d32, char *string) uInt msd; /* coefficient MSD */
{ Int exp; /* exponent top two bits or full */
decNumber dn; /* work */ uInt comb; /* combination field */
decimal32ToNumber (d32, &dn); char *cstart; /* coefficient start */
decNumberToEngString (&dn, string); char *c; /* output pointer in string */
const uInt *pu; /* work */
const uByte *u; /* .. */
char *s, *t; /* .. (source, target) */
Int dpd; /* .. */
Int pre, e; /* .. */
uInt sour; /* source 32-bit */
/* load source from storage; this is endian */
pu=(const uInt *)d32->bytes; /* overlay */
sour=*pu; /* directly load the int */
c=string; /* where result will go */
if (((Int)sour)<0) *c++='-'; /* handle sign */
comb=(sour>>26)&0x1f; /* combination field */
msd=COMBMSD[comb]; /* decode the combination field */
exp=COMBEXP[comb]; /* .. */
if (exp==3) {
if (msd==0) { /* infinity */
strcpy(c, "Inf");
strcpy(c+3, "inity");
return string; /* easy */
}
if (sour&0x02000000) *c++='s'; /* sNaN */
strcpy(c, "NaN"); /* complete word */
c+=3; /* step past */
if ((sour&0x000fffff)==0) return string; /* zero payload */
/* otherwise drop through to add integer; set correct exp */
exp=0; msd=0; /* setup for following code */
}
else exp=(exp<<6)+((sour>>20)&0x3f)-DECIMAL32_Bias; /* unbiased */
/* convert 7 digits of significand to characters */
cstart=c; /* save start of coefficient */
if (msd) *c++='0'+(char)msd; /* non-zero most significant digit */
/* Now decode the declets. After extracting each one, it is */
/* decoded to binary and then to a 4-char sequence by table lookup; */
/* the 4-chars are a 1-char length (significant digits, except 000 */
/* has length 0). This allows us to left-align the first declet */
/* with non-zero content, then remaining ones are full 3-char */
/* length. We use fixed-length memcpys because variable-length */
/* causes a subroutine call in GCC. (These are length 4 for speed */
/* and are safe because the array has an extra terminator byte.) */
#define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; \
if (c!=cstart) {memcpy(c, u+1, 4); c+=3;} \
else if (*u) {memcpy(c, u+4-*u, 4); c+=*u;}
dpd=(sour>>10)&0x3ff; /* declet 1 */
dpd2char;
dpd=(sour)&0x3ff; /* declet 2 */
dpd2char;
if (c==cstart) *c++='0'; /* all zeros -- make 0 */
if (exp==0) { /* integer or NaN case -- easy */
*c='\0'; /* terminate */
return string;
}
/* non-0 exponent */
e=0; /* assume no E */
pre=c-cstart+exp;
/* [here, pre-exp is the digits count (==1 for zero)] */
if (exp>0 || pre<-5) { /* need exponential form */
e=pre-1; /* calculate E value */
pre=1; /* assume one digit before '.' */
} /* exponential form */
/* modify the coefficient, adding 0s, '.', and E+nn as needed */
s=c-1; /* source (LSD) */
if (pre>0) { /* ddd.ddd (plain), perhaps with E */
char *dotat=cstart+pre;
if (dotat<c) { /* if embedded dot needed... */
t=c; /* target */
for (; s>=dotat; s--, t--) *t=*s; /* open the gap; leave t at gap */
*t='.'; /* insert the dot */
c++; /* length increased by one */
}
/* finally add the E-part, if needed; it will never be 0, and has */
/* a maximum length of 3 digits (E-101 case) */
if (e!=0) {
*c++='E'; /* starts with E */
*c++='+'; /* assume positive */
if (e<0) {
*(c-1)='-'; /* oops, need '-' */
e=-e; /* uInt, please */
}
u=&BIN2CHAR[e*4]; /* -> length byte */
memcpy(c, u+4-*u, 4); /* copy fixed 4 characters [is safe] */
c+=*u; /* bump pointer appropriately */
}
*c='\0'; /* add terminator */
/*printf("res %s\n", string); */
return string;
} /* pre>0 */
/* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (can never have E) */
t=c+1-pre;
*(t+1)='\0'; /* can add terminator now */
for (; s>=cstart; s--, t--) *t=*s; /* shift whole coefficient right */
c=cstart;
*c++='0'; /* always starts with 0. */
*c++='.';
for (; pre<0; pre++) *c++='0'; /* add any 0's after '.' */
/*printf("res %s\n", string); */
return string; return string;
} } /* decimal32ToString */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* to-number -- conversion from numeric string */ /* to-number -- conversion from numeric string */
...@@ -296,42 +394,102 @@ decimal32ToEngString (const decimal32 * d32, char *string) ...@@ -296,42 +394,102 @@ decimal32ToEngString (const decimal32 * d32, char *string)
/* (setting of status and traps) and for the rounding mode, only. */ /* (setting of status and traps) and for the rounding mode, only. */
/* If an error occurs, the result will be a valid decimal32 NaN. */ /* If an error occurs, the result will be a valid decimal32 NaN. */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
decimal32 * decimal32 * decimal32FromString(decimal32 *result, const char *string,
decimal32FromString (decimal32 * result, const char *string, decContext * set) decContext *set) {
{
decContext dc; /* work */ decContext dc; /* work */
decNumber dn; /* .. */ decNumber dn; /* .. */
decContextDefault (&dc, DEC_INIT_DECIMAL32); /* no traps, please */ decContextDefault(&dc, DEC_INIT_DECIMAL32); /* no traps, please */
dc.round = set->round; /* use supplied rounding */ dc.round=set->round; /* use supplied rounding */
decNumberFromString (&dn, string, &dc); /* will round if needed */ decNumberFromString(&dn, string, &dc); /* will round if needed */
decimal32FromNumber (result, &dn, &dc); decimal32FromNumber(result, &dn, &dc);
if (dc.status != 0) if (dc.status!=0) { /* something happened */
{ /* something happened */ decContextSetStatus(set, dc.status); /* .. pass it on */
decContextSetStatus (set, dc.status); /* .. pass it on */
} }
return result; return result;
} } /* decimal32FromString */
/* ------------------------------------------------------------------ */
/* decimal32IsCanonical -- test whether encoding is canonical */
/* d32 is the source decimal32 */
/* returns 1 if the encoding of d32 is canonical, 0 otherwise */
/* No error is possible. */
/* ------------------------------------------------------------------ */
uint32_t decimal32IsCanonical(const decimal32 *d32) {
decNumber dn; /* work */
decimal32 canon; /* .. */
decContext dc; /* .. */
decContextDefault(&dc, DEC_INIT_DECIMAL32);
decimal32ToNumber(d32, &dn);
decimal32FromNumber(&canon, &dn, &dc);/* canon will now be canonical */
return memcmp(d32, &canon, DECIMAL32_Bytes)==0;
} /* decimal32IsCanonical */
/* ------------------------------------------------------------------ */
/* decimal32Canonical -- copy an encoding, ensuring it is canonical */
/* d32 is the source decimal32 */
/* result is the target (may be the same decimal32) */
/* returns result */
/* No error is possible. */
/* ------------------------------------------------------------------ */
decimal32 * decimal32Canonical(decimal32 *result, const decimal32 *d32) {
decNumber dn; /* work */
decContext dc; /* .. */
decContextDefault(&dc, DEC_INIT_DECIMAL32);
decimal32ToNumber(d32, &dn);
decimal32FromNumber(result, &dn, &dc);/* result will now be canonical */
return result;
} /* decimal32Canonical */
#if DECTRACE || DECCHECK #if DECTRACE || DECCHECK
/* Macros for accessing decimal32 fields. These assume the argument
is a reference (pointer) to the decimal32 structure, and the
decimal32 is in network byte order (big-endian) */
/* Get sign */
#define decimal32Sign(d) ((unsigned)(d)->bytes[0]>>7)
/* Get combination field */
#define decimal32Comb(d) (((d)->bytes[0] & 0x7c)>>2)
/* Get exponent continuation [does not remove bias] */
#define decimal32ExpCon(d) ((((d)->bytes[0] & 0x03)<<4) \
| ((unsigned)(d)->bytes[1]>>4))
/* Set sign [this assumes sign previously 0] */
#define decimal32SetSign(d, b) { \
(d)->bytes[0]|=((unsigned)(b)<<7);}
/* Set exponent continuation [does not apply bias] */
/* This assumes range has been checked and exponent previously 0; */
/* type of exponent must be unsigned */
#define decimal32SetExpCon(d, e) { \
(d)->bytes[0]|=(uint8_t)((e)>>4); \
(d)->bytes[1]|=(uint8_t)(((e)&0x0F)<<4);}
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* decimal32Show -- display a single in hexadecimal [debug aid] */ /* decimal32Show -- display a decimal32 in hexadecimal [debug aid] */
/* d32 -- the number to show */ /* d32 -- the number to show */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* Also shows sign/cob/expconfields extracted */ /* Also shows sign/cob/expconfields extracted - valid bigendian only */
void void decimal32Show(const decimal32 *d32) {
decimal32Show (const decimal32 * d32) char buf[DECIMAL32_Bytes*2+1];
{ Int i, j=0;
char buf[DECIMAL32_Bytes * 2 + 1];
Int i, j; if (DECLITEND) {
j = 0; for (i=0; i<DECIMAL32_Bytes; i++, j+=2) {
for (i = 0; i < DECIMAL32_Bytes; i++) sprintf(&buf[j], "%02x", d32->bytes[3-i]);
{ }
sprintf (&buf[j], "%02x", d32->bytes[i]); printf(" D32> %s [S:%d Cb:%02x Ec:%02x] LittleEndian\n", buf,
j = j + 2; d32->bytes[3]>>7, (d32->bytes[3]>>2)&0x1f,
((d32->bytes[3]&0x3)<<4)| (d32->bytes[2]>>4));
}
else {
for (i=0; i<DECIMAL32_Bytes; i++, j+=2) {
sprintf(&buf[j], "%02x", d32->bytes[i]);
}
printf(" D32> %s [S:%d Cb:%02x Ec:%02x] BigEndian\n", buf,
decimal32Sign(d32), decimal32Comb(d32), decimal32ExpCon(d32));
} }
printf (" D32> %s [S:%d Cb:%02x E:%d]\n", buf, } /* decimal32Show */
decimal32Sign (d32), decimal32Comb (d32), decimal32ExpCon (d32));
}
#endif #endif
/* Decimal 32-bit format module header for the decNumber C Library /* Decimal 32-bit format module header for the decNumber C Library.
Copyright (C) 2005 Free Software Foundation, Inc. Copyright (C) 2005, 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw. Contributed by IBM Corporation. Author Mike Cowlishaw.
This file is part of GCC. This file is part of GCC.
...@@ -28,93 +28,72 @@ ...@@ -28,93 +28,72 @@
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */ 02110-1301, USA. */
/* ------------------------------------------------------------------ */
/* Decimal 32-bit format module header */
/* ------------------------------------------------------------------ */
#if !defined(DECIMAL32) #if !defined(DECIMAL32)
#define DECIMAL32 #define DECIMAL32
#define DEC32NAME "decimal32" /* Short name */ #define DEC32NAME "decimal32" /* Short name */
#define DEC32FULLNAME "Decimal 32-bit Number" /* Verbose name */ #define DEC32FULLNAME "Decimal 32-bit Number" /* Verbose name */
#define DEC32AUTHOR "Mike Cowlishaw" /* Who to blame */ #define DEC32AUTHOR "Mike Cowlishaw" /* Who to blame */
/* parameters for decimal32s */ /* parameters for decimal32s */
#define DECIMAL32_Bytes 4 /* length */ #define DECIMAL32_Bytes 4 /* length */
#define DECIMAL32_Pmax 7 /* maximum precision (digits) */ #define DECIMAL32_Pmax 7 /* maximum precision (digits) */
#define DECIMAL32_Emax 96 /* maximum adjusted exponent */ #define DECIMAL32_Emax 96 /* maximum adjusted exponent */
#define DECIMAL32_Emin -95 /* minimum adjusted exponent */ #define DECIMAL32_Emin -95 /* minimum adjusted exponent */
#define DECIMAL32_Bias 101 /* bias for the exponent */ #define DECIMAL32_Bias 101 /* bias for the exponent */
#define DECIMAL32_String 15 /* maximum string length, +1 */ #define DECIMAL32_String 15 /* maximum string length, +1 */
#define DECIMAL32_EconL 6 /* exp. continuation length */
/* highest biased exponent (Elimit-1) */ /* highest biased exponent (Elimit-1) */
#define DECIMAL32_Ehigh (DECIMAL32_Emax+DECIMAL32_Bias-DECIMAL32_Pmax+1) #define DECIMAL32_Ehigh (DECIMAL32_Emax+DECIMAL32_Bias-DECIMAL32_Pmax+1)
#ifndef DECNUMDIGITS /* check enough digits, if pre-defined */
#define DECNUMDIGITS DECIMAL32_Pmax /* size if not already defined */ #if defined(DECNUMDIGITS)
#endif #if (DECNUMDIGITS<DECIMAL32_Pmax)
#ifndef DECNUMBER #error decimal32.h needs pre-defined DECNUMDIGITS>=7 for safe use
#include "decNumber.h" /* context and number library */ #endif
#endif #endif
#ifndef DECNUMDIGITS
#define DECNUMDIGITS DECIMAL32_Pmax /* size if not already defined*/
#endif
#ifndef DECNUMBER
#include "decNumber.h" /* context and number library */
#endif
/* Decimal 32-bit type, accessible by bytes */ /* Decimal 32-bit type, accessible by bytes */
typedef struct typedef struct {
{ uint8_t bytes[DECIMAL32_Bytes]; /* decimal32: 1, 5, 6, 20 bits*/
uint8_t bytes[DECIMAL32_Bytes]; /* decimal32: 1, 5, 6, 20 bits */ } decimal32;
} decimal32;
/* special values [top byte excluding sign bit; last two bits are */
/* special values [top byte excluding sign bit; last two bits are /* don't-care for Infinity on input, last bit don't-care for NaN] */
don't-care for Infinity on input, last bit don't-care for NaN] */ #if !defined(DECIMAL_NaN)
#if !defined(DECIMAL_NaN) #define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */
#define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */ #define DECIMAL_sNaN 0x7e /* 0 11111 10 sNaN */
#define DECIMAL_sNaN 0x7e /* 0 11111 10 sNaN */ #define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */
#define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */ #endif
#endif
/* ---------------------------------------------------------------- */
/* Macros for accessing decimal32 fields. These assume the argument /* Routines */
is a reference (pointer) to the decimal32 structure */ /* ---------------------------------------------------------------- */
/* Get sign */
#define decimal32Sign(d) ((unsigned)(d)->bytes[0]>>7)
/* Get combination field */
#define decimal32Comb(d) (((d)->bytes[0] & 0x7c)>>2)
/* Get exponent continuation [does not remove bias] */
#define decimal32ExpCon(d) ((((d)->bytes[0] & 0x03)<<4) \
| ((unsigned)(d)->bytes[1]>>4))
/* Set sign [this assumes sign previously 0] */
#define decimal32SetSign(d, b) { \
(d)->bytes[0]|=((unsigned)(b)<<7);}
/* Clear sign */
#define decimal32ClearSign(d) {(d)->bytes[0]&=~0x80;}
/* Flip sign */
#define decimal32FlipSign(d) {(d)->bytes[0]^=0x80;}
/* Set exponent continuation [does not apply bias] */ #include "decimal32Symbols.h"
/* This assumes range has been checked and exponent previously 0; */
/* type of exponent must be unsigned */
#define decimal32SetExpCon(d, e) { \
(d)->bytes[0]|=(uint8_t)((e)>>4); \
(d)->bytes[1]|=(uint8_t)(((e)&0x0F)<<4);}
/* ------------------------------------------------------------------ */ /* String conversions */
/* Routines */ decimal32 * decimal32FromString(decimal32 *, const char *, decContext *);
/* ------------------------------------------------------------------ */ char * decimal32ToString(const decimal32 *, char *);
char * decimal32ToEngString(const decimal32 *, char *);
#ifdef IN_LIBGCC2
#ifndef decimal32FromString
#define decimal32FromString __decimal32FromString
#define decimal32ToString __decimal32ToString
#define decimal32ToEngString __decimal32ToEngString
#define decimal32FromNumber __decimal32FromNumber
#define decimal32ToNumber __decimal32ToNumber
#endif
#endif
/* String conversions. */ /* decNumber conversions */
decimal32 *decimal32FromString (decimal32 *, const char *, decContext *); decimal32 * decimal32FromNumber(decimal32 *, const decNumber *,
char *decimal32ToString (const decimal32 *, char *); decContext *);
char *decimal32ToEngString (const decimal32 *, char *); decNumber * decimal32ToNumber(const decimal32 *, decNumber *);
/* decNumber conversions. */ /* Format-dependent utilities */
decimal32 *decimal32FromNumber (decimal32 *, const decNumber *, decContext *); uint32_t decimal32IsCanonical(const decimal32 *);
decNumber *decimal32ToNumber (const decimal32 *, decNumber *); decimal32 * decimal32Canonical(decimal32 *, const decimal32 *);
#endif #endif
#if !defined(DECIMAL32SYMBOLS)
#define DECIMAL32SYMBOLS
#ifdef IN_LIBGCC2
#define decDigitsFromDPD __decDigitsFromDPD
#define decDigitsToDPD __decDigitsToDPD
#define decimal32Canonical __decimal32Canonical
#define decimal32FromNumber __decimal32FromNumber
#define decimal32FromString __decimal32FromString
#define decimal32IsCanonical __decimal32IsCanonical
#define decimal32ToEngString __decimal32ToEngString
#define decimal32ToNumber __decimal32ToNumber
#define decimal32ToString __decimal32ToString
#endif
#endif
/* Decimal 64-bit format module for the decNumber C Library /* Decimal 64-bit format module for the decNumber C Library.
Copyright (C) 2005 Free Software Foundation, Inc. Copyright (C) 2005, 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw. Contributed by IBM Corporation. Author Mike Cowlishaw.
This file is part of GCC. This file is part of GCC.
...@@ -29,32 +29,53 @@ ...@@ -29,32 +29,53 @@
02110-1301, USA. */ 02110-1301, USA. */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* Decimal 64-bit format module */
/* ------------------------------------------------------------------ */
/* This module comprises the routines for decimal64 format numbers. */ /* This module comprises the routines for decimal64 format numbers. */
/* Conversions are supplied to and from decNumber and String. */ /* Conversions are supplied to and from decNumber and String. */
/* */ /* */
/* No arithmetic routines are included; decNumber provides these. */ /* This is used when decNumber provides operations, either for all */
/* operations or as a proxy between decNumber and decSingle. */
/* */ /* */
/* Error handling is the same as decNumber (qv.). */ /* Error handling is the same as decNumber (qv.). */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
#include <string.h> /* [for memset/memcpy] */ #include <string.h> /* [for memset/memcpy] */
#include <stdio.h> /* [for printf] */ #include <stdio.h> /* [for printf] */
#define DECNUMDIGITS 16 /* we need decNumbers with space for 16 */ #include "config.h" /* GCC definitions */
#include "config.h" #define DECNUMDIGITS 16 /* make decNumbers with space for 16 */
#include "decNumber.h" /* base number library */ #include "decNumber.h" /* base number library */
#include "decNumberLocal.h" /* decNumber local types, etc. */ #include "decNumberLocal.h" /* decNumber local types, etc. */
#include "decimal64.h" /* our primary include */ #include "decimal64.h" /* our primary include */
#include "decUtility.h" /* utility routines */
/* Utility routines and tables [in decimal64.c]; externs for C++ */
/* DPD2BIN and the reverse are renamed to prevent link-time conflict */
/* if decQuad is also built in the same executable */
#define DPD2BIN DPD2BINx
#define BIN2DPD BIN2DPDx
extern const uInt COMBEXP[32], COMBMSD[32];
extern const uShort DPD2BIN[1024];
extern const uShort BIN2DPD[1000];
extern const uByte BIN2CHAR[4001];
extern void decDigitsFromDPD(decNumber *, const uInt *, Int);
extern void decDigitsToDPD(const decNumber *, uInt *, Int);
#if DECTRACE || DECCHECK #if DECTRACE || DECCHECK
void decimal64Show (const decimal64 *); /* for debug */ void decimal64Show(const decimal64 *); /* for debug */
void decNumberShow (const decNumber *); /* .. */ extern void decNumberShow(const decNumber *); /* .. */
#endif #endif
/* Useful macro */ /* Useful macro */
/* Clear a structure (e.g., a decNumber) */ /* Clear a structure (e.g., a decNumber) */
#define DEC_clear(d) memset(d, 0, sizeof(*d)) #define DEC_clear(d) memset(d, 0, sizeof(*d))
/* define and include the tables to use for conversions */
#define DEC_BIN2CHAR 1
#define DEC_DPD2BIN 1
#define DEC_BIN2DPD 1 /* used for all sizes */
#include "decDPD.h" /* lookup tables */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* decimal64FromNumber -- convert decNumber to decimal64 */ /* decimal64FromNumber -- convert decNumber to decimal64 */
/* */ /* */
...@@ -72,115 +93,124 @@ void decNumberShow (const decNumber *); /* .. */ ...@@ -72,115 +93,124 @@ void decNumberShow (const decNumber *); /* .. */
/* by reducing its exponent and multiplying the coefficient by a */ /* by reducing its exponent and multiplying the coefficient by a */
/* power of ten, or if the exponent on a zero had to be clamped. */ /* power of ten, or if the exponent on a zero had to be clamped. */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
decimal64 * decimal64 * decimal64FromNumber(decimal64 *d64, const decNumber *dn,
decimal64FromNumber (decimal64 * d64, const decNumber * dn, decContext * set) decContext *set) {
{ uInt status=0; /* status accumulator */
uInt status = 0; /* status accumulator */ Int ae; /* adjusted exponent */
Int pad = 0; /* coefficient pad digits */
decNumber dw; /* work */ decNumber dw; /* work */
decContext dc; /* .. */ decContext dc; /* .. */
uByte isneg = dn->bits & DECNEG; /* non-0 if original sign set */ uInt *pu; /* .. */
uInt comb, exp; /* work */ uInt comb, exp; /* .. */
uInt targar[2]={0, 0}; /* target 64-bit */
/* If the number is finite, and has too many digits, or the exponent */ #define targhi targar[1] /* name the word with the sign */
/* could be out of range then we reduce the number under the */ #define targlo targar[0] /* and the other */
/* appropriate constraints */
if (!(dn->bits & DECSPECIAL)) /* If the number has too many digits, or the exponent could be */
{ /* not a special value */ /* out of range then reduce the number under the appropriate */
Int ae = dn->exponent + dn->digits - 1; /* adjusted exponent */ /* constraints. This could push the number to Infinity or zero, */
if (dn->digits > DECIMAL64_Pmax /* too many digits */ /* so this check and rounding must be done before generating the */
|| ae > DECIMAL64_Emax /* likely overflow */ /* decimal64] */
|| ae < DECIMAL64_Emin) ae=dn->exponent+dn->digits-1; /* [0 if special] */
{ /* likely underflow */ if (dn->digits>DECIMAL64_Pmax /* too many digits */
decContextDefault (&dc, DEC_INIT_DECIMAL64); /* [no traps] */ || ae>DECIMAL64_Emax /* likely overflow */
dc.round = set->round; /* use supplied rounding */ || ae<DECIMAL64_Emin) { /* likely underflow */
decNumberPlus (&dw, dn, &dc); /* (round and check) */ decContextDefault(&dc, DEC_INIT_DECIMAL64); /* [no traps] */
/* [this changes -0 to 0, but it will be restored below] */ dc.round=set->round; /* use supplied rounding */
status |= dc.status; /* save status */ decNumberPlus(&dw, dn, &dc); /* (round and check) */
dn = &dw; /* use the work number */ /* [this changes -0 to 0, so enforce the sign...] */
} dw.bits|=dn->bits&DECNEG;
/* [this could have pushed number to Infinity or zero, so this */ status=dc.status; /* save status */
/* rounding must be done before we generate the decimal64] */ dn=&dw; /* use the work number */
} } /* maybe out of range */
DEC_clear (d64); /* clean the target */ if (dn->bits&DECSPECIAL) { /* a special value */
if (dn->bits & DECSPECIAL) if (dn->bits&DECINF) targhi=DECIMAL_Inf<<24;
{ /* a special value */ else { /* sNaN or qNaN */
uByte top; /* work */ if ((*dn->lsu!=0 || dn->digits>1) /* non-zero coefficient */
if (dn->bits & DECINF) && (dn->digits<DECIMAL64_Pmax)) { /* coefficient fits */
top = DECIMAL_Inf; decDigitsToDPD(dn, targar, 0);
else }
{ /* sNaN or qNaN */ if (dn->bits&DECNAN) targhi|=DECIMAL_NaN<<24;
if ((*dn->lsu != 0 || dn->digits > 1) /* non-zero coefficient */ else targhi|=DECIMAL_sNaN<<24;
&& (dn->digits < DECIMAL64_Pmax)) } /* a NaN */
{ /* coefficient fits */ } /* special */
decDensePackCoeff (dn, d64->bytes, sizeof (d64->bytes), 0);
} else { /* is finite */
if (dn->bits & DECNAN) if (decNumberIsZero(dn)) { /* is a zero */
top = DECIMAL_NaN;
else
top = DECIMAL_sNaN;
}
d64->bytes[0] = top;
}
else if (decNumberIsZero (dn))
{ /* a zero */
/* set and clamp exponent */ /* set and clamp exponent */
if (dn->exponent < -DECIMAL64_Bias) if (dn->exponent<-DECIMAL64_Bias) {
{ exp=0; /* low clamp */
exp = 0; status|=DEC_Clamped;
status |= DEC_Clamped; }
} else {
else exp=dn->exponent+DECIMAL64_Bias; /* bias exponent */
{ if (exp>DECIMAL64_Ehigh) { /* top clamp */
exp = dn->exponent + DECIMAL64_Bias; /* bias exponent */ exp=DECIMAL64_Ehigh;
if (exp > DECIMAL64_Ehigh) status|=DEC_Clamped;
{ /* top clamp */ }
exp = DECIMAL64_Ehigh; }
status |= DEC_Clamped; comb=(exp>>5) & 0x18; /* msd=0, exp top 2 bits .. */
} }
} else { /* non-zero finite number */
comb = (exp >> 5) & 0x18; /* combination field */
d64->bytes[0] = (uByte) (comb << 2);
exp &= 0xff; /* remaining exponent bits */
decimal64SetExpCon (d64, exp);
}
else
{ /* non-zero finite number */
uInt msd; /* work */ uInt msd; /* work */
Int pad=0; /* coefficient pad digits */
/* we have a dn that fits, but it may need to be padded */ /* the dn is known to fit, but it may need to be padded */
exp = (uInt) (dn->exponent + DECIMAL64_Bias); /* bias exponent */ exp=(uInt)(dn->exponent+DECIMAL64_Bias); /* bias exponent */
if (exp > DECIMAL64_Ehigh) if (exp>DECIMAL64_Ehigh) { /* fold-down case */
{ /* fold-down case */ pad=exp-DECIMAL64_Ehigh;
pad = exp - DECIMAL64_Ehigh; exp=DECIMAL64_Ehigh; /* [to maximum] */
exp = DECIMAL64_Ehigh; /* [to maximum] */ status|=DEC_Clamped;
status |= DEC_Clamped;
} }
decDensePackCoeff (dn, d64->bytes, sizeof (d64->bytes), pad); /* fastpath common case */
if (DECDPUN==3 && pad==0) {
uInt dpd[6]={0,0,0,0,0,0};
uInt i;
Int d=dn->digits;
for (i=0; d>0; i++, d-=3) dpd[i]=BIN2DPD[dn->lsu[i]];
targlo =dpd[0];
targlo|=dpd[1]<<10;
targlo|=dpd[2]<<20;
if (dn->digits>6) {
targlo|=dpd[3]<<30;
targhi =dpd[3]>>2;
targhi|=dpd[4]<<8;
}
msd=dpd[5]; /* [did not really need conversion] */
}
else { /* general case */
decDigitsToDPD(dn, targar, pad);
/* save and clear the top digit */ /* save and clear the top digit */
msd = ((unsigned) d64->bytes[1] >> 2) & 0x0f; msd=targhi>>18;
d64->bytes[1] &= 0x03; targhi&=0x0003ffff;
}
/* create the combination field */ /* create the combination field */
if (msd >= 8) if (msd>=8) comb=0x18 | ((exp>>7) & 0x06) | (msd & 0x01);
comb = 0x18 | (msd & 0x01) | ((exp >> 7) & 0x06); else comb=((exp>>5) & 0x18) | msd;
else
comb = (msd & 0x07) | ((exp >> 5) & 0x18);
d64->bytes[0] = (uByte) (comb << 2);
exp &= 0xff; /* remaining exponent bits */
decimal64SetExpCon (d64, exp);
} }
targhi|=comb<<26; /* add combination field .. */
targhi|=(exp&0xff)<<18; /* .. and exponent continuation */
} /* finite */
if (isneg) if (dn->bits&DECNEG) targhi|=0x80000000; /* add sign bit */
decimal64SetSign (d64, 1);
if (status != 0)
decContextSetStatus (set, status); /* pass on status */
/*decimal64Show(d64); */ /* now write to storage; this is now always endian */
pu=(uInt *)d64->bytes; /* overlay */
if (DECLITEND) {
pu[0]=targar[0]; /* directly store the low int */
pu[1]=targar[1]; /* then the high int */
}
else {
pu[0]=targar[1]; /* directly store the high int */
pu[1]=targar[0]; /* then the low int */
}
if (status!=0) decContextSetStatus(set, status); /* pass on status */
/* decimal64Show(d64); */
return d64; return d64;
} } /* decimal64FromNumber */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* decimal64ToNumber -- convert decimal64 to decNumber */ /* decimal64ToNumber -- convert decimal64 to decNumber */
...@@ -188,65 +218,71 @@ decimal64FromNumber (decimal64 * d64, const decNumber * dn, decContext * set) ...@@ -188,65 +218,71 @@ decimal64FromNumber (decimal64 * d64, const decNumber * dn, decContext * set)
/* dn is the target number, with appropriate space */ /* dn is the target number, with appropriate space */
/* No error is possible. */ /* No error is possible. */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
decNumber * decNumber * decimal64ToNumber(const decimal64 *d64, decNumber *dn) {
decimal64ToNumber (const decimal64 * d64, decNumber * dn)
{
uInt msd; /* coefficient MSD */ uInt msd; /* coefficient MSD */
decimal64 wk; /* working copy, if needed */ uInt exp; /* exponent top two bits */
uInt top = d64->bytes[0] & 0x7f; /* top byte, less sign bit */ uInt comb; /* combination field */
decNumberZero (dn); /* clean target */ const uInt *pu; /* work */
/* set the sign if negative */ Int need; /* .. */
if (decimal64Sign (d64)) uInt sourar[2]; /* source 64-bit */
dn->bits = DECNEG; #define sourhi sourar[1] /* name the word with the sign */
#define sourlo sourar[0] /* and the lower word */
if (top >= 0x78)
{ /* is a special */ /* load source from storage; this is endian */
if ((top & 0x7c) == (DECIMAL_Inf & 0x7c)) pu=(const uInt *)d64->bytes; /* overlay */
dn->bits |= DECINF; if (DECLITEND) {
else if ((top & 0x7e) == (DECIMAL_NaN & 0x7e)) sourlo=pu[0]; /* directly load the low int */
dn->bits |= DECNAN; sourhi=pu[1]; /* then the high int */
else }
dn->bits |= DECSNAN; else {
msd = 0; /* no top digit */ sourhi=pu[0]; /* directly load the high int */
} sourlo=pu[1]; /* then the low int */
else }
{ /* have a finite number */
uInt comb = top >> 2; /* combination field */ comb=(sourhi>>26)&0x1f; /* combination field */
uInt exp; /* exponent */
decNumberZero(dn); /* clean number */
if (comb >= 0x18) if (sourhi&0x80000000) dn->bits=DECNEG; /* set sign if negative */
{
msd = 8 + (comb & 0x01); msd=COMBMSD[comb]; /* decode the combination field */
exp = (comb & 0x06) << 7; /* MSBs */ exp=COMBEXP[comb]; /* .. */
}
else if (exp==3) { /* is a special */
{ if (msd==0) {
msd = comb & 0x07; dn->bits|=DECINF;
exp = (comb & 0x18) << 5; return dn; /* no coefficient needed */
}
dn->exponent = exp + decimal64ExpCon (d64) - DECIMAL64_Bias; /* remove bias */
}
/* get the coefficient, unless infinite */
if (!(dn->bits & DECINF))
{
Int bunches = DECIMAL64_Pmax / 3; /* coefficient full bunches to convert */
Int odd = 0; /* assume MSD is 0 (no odd bunch) */
if (msd != 0)
{ /* coefficient has leading non-0 digit */
/* make a copy of the decimal64, with an extra bunch which has */
/* the top digit ready for conversion */
wk = *d64; /* take a copy */
wk.bytes[0] = 0; /* clear all but coecon */
wk.bytes[1] &= 0x03; /* .. */
wk.bytes[1] |= (msd << 2); /* and prefix MSD */
odd++; /* indicate the extra */
d64 = &wk; /* use the work copy */
}
decDenseUnpackCoeff (d64->bytes, sizeof (d64->bytes), dn, bunches, odd);
} }
else if (sourhi&0x02000000) dn->bits|=DECSNAN;
else dn->bits|=DECNAN;
msd=0; /* no top digit */
}
else { /* is a finite number */
dn->exponent=(exp<<8)+((sourhi>>18)&0xff)-DECIMAL64_Bias; /* unbiased */
}
/* get the coefficient */
sourhi&=0x0003ffff; /* clean coefficient continuation */
if (msd) { /* non-zero msd */
sourhi|=msd<<18; /* prefix to coefficient */
need=6; /* process 6 declets */
}
else { /* msd=0 */
if (!sourhi) { /* top word 0 */
if (!sourlo) return dn; /* easy: coefficient is 0 */
need=3; /* process at least 3 declets */
if (sourlo&0xc0000000) need++; /* process 4 declets */
/* [could reduce some more, here] */
}
else { /* some bits in top word, msd=0 */
need=4; /* process at least 4 declets */
if (sourhi&0x0003ff00) need++; /* top declet!=0, process 5 */
}
} /*msd=0 */
decDigitsFromDPD(dn, sourar, need); /* process declets */
return dn; return dn;
} } /* decimal64ToNumber */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* to-scientific-string -- conversion to numeric string */ /* to-scientific-string -- conversion to numeric string */
...@@ -262,23 +298,145 @@ decimal64ToNumber (const decimal64 * d64, decNumber * dn) ...@@ -262,23 +298,145 @@ decimal64ToNumber (const decimal64 * d64, decNumber * dn)
/* */ /* */
/* No error is possible, and no status can be set. */ /* No error is possible, and no status can be set. */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
char * char * decimal64ToEngString(const decimal64 *d64, char *string){
decimal64ToString (const decimal64 * d64, char *string)
{
decNumber dn; /* work */ decNumber dn; /* work */
decimal64ToNumber (d64, &dn); decimal64ToNumber(d64, &dn);
decNumberToString (&dn, string); decNumberToEngString(&dn, string);
return string; return string;
} } /* decimal64ToEngString */
char * char * decimal64ToString(const decimal64 *d64, char *string){
decimal64ToEngString (const decimal64 * d64, char *string) uInt msd; /* coefficient MSD */
{ Int exp; /* exponent top two bits or full */
decNumber dn; /* work */ uInt comb; /* combination field */
decimal64ToNumber (d64, &dn); char *cstart; /* coefficient start */
decNumberToEngString (&dn, string); char *c; /* output pointer in string */
const uInt *pu; /* work */
char *s, *t; /* .. (source, target) */
Int dpd; /* .. */
Int pre, e; /* .. */
const uByte *u; /* .. */
uInt sourar[2]; /* source 64-bit */
#define sourhi sourar[1] /* name the word with the sign */
#define sourlo sourar[0] /* and the lower word */
/* load source from storage; this is endian */
pu=(const uInt *)d64->bytes; /* overlay */
if (DECLITEND) {
sourlo=pu[0]; /* directly load the low int */
sourhi=pu[1]; /* then the high int */
}
else {
sourhi=pu[0]; /* directly load the high int */
sourlo=pu[1]; /* then the low int */
}
c=string; /* where result will go */
if (((Int)sourhi)<0) *c++='-'; /* handle sign */
comb=(sourhi>>26)&0x1f; /* combination field */
msd=COMBMSD[comb]; /* decode the combination field */
exp=COMBEXP[comb]; /* .. */
if (exp==3) {
if (msd==0) { /* infinity */
strcpy(c, "Inf");
strcpy(c+3, "inity");
return string; /* easy */
}
if (sourhi&0x02000000) *c++='s'; /* sNaN */
strcpy(c, "NaN"); /* complete word */
c+=3; /* step past */
if (sourlo==0 && (sourhi&0x0003ffff)==0) return string; /* zero payload */
/* otherwise drop through to add integer; set correct exp */
exp=0; msd=0; /* setup for following code */
}
else exp=(exp<<8)+((sourhi>>18)&0xff)-DECIMAL64_Bias;
/* convert 16 digits of significand to characters */
cstart=c; /* save start of coefficient */
if (msd) *c++='0'+(char)msd; /* non-zero most significant digit */
/* Now decode the declets. After extracting each one, it is */
/* decoded to binary and then to a 4-char sequence by table lookup; */
/* the 4-chars are a 1-char length (significant digits, except 000 */
/* has length 0). This allows us to left-align the first declet */
/* with non-zero content, then remaining ones are full 3-char */
/* length. We use fixed-length memcpys because variable-length */
/* causes a subroutine call in GCC. (These are length 4 for speed */
/* and are safe because the array has an extra terminator byte.) */
#define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; \
if (c!=cstart) {memcpy(c, u+1, 4); c+=3;} \
else if (*u) {memcpy(c, u+4-*u, 4); c+=*u;}
dpd=(sourhi>>8)&0x3ff; /* declet 1 */
dpd2char;
dpd=((sourhi&0xff)<<2) | (sourlo>>30); /* declet 2 */
dpd2char;
dpd=(sourlo>>20)&0x3ff; /* declet 3 */
dpd2char;
dpd=(sourlo>>10)&0x3ff; /* declet 4 */
dpd2char;
dpd=(sourlo)&0x3ff; /* declet 5 */
dpd2char;
if (c==cstart) *c++='0'; /* all zeros -- make 0 */
if (exp==0) { /* integer or NaN case -- easy */
*c='\0'; /* terminate */
return string; return string;
} }
/* non-0 exponent */
e=0; /* assume no E */
pre=c-cstart+exp;
/* [here, pre-exp is the digits count (==1 for zero)] */
if (exp>0 || pre<-5) { /* need exponential form */
e=pre-1; /* calculate E value */
pre=1; /* assume one digit before '.' */
} /* exponential form */
/* modify the coefficient, adding 0s, '.', and E+nn as needed */
s=c-1; /* source (LSD) */
if (pre>0) { /* ddd.ddd (plain), perhaps with E */
char *dotat=cstart+pre;
if (dotat<c) { /* if embedded dot needed... */
t=c; /* target */
for (; s>=dotat; s--, t--) *t=*s; /* open the gap; leave t at gap */
*t='.'; /* insert the dot */
c++; /* length increased by one */
}
/* finally add the E-part, if needed; it will never be 0, and has */
/* a maximum length of 3 digits */
if (e!=0) {
*c++='E'; /* starts with E */
*c++='+'; /* assume positive */
if (e<0) {
*(c-1)='-'; /* oops, need '-' */
e=-e; /* uInt, please */
}
u=&BIN2CHAR[e*4]; /* -> length byte */
memcpy(c, u+4-*u, 4); /* copy fixed 4 characters [is safe] */
c+=*u; /* bump pointer appropriately */
}
*c='\0'; /* add terminator */
/*printf("res %s\n", string); */
return string;
} /* pre>0 */
/* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (can never have E) */
t=c+1-pre;
*(t+1)='\0'; /* can add terminator now */
for (; s>=cstart; s--, t--) *t=*s; /* shift whole coefficient right */
c=cstart;
*c++='0'; /* always starts with 0. */
*c++='.';
for (; pre<0; pre++) *c++='0'; /* add any 0's after '.' */
/*printf("res %s\n", string); */
return string;
} /* decimal64ToString */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* to-number -- conversion from numeric string */ /* to-number -- conversion from numeric string */
...@@ -295,43 +453,404 @@ decimal64ToEngString (const decimal64 * d64, char *string) ...@@ -295,43 +453,404 @@ decimal64ToEngString (const decimal64 * d64, char *string)
/* (setting of status and traps) and for the rounding mode, only. */ /* (setting of status and traps) and for the rounding mode, only. */
/* If an error occurs, the result will be a valid decimal64 NaN. */ /* If an error occurs, the result will be a valid decimal64 NaN. */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
decimal64 * decimal64 * decimal64FromString(decimal64 *result, const char *string,
decimal64FromString (decimal64 * result, const char *string, decContext * set) decContext *set) {
{
decContext dc; /* work */ decContext dc; /* work */
decNumber dn; /* .. */ decNumber dn; /* .. */
decContextDefault (&dc, DEC_INIT_DECIMAL64); /* no traps, please */ decContextDefault(&dc, DEC_INIT_DECIMAL64); /* no traps, please */
dc.round = set->round; /* use supplied rounding */ dc.round=set->round; /* use supplied rounding */
decNumberFromString (&dn, string, &dc); /* will round if needed */ decNumberFromString(&dn, string, &dc); /* will round if needed */
decimal64FromNumber (result, &dn, &dc); decimal64FromNumber(result, &dn, &dc);
if (dc.status != 0) if (dc.status!=0) { /* something happened */
{ /* something happened */ decContextSetStatus(set, dc.status); /* .. pass it on */
decContextSetStatus (set, dc.status); /* .. pass it on */
} }
return result; return result;
} } /* decimal64FromString */
/* ------------------------------------------------------------------ */
/* decimal64IsCanonical -- test whether encoding is canonical */
/* d64 is the source decimal64 */
/* returns 1 if the encoding of d64 is canonical, 0 otherwise */
/* No error is possible. */
/* ------------------------------------------------------------------ */
uint32_t decimal64IsCanonical(const decimal64 *d64) {
decNumber dn; /* work */
decimal64 canon; /* .. */
decContext dc; /* .. */
decContextDefault(&dc, DEC_INIT_DECIMAL64);
decimal64ToNumber(d64, &dn);
decimal64FromNumber(&canon, &dn, &dc);/* canon will now be canonical */
return memcmp(d64, &canon, DECIMAL64_Bytes)==0;
} /* decimal64IsCanonical */
/* ------------------------------------------------------------------ */
/* decimal64Canonical -- copy an encoding, ensuring it is canonical */
/* d64 is the source decimal64 */
/* result is the target (may be the same decimal64) */
/* returns result */
/* No error is possible. */
/* ------------------------------------------------------------------ */
decimal64 * decimal64Canonical(decimal64 *result, const decimal64 *d64) {
decNumber dn; /* work */
decContext dc; /* .. */
decContextDefault(&dc, DEC_INIT_DECIMAL64);
decimal64ToNumber(d64, &dn);
decimal64FromNumber(result, &dn, &dc);/* result will now be canonical */
return result;
} /* decimal64Canonical */
#if DECTRACE || DECCHECK #if DECTRACE || DECCHECK
/* Macros for accessing decimal64 fields. These assume the
argument is a reference (pointer) to the decimal64 structure,
and the decimal64 is in network byte order (big-endian) */
/* Get sign */
#define decimal64Sign(d) ((unsigned)(d)->bytes[0]>>7)
/* Get combination field */
#define decimal64Comb(d) (((d)->bytes[0] & 0x7c)>>2)
/* Get exponent continuation [does not remove bias] */
#define decimal64ExpCon(d) ((((d)->bytes[0] & 0x03)<<6) \
| ((unsigned)(d)->bytes[1]>>2))
/* Set sign [this assumes sign previously 0] */
#define decimal64SetSign(d, b) { \
(d)->bytes[0]|=((unsigned)(b)<<7);}
/* Set exponent continuation [does not apply bias] */
/* This assumes range has been checked and exponent previously 0; */
/* type of exponent must be unsigned */
#define decimal64SetExpCon(d, e) { \
(d)->bytes[0]|=(uint8_t)((e)>>6); \
(d)->bytes[1]|=(uint8_t)(((e)&0x3F)<<2);}
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* decimal64Show -- display a single in hexadecimal [debug aid] */ /* decimal64Show -- display a decimal64 in hexadecimal [debug aid] */
/* d64 -- the number to show */ /* d64 -- the number to show */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* Also shows sign/cob/expconfields extracted */ /* Also shows sign/cob/expconfields extracted */
void void decimal64Show(const decimal64 *d64) {
decimal64Show (const decimal64 * d64) char buf[DECIMAL64_Bytes*2+1];
{ Int i, j=0;
char buf[DECIMAL64_Bytes * 2 + 1];
Int i, j; if (DECLITEND) {
j = 0; for (i=0; i<DECIMAL64_Bytes; i++, j+=2) {
for (i = 0; i < DECIMAL64_Bytes; i++) sprintf(&buf[j], "%02x", d64->bytes[7-i]);
{ }
sprintf (&buf[j], "%02x", d64->bytes[i]); printf(" D64> %s [S:%d Cb:%02x Ec:%02x] LittleEndian\n", buf,
j = j + 2; d64->bytes[7]>>7, (d64->bytes[7]>>2)&0x1f,
} ((d64->bytes[7]&0x3)<<6)| (d64->bytes[6]>>2));
printf (" D64> %s [S:%d Cb:%02x E:%d]\n", buf, }
decimal64Sign (d64), decimal64Comb (d64), decimal64ExpCon (d64)); else { /* big-endian */
} for (i=0; i<DECIMAL64_Bytes; i++, j+=2) {
sprintf(&buf[j], "%02x", d64->bytes[i]);
}
printf(" D64> %s [S:%d Cb:%02x Ec:%02x] BigEndian\n", buf,
decimal64Sign(d64), decimal64Comb(d64), decimal64ExpCon(d64));
}
} /* decimal64Show */
#endif
/* ================================================================== */
/* Shared utility routines and tables */
/* ================================================================== */
/* define and include the conversion tables to use for shared code */
#if DECDPUN==3
#define DEC_DPD2BIN 1
#else
#define DEC_DPD2BCD 1
#endif #endif
#include "decDPD.h" /* lookup tables */
/* The maximum number of decNumberUnits needed for a working copy of */
/* the units array is the ceiling of digits/DECDPUN, where digits is */
/* the maximum number of digits in any of the formats for which this */
/* is used. decimal128.h must not be included in this module, so, as */
/* a very special case, that number is defined as a literal here. */
#define DECMAX754 34
#define DECMAXUNITS ((DECMAX754+DECDPUN-1)/DECDPUN)
/* ------------------------------------------------------------------ */
/* Combination field lookup tables (uInts to save measurable work) */
/* */
/* COMBEXP - 2-bit most-significant-bits of exponent */
/* [11 if an Infinity or NaN] */
/* COMBMSD - 4-bit most-significant-digit */
/* [0=Infinity, 1=NaN if COMBEXP=11] */
/* */
/* Both are indexed by the 5-bit combination field (0-31) */
/* ------------------------------------------------------------------ */
const uInt COMBEXP[32]={0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2,
0, 0, 1, 1, 2, 2, 3, 3};
const uInt COMBMSD[32]={0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 8, 9, 8, 9, 0, 1};
/* ------------------------------------------------------------------ */
/* decDigitsToDPD -- pack coefficient into DPD form */
/* */
/* dn is the source number (assumed valid, max DECMAX754 digits) */
/* targ is 1, 2, or 4-element uInt array, which the caller must */
/* have cleared to zeros */
/* shift is the number of 0 digits to add on the right (normally 0) */
/* */
/* The coefficient must be known small enough to fit. The full */
/* coefficient is copied, including the leading 'odd' digit. This */
/* digit is retrieved and packed into the combination field by the */
/* caller. */
/* */
/* The target uInts are altered only as necessary to receive the */
/* digits of the decNumber. When more than one uInt is needed, they */
/* are filled from left to right (that is, the uInt at offset 0 will */
/* end up with the least-significant digits). */
/* */
/* shift is used for 'fold-down' padding. */
/* */
/* No error is possible. */
/* ------------------------------------------------------------------ */
#if DECDPUN<=4
/* Constant multipliers for divide-by-power-of five using reciprocal */
/* multiply, after removing powers of 2 by shifting, and final shift */
/* of 17 [we only need up to **4] */
static const uInt multies[]={131073, 26215, 5243, 1049, 210};
/* QUOT10 -- macro to return the quotient of unit u divided by 10**n */
#define QUOT10(u, n) ((((uInt)(u)>>(n))*multies[n])>>17)
#endif
void decDigitsToDPD(const decNumber *dn, uInt *targ, Int shift) {
Int cut; /* work */
Int n; /* output bunch counter */
Int digits=dn->digits; /* digit countdown */
uInt dpd; /* densely packed decimal value */
uInt bin; /* binary value 0-999 */
uInt *uout=targ; /* -> current output uInt */
uInt uoff=0; /* -> current output offset [from right] */
const Unit *inu=dn->lsu; /* -> current input unit */
Unit uar[DECMAXUNITS]; /* working copy of units, iff shifted */
#if DECDPUN!=3 /* not fast path */
Unit in; /* current unit */
#endif
if (shift!=0) { /* shift towards most significant required */
/* shift the units array to the left by pad digits and copy */
/* [this code is a special case of decShiftToMost, which could */
/* be used instead if exposed and the array were copied first] */
const Unit *source; /* .. */
Unit *target, *first; /* .. */
uInt next=0; /* work */
source=dn->lsu+D2U(digits)-1; /* where msu comes from */
target=uar+D2U(digits)-1+D2U(shift);/* where upper part of first cut goes */
cut=DECDPUN-MSUDIGITS(shift); /* where to slice */
if (cut==0) { /* unit-boundary case */
for (; source>=dn->lsu; source--, target--) *target=*source;
}
else {
first=uar+D2U(digits+shift)-1; /* where msu will end up */
for (; source>=dn->lsu; source--, target--) {
/* split the source Unit and accumulate remainder for next */
#if DECDPUN<=4
uInt quot=QUOT10(*source, cut);
uInt rem=*source-quot*DECPOWERS[cut];
next+=quot;
#else
uInt rem=*source%DECPOWERS[cut];
next+=*source/DECPOWERS[cut];
#endif
if (target<=first) *target=(Unit)next; /* write to target iff valid */
next=rem*DECPOWERS[DECDPUN-cut]; /* save remainder for next Unit */
}
} /* shift-move */
/* propagate remainder to one below and clear the rest */
for (; target>=uar; target--) {
*target=(Unit)next;
next=0;
}
digits+=shift; /* add count (shift) of zeros added */
inu=uar; /* use units in working array */
}
/* now densely pack the coefficient into DPD declets */
#if DECDPUN!=3 /* not fast path */
in=*inu; /* current unit */
cut=0; /* at lowest digit */
bin=0; /* [keep compiler quiet] */
#endif
for(n=0; digits>0; n++) { /* each output bunch */
#if DECDPUN==3 /* fast path, 3-at-a-time */
bin=*inu; /* 3 digits ready for convert */
digits-=3; /* [may go negative] */
inu++; /* may need another */
#else /* must collect digit-by-digit */
Unit dig; /* current digit */
Int j; /* digit-in-declet count */
for (j=0; j<3; j++) {
#if DECDPUN<=4
Unit temp=(Unit)((uInt)(in*6554)>>16);
dig=(Unit)(in-X10(temp));
in=temp;
#else
dig=in%10;
in=in/10;
#endif
if (j==0) bin=dig;
else if (j==1) bin+=X10(dig);
else /* j==2 */ bin+=X100(dig);
digits--;
if (digits==0) break; /* [also protects *inu below] */
cut++;
if (cut==DECDPUN) {inu++; in=*inu; cut=0;}
}
#endif
/* here there are 3 digits in bin, or have used all input digits */
dpd=BIN2DPD[bin];
/* write declet to uInt array */
*uout|=dpd<<uoff;
uoff+=10;
if (uoff<32) continue; /* no uInt boundary cross */
uout++;
uoff-=32;
*uout|=dpd>>(10-uoff); /* collect top bits */
} /* n declets */
return;
} /* decDigitsToDPD */
/* ------------------------------------------------------------------ */
/* decDigitsFromDPD -- unpack a format's coefficient */
/* */
/* dn is the target number, with 7, 16, or 34-digit space. */
/* sour is a 1, 2, or 4-element uInt array containing only declets */
/* declets is the number of (right-aligned) declets in sour to */
/* be processed. This may be 1 more than the obvious number in */
/* a format, as any top digit is prefixed to the coefficient */
/* continuation field. It also may be as small as 1, as the */
/* caller may pre-process leading zero declets. */
/* */
/* When doing the 'extra declet' case care is taken to avoid writing */
/* extra digits when there are leading zeros, as these could overflow */
/* the units array when DECDPUN is not 3. */
/* */
/* The target uInts are used only as necessary to process declets */
/* declets into the decNumber. When more than one uInt is needed, */
/* they are used from left to right (that is, the uInt at offset 0 */
/* provides the least-significant digits). */
/* */
/* dn->digits is set, but not the sign or exponent. */
/* No error is possible [the redundant 888 codes are allowed]. */
/* ------------------------------------------------------------------ */
void decDigitsFromDPD(decNumber *dn, const uInt *sour, Int declets) {
uInt dpd; /* collector for 10 bits */
Int n; /* counter */
Unit *uout=dn->lsu; /* -> current output unit */
Unit *last=uout; /* will be unit containing msd */
const uInt *uin=sour; /* -> current input uInt */
uInt uoff=0; /* -> current input offset [from right] */
#if DECDPUN!=3
uInt bcd; /* BCD result */
uInt nibble; /* work */
Unit out=0; /* accumulator */
Int cut=0; /* power of ten in current unit */
#endif
#if DECDPUN>4
uInt const *pow; /* work */
#endif
/* Expand the densely-packed integer, right to left */
for (n=declets-1; n>=0; n--) { /* count down declets of 10 bits */
dpd=*uin>>uoff;
uoff+=10;
if (uoff>32) { /* crossed uInt boundary */
uin++;
uoff-=32;
dpd|=*uin<<(10-uoff); /* get waiting bits */
}
dpd&=0x3ff; /* clear uninteresting bits */
#if DECDPUN==3
if (dpd==0) *uout=0;
else {
*uout=DPD2BIN[dpd]; /* convert 10 bits to binary 0-999 */
last=uout; /* record most significant unit */
}
uout++;
} /* n */
#else /* DECDPUN!=3 */
if (dpd==0) { /* fastpath [e.g., leading zeros] */
/* write out three 0 digits (nibbles); out may have digit(s) */
cut++;
if (cut==DECDPUN) {*uout=out; if (out) {last=uout; out=0;} uout++; cut=0;}
if (n==0) break; /* [as below, works even if MSD=0] */
cut++;
if (cut==DECDPUN) {*uout=out; if (out) {last=uout; out=0;} uout++; cut=0;}
cut++;
if (cut==DECDPUN) {*uout=out; if (out) {last=uout; out=0;} uout++; cut=0;}
continue;
}
bcd=DPD2BCD[dpd]; /* convert 10 bits to 12 bits BCD */
/* now accumulate the 3 BCD nibbles into units */
nibble=bcd & 0x00f;
if (nibble) out=(Unit)(out+nibble*DECPOWERS[cut]);
cut++;
if (cut==DECDPUN) {*uout=out; if (out) {last=uout; out=0;} uout++; cut=0;}
bcd>>=4;
/* if this is the last declet and the remaining nibbles in bcd */
/* are 00 then process no more nibbles, because this could be */
/* the 'odd' MSD declet and writing any more Units would then */
/* overflow the unit array */
if (n==0 && !bcd) break;
nibble=bcd & 0x00f;
if (nibble) out=(Unit)(out+nibble*DECPOWERS[cut]);
cut++;
if (cut==DECDPUN) {*uout=out; if (out) {last=uout; out=0;} uout++; cut=0;}
bcd>>=4;
nibble=bcd & 0x00f;
if (nibble) out=(Unit)(out+nibble*DECPOWERS[cut]);
cut++;
if (cut==DECDPUN) {*uout=out; if (out) {last=uout; out=0;} uout++; cut=0;}
} /* n */
if (cut!=0) { /* some more left over */
*uout=out; /* write out final unit */
if (out) last=uout; /* and note if non-zero */
}
#endif
/* here, last points to the most significant unit with digits; */
/* inspect it to get the final digits count -- this is essentially */
/* the same code as decGetDigits in decNumber.c */
dn->digits=(last-dn->lsu)*DECDPUN+1; /* floor of digits, plus */
/* must be at least 1 digit */
#if DECDPUN>1
if (*last<10) return; /* common odd digit or 0 */
dn->digits++; /* must be 2 at least */
#if DECDPUN>2
if (*last<100) return; /* 10-99 */
dn->digits++; /* must be 3 at least */
#if DECDPUN>3
if (*last<1000) return; /* 100-999 */
dn->digits++; /* must be 4 at least */
#if DECDPUN>4
for (pow=&DECPOWERS[4]; *last>=*pow; pow++) dn->digits++;
#endif
#endif
#endif
#endif
return;
} /*decDigitsFromDPD */
/* Decimal 64-bit format module header for the decNumber C Library /* Decimal 64-bit format module header for the decNumber C Library.
Copyright (C) 2005 Free Software Foundation, Inc. Copyright (C) 2005, 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw. Contributed by IBM Corporation. Author Mike Cowlishaw.
This file is part of GCC. This file is part of GCC.
...@@ -28,97 +28,74 @@ ...@@ -28,97 +28,74 @@
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */ 02110-1301, USA. */
/* ------------------------------------------------------------------ */
/* Decimal 64-bit format module header */
/* ------------------------------------------------------------------ */
#if !defined(DECIMAL64) #if !defined(DECIMAL64)
#define DECIMAL64 #define DECIMAL64
#define DEC64NAME "decimal64" /* Short name */ #define DEC64NAME "decimal64" /* Short name */
#define DEC64FULLNAME "Decimal 64-bit Number" /* Verbose name */ #define DEC64FULLNAME "Decimal 64-bit Number" /* Verbose name */
#define DEC64AUTHOR "Mike Cowlishaw" /* Who to blame */ #define DEC64AUTHOR "Mike Cowlishaw" /* Who to blame */
#if defined(DECIMAL32)
#error decimal64.h must precede decimal32.h for correct DECNUMDIGITS
#endif
/* parameters for decimal64s */ /* parameters for decimal64s */
#define DECIMAL64_Bytes 8 /* length */ #define DECIMAL64_Bytes 8 /* length */
#define DECIMAL64_Pmax 16 /* maximum precision (digits) */ #define DECIMAL64_Pmax 16 /* maximum precision (digits) */
#define DECIMAL64_Emax 384 /* maximum adjusted exponent */ #define DECIMAL64_Emax 384 /* maximum adjusted exponent */
#define DECIMAL64_Emin -383 /* minimum adjusted exponent */ #define DECIMAL64_Emin -383 /* minimum adjusted exponent */
#define DECIMAL64_Bias 398 /* bias for the exponent */ #define DECIMAL64_Bias 398 /* bias for the exponent */
#define DECIMAL64_String 24 /* maximum string length, +1 */ #define DECIMAL64_String 24 /* maximum string length, +1 */
#define DECIMAL64_EconL 8 /* exp. continuation length */
/* highest biased exponent (Elimit-1) */ /* highest biased exponent (Elimit-1) */
#define DECIMAL64_Ehigh (DECIMAL64_Emax+DECIMAL64_Bias-DECIMAL64_Pmax+1) #define DECIMAL64_Ehigh (DECIMAL64_Emax+DECIMAL64_Bias-DECIMAL64_Pmax+1)
#ifndef DECNUMDIGITS
#define DECNUMDIGITS DECIMAL64_Pmax /* size if not already defined */
#endif
#ifndef DECNUMBER
#include "decNumber.h" /* context and number library */
#endif
/* Decimal 64-bit type, accessible by bytes */
typedef struct
{
uint8_t bytes[DECIMAL64_Bytes]; /* decimal64: 1, 5, 8, 50 bits */
} decimal64;
/* special values [top byte excluding sign bit; last two bits are
don't-care for Infinity on input, last bit don't-care for NaN] */
#if !defined(DECIMAL_NaN)
#define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */
#define DECIMAL_sNaN 0x7e /* 0 11111 10 sNaN */
#define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */
#endif
/* Macros for accessing decimal64 fields. These assume the argument
is a reference (pointer) to the decimal64 structure */
/* Get sign */
#define decimal64Sign(d) ((unsigned)(d)->bytes[0]>>7)
/* Get combination field */ /* check enough digits, if pre-defined */
#define decimal64Comb(d) (((d)->bytes[0] & 0x7c)>>2) #if defined(DECNUMDIGITS)
#if (DECNUMDIGITS<DECIMAL64_Pmax)
#error decimal64.h needs pre-defined DECNUMDIGITS>=16 for safe use
#endif
#endif
/* Get exponent continuation [does not remove bias] */
#define decimal64ExpCon(d) ((((d)->bytes[0] & 0x03)<<6) \
| ((unsigned)(d)->bytes[1]>>2))
/* Set sign [this assumes sign previously 0] */ #ifndef DECNUMDIGITS
#define decimal64SetSign(d, b) { \ #define DECNUMDIGITS DECIMAL64_Pmax /* size if not already defined*/
(d)->bytes[0]|=((unsigned)(b)<<7);} #endif
#ifndef DECNUMBER
#include "decNumber.h" /* context and number library */
#endif
/* Clear sign */ /* Decimal 64-bit type, accessible by bytes */
#define decimal64ClearSign(d) {(d)->bytes[0]&=~0x80;} typedef struct {
uint8_t bytes[DECIMAL64_Bytes]; /* decimal64: 1, 5, 8, 50 bits*/
/* Flip sign */ } decimal64;
#define decimal64FlipSign(d) {(d)->bytes[0]^=0x80;}
/* special values [top byte excluding sign bit; last two bits are */
/* Set exponent continuation [does not apply bias] */ /* don't-care for Infinity on input, last bit don't-care for NaN] */
/* This assumes range has been checked and exponent previously 0; type */ #if !defined(DECIMAL_NaN)
/* of exponent must be unsigned */ #define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */
#define decimal64SetExpCon(d, e) { \ #define DECIMAL_sNaN 0x7e /* 0 11111 10 sNaN */
(d)->bytes[0]|=(uint8_t)((e)>>6); \ #define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */
(d)->bytes[1]|=(uint8_t)(((e)&0x3F)<<2);} #endif
/* ------------------------------------------------------------------ */ /* ---------------------------------------------------------------- */
/* Routines */ /* Routines */
/* ------------------------------------------------------------------ */ /* ---------------------------------------------------------------- */
#ifdef IN_LIBGCC2 #include "decimal64Symbols.h"
#ifndef decimal64FromString
#define decimal64FromString __decimal64FromString
#define decimal64ToString __decimal64ToString
#define decimal64ToEngString __decimal64ToEngString
#define decimal64FromNumber __decimal64FromNumber
#define decimal64ToNumber __decimal64ToNumber
#endif
#endif
/* String conversions */ /* String conversions */
decimal64 *decimal64FromString (decimal64 *, const char *, decContext *); decimal64 * decimal64FromString(decimal64 *, const char *, decContext *);
char *decimal64ToString (const decimal64 *, char *); char * decimal64ToString(const decimal64 *, char *);
char *decimal64ToEngString (const decimal64 *, char *); char * decimal64ToEngString(const decimal64 *, char *);
/* decNumber conversions */ /* decNumber conversions */
decimal64 *decimal64FromNumber (decimal64 *, const decNumber *, decContext *); decimal64 * decimal64FromNumber(decimal64 *, const decNumber *,
decNumber *decimal64ToNumber (const decimal64 *, decNumber *); decContext *);
decNumber * decimal64ToNumber(const decimal64 *, decNumber *);
/* Format-dependent utilities */
uint32_t decimal64IsCanonical(const decimal64 *);
decimal64 * decimal64Canonical(decimal64 *, const decimal64 *);
#endif #endif
#if !defined(DECIMAL64SYMBOLS)
#define DECIMAL64SYMBOLS
#ifdef IN_LIBGCC2
#define decDigitsFromDPD __decDigitsFromDPD
#define decDigitsToDPD __decDigitsToDPD
#define decimal64Canonical __decimal64Canonical
#define decimal64FromNumber __decimal64FromNumber
#define decimal64FromString __decimal64FromString
#define decimal64IsCanonical __decimal64IsCanonical
#define decimal64ToEngString __decimal64ToEngString
#define decimal64ToNumber __decimal64ToNumber
#define decimal64ToString __decimal64ToString
#endif
#endif
2007-09-10 Janis Johnson <janis187@us.ibm.com>
* Makefile.in (dfp-filenames): Remove decUtility, add
decDouble, decPacked, decQuad, decSingle.
2007-08-27 Hans Kester <hans.kester@ellips.nl> 2007-08-27 Hans Kester <hans.kester@ellips.nl>
* config.host : Add x86_64-elf target. * config.host : Add x86_64-elf target.
......
...@@ -488,7 +488,7 @@ dfp-filenames += decimal_globals decimal_data binarydecimal \ ...@@ -488,7 +488,7 @@ dfp-filenames += decimal_globals decimal_data binarydecimal \
bid128_to_int32 bid128_to_int64 \ bid128_to_int32 bid128_to_int64 \
bid128_to_uint32 bid128_to_uint64 bid128_to_uint32 bid128_to_uint64
else else
dfp-filenames += decContext decNumber decExcept decRound decLibrary decUtility dfp-filenames += decContext decNumber decExcept decRound decLibrary decDouble decPacked decQuad decSingle
endif endif
endif endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment