* libdecnumber: Import decNumber sources from the dfp-branch.

From-SVN: r107629
This commit is contained in:
Ben Elliston 2005-11-28 22:30:30 +00:00 committed by Ben Elliston
parent e669bd2b69
commit 473a74b91e
18 changed files with 9071 additions and 0 deletions

View file

@ -1,3 +1,7 @@
2005-11-29 Ben Elliston <bje@au.ibm.com>
* libdecnumber: Import decNumber sources from the dfp-branch.
2005-11-21 Kean Johnston <jkj@sco.com>
* config.sub, config.guess: Sync from upstream sources.

9
libdecnumber/ChangeLog Normal file
View file

@ -0,0 +1,9 @@
2005-11-29 Ben Elliston <bje@au.ibm.com>
* decimal32.h, decimal64.h, decimal128.h: New.
* decimal32.c, decimal64.c, decimal128.c: Likewise.
* decContext.c, decContext.h: Likewise.
* decUtility.c, decUtility.h: Likewise.
* decNumber.c, decNumber.h, decNumberLocal.h: Likewise.
* decDPD.h: Likewise.
* decLibrary.c, decRound.c: Likewise.

218
libdecnumber/decContext.c Normal file
View file

@ -0,0 +1,218 @@
/* Decimal context module 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.
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, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
/* This module compirises the routines for handling the arithmetic
context structures. */
#include <string.h> /* for strcmp */
#include "decContext.h" /* context and base types */
#include "decNumberLocal.h" /* decNumber local types, etc. */
/* ------------------------------------------------------------------ */
/* decContextDefault -- initialize a context structure */
/* */
/* context is the structure to be initialized */
/* kind selects the required set of default values, one of: */
/* DEC_INIT_BASE -- select ANSI X3-274 defaults */
/* DEC_INIT_DECIMAL32 -- select IEEE 754r defaults, 32-bit */
/* DEC_INIT_DECIMAL64 -- select IEEE 754r defaults, 64-bit */
/* DEC_INIT_DECIMAL128 -- select IEEE 754r defaults, 128-bit */
/* For any other value a valid context is returned, but with */
/* Invalid_operation set in the status field. */
/* returns a context structure with the appropriate initial values. */
/* ------------------------------------------------------------------ */
decContext *
decContextDefault (decContext * context, Int kind)
{
/* set defaults... */
context->digits = 9; /* 9 digits */
context->emax = DEC_MAX_EMAX; /* 9-digit exponents */
context->emin = DEC_MIN_EMIN; /* .. balanced */
context->round = DEC_ROUND_HALF_UP; /* 0.5 rises */
context->traps = DEC_Errors; /* all but informational */
context->status = 0; /* cleared */
context->clamp = 0; /* no clamping */
#if DECSUBSET
context->extended = 0; /* cleared */
#endif
switch (kind)
{
case DEC_INIT_BASE:
/* [use defaults] */
break;
case DEC_INIT_DECIMAL32:
context->digits = 7; /* digits */
context->emax = 96; /* Emax */
context->emin = -95; /* Emin */
context->round = DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
context->traps = 0; /* no traps set */
context->clamp = 1; /* clamp exponents */
#if DECSUBSET
context->extended = 1; /* set */
#endif
break;
case DEC_INIT_DECIMAL64:
context->digits = 16; /* digits */
context->emax = 384; /* Emax */
context->emin = -383; /* Emin */
context->round = DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
context->traps = 0; /* no traps set */
context->clamp = 1; /* clamp exponents */
#if DECSUBSET
context->extended = 1; /* set */
#endif
break;
case DEC_INIT_DECIMAL128:
context->digits = 34; /* digits */
context->emax = 6144; /* Emax */
context->emin = -6143; /* Emin */
context->round = DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
context->traps = 0; /* no traps set */
context->clamp = 1; /* clamp exponents */
#if DECSUBSET
context->extended = 1; /* set */
#endif
break;
default: /* invalid Kind */
/* use defaults, and .. */
decContextSetStatus (context, DEC_Invalid_operation); /* trap */
}
return context;
} /* decContextDefault */
/* ------------------------------------------------------------------ */
/* decContextStatusToString -- convert status flags to a string */
/* */
/* context is a context with valid status field */
/* */
/* returns a constant string describing the condition. If multiple */
/* (or no) flags are set, a generic constant message is returned. */
/* ------------------------------------------------------------------ */
const char *
decContextStatusToString (decContext * context)
{
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 */
/* */
/* context is the controlling context */
/* string is a string exactly equal to one that might be returned */
/* by decContextStatusToString */
/* */
/* The status bit corresponding to the string is set, and a trap */
/* is raised if appropriate. */
/* */
/* returns the context structure, unless the string is equal to */
/* DEC_Condition_MU or is not recognized. In these cases NULL is */
/* returned. */
/* ------------------------------------------------------------------ */
decContext *
decContextSetStatusFromString (decContext * context, char *string)
{
if (strcmp (string, DEC_Condition_CS) == 0)
return decContextSetStatus (context, DEC_Conversion_syntax);
if (strcmp (string, DEC_Condition_DZ) == 0)
return decContextSetStatus (context, DEC_Division_by_zero);
if (strcmp (string, DEC_Condition_DI) == 0)
return decContextSetStatus (context, DEC_Division_impossible);
if (strcmp (string, DEC_Condition_DU) == 0)
return decContextSetStatus (context, DEC_Division_undefined);
if (strcmp (string, DEC_Condition_IE) == 0)
return decContextSetStatus (context, DEC_Inexact);
if (strcmp (string, DEC_Condition_IS) == 0)
return decContextSetStatus (context, DEC_Insufficient_storage);
if (strcmp (string, DEC_Condition_IC) == 0)
return decContextSetStatus (context, DEC_Invalid_context);
if (strcmp (string, DEC_Condition_IO) == 0)
return decContextSetStatus (context, DEC_Invalid_operation);
#if DECSUBSET
if (strcmp (string, DEC_Condition_LD) == 0)
return decContextSetStatus (context, DEC_Lost_digits);
#endif
if (strcmp (string, DEC_Condition_OV) == 0)
return decContextSetStatus (context, DEC_Overflow);
if (strcmp (string, DEC_Condition_PA) == 0)
return decContextSetStatus (context, DEC_Clamped);
if (strcmp (string, DEC_Condition_RO) == 0)
return decContextSetStatus (context, DEC_Rounded);
if (strcmp (string, DEC_Condition_SU) == 0)
return decContextSetStatus (context, DEC_Subnormal);
if (strcmp (string, DEC_Condition_UN) == 0)
return decContextSetStatus (context, DEC_Underflow);
if (strcmp (string, DEC_Condition_ZE) == 0)
return context;
return NULL; /* Multiple status, or unknown */
} /* decContextSetStatusFromString */
/* ------------------------------------------------------------------ */
/* decContextSetStatus -- set status and raise trap if appropriate */
/* */
/* context is the controlling context */
/* 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 */

178
libdecnumber/decContext.h Normal file
View file

@ -0,0 +1,178 @@
/* Decimal Context 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.
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, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
/* ------------------------------------------------------------------ */
/* */
/* Context must always be set correctly: */
/* */
/* digits -- must be in the range 1 through 999999999 */
/* emax -- 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] */
/* */
/* ------------------------------------------------------------------ */
#if !defined(DECCONTEXT)
#define DECCONTEXT
#define DECCNAME "decContext" /* Short name */
#define DECCFULLNAME "Decimal Context Descriptor" /* Verbose name */
#define DECCAUTHOR "Mike Cowlishaw" /* Who to blame */
#include <stdint.h> /* C99 standard integers */
#include <signal.h> /* for traps */
/* Conditional code flag -- set this to 0 for best performance */
#define DECSUBSET 0 /* 1 to enable subset arithmetic */
/* Context for operations, with associated constants */
enum rounding
{
DEC_ROUND_CEILING, /* round towards +infinity */
DEC_ROUND_UP, /* round away from 0 */
DEC_ROUND_HALF_UP, /* 0.5 rounds up */
DEC_ROUND_HALF_EVEN, /* 0.5 rounds to nearest even */
DEC_ROUND_HALF_DOWN, /* 0.5 rounds down */
DEC_ROUND_DOWN, /* round towards 0 (truncate) */
DEC_ROUND_FLOOR, /* round towards -infinity */
DEC_ROUND_MAX /* enum must be less than this */
};
typedef struct
{
int32_t digits; /* working precision */
int32_t emax; /* maximum positive exponent */
int32_t emin; /* minimum negative exponent */
enum rounding round; /* rounding mode */
uint32_t traps; /* trap-enabler flags */
uint32_t status; /* status flags */
uint8_t clamp; /* flag: apply IEEE exponent clamp */
#if DECSUBSET
uint8_t extended; /* flag: special-values allowed */
#endif
} decContext;
/* Maxima and Minima */
#define DEC_MAX_DIGITS 999999999
#define DEC_MIN_DIGITS 1
#define DEC_MAX_EMAX 999999999
#define DEC_MIN_EMAX 0
#define DEC_MAX_EMIN 0
#define DEC_MIN_EMIN -999999999
/* Trap-enabler and Status flags (exceptional conditions), and their names */
/* Top byte is reserved for internal use */
#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 /* [used if 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
/* IEEE 854 groupings for the flags */
/* [DEC_Clamped, DEC_Lost_digits, DEC_Rounded, and DEC_Subnormal are */
/* not in IEEE 854] */
#define DEC_IEEE_854_Division_by_zero (DEC_Division_by_zero)
#if DECSUBSET
#define DEC_IEEE_854_Inexact (DEC_Inexact | DEC_Lost_digits)
#else
#define DEC_IEEE_854_Inexact (DEC_Inexact)
#endif
#define DEC_IEEE_854_Invalid_operation (DEC_Conversion_syntax | \
DEC_Division_impossible | \
DEC_Division_undefined | \
DEC_Insufficient_storage | \
DEC_Invalid_context | \
DEC_Invalid_operation)
#define DEC_IEEE_854_Overflow (DEC_Overflow)
#define DEC_IEEE_854_Underflow (DEC_Underflow)
/* flags which are normally errors (results are qNaN, infinite, or 0) */
#define DEC_Errors (DEC_IEEE_854_Division_by_zero | \
DEC_IEEE_854_Invalid_operation | \
DEC_IEEE_854_Overflow | DEC_IEEE_854_Underflow)
/* flags which cause a result to become qNaN */
#define DEC_NaNs DEC_IEEE_854_Invalid_operation
/* flags which are normally for information only (have finite results) */
#if DECSUBSET
#define DEC_Information (DEC_Clamped | DEC_Rounded | DEC_Inexact \
| DEC_Lost_digits)
#else
#define DEC_Information (DEC_Clamped | DEC_Rounded | DEC_Inexact)
#endif
/* name strings for the exceptional conditions */
#define DEC_Condition_CS "Conversion syntax"
#define DEC_Condition_DZ "Division by zero"
#define DEC_Condition_DI "Division impossible"
#define DEC_Condition_DU "Division undefined"
#define DEC_Condition_IE "Inexact"
#define DEC_Condition_IS "Insufficient storage"
#define DEC_Condition_IC "Invalid context"
#define DEC_Condition_IO "Invalid operation"
#if DECSUBSET
#define DEC_Condition_LD "Lost digits"
#endif
#define DEC_Condition_OV "Overflow"
#define DEC_Condition_PA "Clamped"
#define DEC_Condition_RO "Rounded"
#define DEC_Condition_SU "Subnormal"
#define DEC_Condition_UN "Underflow"
#define DEC_Condition_ZE "No status"
#define DEC_Condition_MU "Multiple status"
#define DEC_Condition_Length 21 /* length of the longest string, */
/* including terminator */
/* Initialization descriptors, used by decContextDefault */
#define DEC_INIT_BASE 0
#define DEC_INIT_DECIMAL32 32
#define DEC_INIT_DECIMAL64 64
#define DEC_INIT_DECIMAL128 128
/* decContext routines */
#ifdef IN_LIBGCC2
#define decContextDefault __decContextDefault
#define decContextSetStatus __decContextSetStatus
#define decContextStatusToString __decContextStatusToString
#define decContextSetStatusFromString __decContextSetStatusFromString
#endif
decContext *decContextDefault (decContext *, int32_t);
decContext *decContextSetStatus (decContext *, uint32_t);
const char *decContextStatusToString (decContext *);
decContext *decContextSetStatusFromString (decContext *, char *);
#endif

525
libdecnumber/decDPD.h Normal file
View file

@ -0,0 +1,525 @@
/* Binary Coded Decimal <--> Densely Packed Decimal lookup tables.
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.
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, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
/* ------------------------------------------------------------------------ */
/* For details, see: http://www2.hursley.ibm.com/decimal/DPDecimal.html */
/* */
/* This include file defines conversion tables for DPD, as follows. */
/* */
/* 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 DPD2BIN[1024]; // DPD -> BIN (0x3FF => 999) */
/* */
/* In all cases the result (10 bits or 12 bits, or binary) is right-aligned */
/* in the table entry. */
/* */
/* 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: */
/* #define DEC_BCD2DPD 1 */
/* ------------------------------------------------------------------------ */
#if DEC_BCD2DPD==1
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,
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,
0, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 0, 0,
0, 0, 0, 0, 64, 65, 66, 67, 68, 69, 70, 71, 72,
73, 0, 0, 0, 0, 0, 0, 80, 81, 82, 83, 84, 85,
86, 87, 88, 89, 0, 0, 0, 0, 0, 0, 96, 97, 98,
99, 100, 101, 102, 103, 104, 105, 0, 0, 0, 0, 0, 0,
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 0, 0, 0,
0, 0, 0, 10, 11, 42, 43, 74, 75, 106, 107, 78, 79,
0, 0, 0, 0, 0, 0, 26, 27, 58, 59, 90, 91, 122,
123, 94, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,
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, 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,
153, 0, 0, 0, 0, 0, 0, 160, 161, 162, 163, 164, 165,
166, 167, 168, 169, 0, 0, 0, 0, 0, 0, 176, 177, 178,
179, 180, 181, 182, 183, 184, 185, 0, 0, 0, 0, 0, 0,
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 0, 0, 0,
0, 0, 0, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217,
0, 0, 0, 0, 0, 0, 224, 225, 226, 227, 228, 229, 230,
231, 232, 233, 0, 0, 0, 0, 0, 0, 240, 241, 242, 243,
244, 245, 246, 247, 248, 249, 0, 0, 0, 0, 0, 0, 138,
139, 170, 171, 202, 203, 234, 235, 206, 207, 0, 0, 0, 0,
0, 0, 154, 155, 186, 187, 218, 219, 250, 251, 222, 223, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 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,
207, 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,
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,
0, 0, 0, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297,
0, 0, 0, 0, 0, 0, 304, 305, 306, 307, 308, 309, 310,
311, 312, 313, 0, 0, 0, 0, 0, 0, 320, 321, 322, 323,
324, 325, 326, 327, 328, 329, 0, 0, 0, 0, 0, 0, 336,
337, 338, 339, 340, 341, 342, 343, 344, 345, 0, 0, 0, 0,
0, 0, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 0,
0, 0, 0, 0, 0, 368, 369, 370, 371, 372, 373, 374, 375,
376, 377, 0, 0, 0, 0, 0, 0, 266, 267, 298, 299, 330,
331, 362, 363, 334, 335, 0, 0, 0, 0, 0, 0, 282, 283,
314, 315, 346, 347, 378, 379, 350, 351, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 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, 384, 385, 386, 387, 388, 389, 390,
391, 392, 393, 0, 0, 0, 0, 0, 0, 400, 401, 402, 403,
404, 405, 406, 407, 408, 409, 0, 0, 0, 0, 0, 0, 416,
417, 418, 419, 420, 421, 422, 423, 424, 425, 0, 0, 0, 0,
0, 0, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 0,
0, 0, 0, 0, 0, 448, 449, 450, 451, 452, 453, 454, 455,
456, 457, 0, 0, 0, 0, 0, 0, 464, 465, 466, 467, 468,
469, 470, 471, 472, 473, 0, 0, 0, 0, 0, 0, 480, 481,
482, 483, 484, 485, 486, 487, 488, 489, 0, 0, 0, 0, 0,
0, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 0, 0,
0, 0, 0, 0, 394, 395, 426, 427, 458, 459, 490, 491, 462,
463, 0, 0, 0, 0, 0, 0, 410, 411, 442, 443, 474, 475,
506, 507, 478, 479, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,
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, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 0,
0, 0, 0, 0, 0, 528, 529, 530, 531, 532, 533, 534, 535,
536, 537, 0, 0, 0, 0, 0, 0, 544, 545, 546, 547, 548,
549, 550, 551, 552, 553, 0, 0, 0, 0, 0, 0, 560, 561,
562, 563, 564, 565, 566, 567, 568, 569, 0, 0, 0, 0, 0,
0, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 0, 0,
0, 0, 0, 0, 592, 593, 594, 595, 596, 597, 598, 599, 600,
601, 0, 0, 0, 0, 0, 0, 608, 609, 610, 611, 612, 613,
614, 615, 616, 617, 0, 0, 0, 0, 0, 0, 624, 625, 626,
627, 628, 629, 630, 631, 632, 633, 0, 0, 0, 0, 0, 0,
522, 523, 554, 555, 586, 587, 618, 619, 590, 591, 0, 0, 0,
0, 0, 0, 538, 539, 570, 571, 602, 603, 634, 635, 606, 607,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 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,
590, 591, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
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,
0, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 0, 0,
0, 0, 0, 0, 672, 673, 674, 675, 676, 677, 678, 679, 680,
681, 0, 0, 0, 0, 0, 0, 688, 689, 690, 691, 692, 693,
694, 695, 696, 697, 0, 0, 0, 0, 0, 0, 704, 705, 706,
707, 708, 709, 710, 711, 712, 713, 0, 0, 0, 0, 0, 0,
720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 0, 0, 0,
0, 0, 0, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745,
0, 0, 0, 0, 0, 0, 752, 753, 754, 755, 756, 757, 758,
759, 760, 761, 0, 0, 0, 0, 0, 0, 650, 651, 682, 683,
714, 715, 746, 747, 718, 719, 0, 0, 0, 0, 0, 0, 666,
667, 698, 699, 730, 731, 762, 763, 734, 735, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 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, 768, 769, 770, 771, 772, 773,
774, 775, 776, 777, 0, 0, 0, 0, 0, 0, 784, 785, 786,
787, 788, 789, 790, 791, 792, 793, 0, 0, 0, 0, 0, 0,
800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 0, 0, 0,
0, 0, 0, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825,
0, 0, 0, 0, 0, 0, 832, 833, 834, 835, 836, 837, 838,
839, 840, 841, 0, 0, 0, 0, 0, 0, 848, 849, 850, 851,
852, 853, 854, 855, 856, 857, 0, 0, 0, 0, 0, 0, 864,
865, 866, 867, 868, 869, 870, 871, 872, 873, 0, 0, 0, 0,
0, 0, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 0,
0, 0, 0, 0, 0, 778, 779, 810, 811, 842, 843, 874, 875,
846, 847, 0, 0, 0, 0, 0, 0, 794, 795, 826, 827, 858,
859, 890, 891, 862, 863, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,
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, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905,
0, 0, 0, 0, 0, 0, 912, 913, 914, 915, 916, 917, 918,
919, 920, 921, 0, 0, 0, 0, 0, 0, 928, 929, 930, 931,
932, 933, 934, 935, 936, 937, 0, 0, 0, 0, 0, 0, 944,
945, 946, 947, 948, 949, 950, 951, 952, 953, 0, 0, 0, 0,
0, 0, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 0,
0, 0, 0, 0, 0, 976, 977, 978, 979, 980, 981, 982, 983,
984, 985, 0, 0, 0, 0, 0, 0, 992, 993, 994, 995, 996,
997, 998, 999, 1000, 1001, 0, 0, 0, 0, 0, 0, 1008, 1009,
1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 0, 0, 0, 0, 0,
0, 906, 907, 938, 939, 970, 971, 1002, 1003, 974, 975, 0, 0,
0, 0, 0, 0, 922, 923, 954, 955, 986, 987, 1018, 1019, 990,
991, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 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,
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, 12,
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, 0, 0, 0, 44, 45, 300, 301, 556, 557, 812, 813,
302, 303, 0, 0, 0, 0, 0, 0, 60, 61, 316, 317, 572,
573, 828, 829, 318, 319, 0, 0, 0, 0, 0, 0, 76, 77,
332, 333, 588, 589, 844, 845, 558, 559, 0, 0, 0, 0, 0,
0, 92, 93, 348, 349, 604, 605, 860, 861, 574, 575, 0, 0,
0, 0, 0, 0, 108, 109, 364, 365, 620, 621, 876, 877, 814,
815, 0, 0, 0, 0, 0, 0, 124, 125, 380, 381, 636, 637,
892, 893, 830, 831, 0, 0, 0, 0, 0, 0, 14, 15, 270,
271, 526, 527, 782, 783, 110, 111, 0, 0, 0, 0, 0, 0,
30, 31, 286, 287, 542, 543, 798, 799, 126, 127, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 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, 140, 141, 396, 397, 652,
653, 908, 909, 174, 175, 0, 0, 0, 0, 0, 0, 156, 157,
412, 413, 668, 669, 924, 925, 190, 191, 0, 0, 0, 0, 0,
0, 172, 173, 428, 429, 684, 685, 940, 941, 430, 431, 0, 0,
0, 0, 0, 0, 188, 189, 444, 445, 700, 701, 956, 957, 446,
447, 0, 0, 0, 0, 0, 0, 204, 205, 460, 461, 716, 717,
972, 973, 686, 687, 0, 0, 0, 0, 0, 0, 220, 221, 476,
477, 732, 733, 988, 989, 702, 703, 0, 0, 0, 0, 0, 0,
236, 237, 492, 493, 748, 749, 1004, 1005, 942, 943, 0, 0, 0,
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,
911, 238, 239, 0, 0, 0, 0, 0, 0, 158, 159, 414, 415,
670, 671, 926, 927, 254, 255
};
#endif
#if DEC_DPD2BCD==1
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,
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,
2057, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 146, 147,
2096, 2097, 2072, 2073, 64, 65, 66, 67, 68, 69, 70, 71, 72,
73, 132, 133, 2112, 2113, 136, 137, 80, 81, 82, 83, 84, 85,
86, 87, 88, 89, 148, 149, 2128, 2129, 152, 153, 96, 97, 98,
99, 100, 101, 102, 103, 104, 105, 134, 135, 2144, 2145, 2184, 2185,
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 150, 151, 2160,
2161, 2200, 2201, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265,
384, 385, 2304, 2305, 2432, 2433, 272, 273, 274, 275, 276, 277, 278,
279, 280, 281, 400, 401, 2320, 2321, 2448, 2449, 288, 289, 290, 291,
292, 293, 294, 295, 296, 297, 386, 387, 2336, 2337, 2312, 2313, 304,
305, 306, 307, 308, 309, 310, 311, 312, 313, 402, 403, 2352, 2353,
2328, 2329, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 388,
389, 2368, 2369, 392, 393, 336, 337, 338, 339, 340, 341, 342, 343,
344, 345, 404, 405, 2384, 2385, 408, 409, 352, 353, 354, 355, 356,
357, 358, 359, 360, 361, 390, 391, 2400, 2401, 2440, 2441, 368, 369,
370, 371, 372, 373, 374, 375, 376, 377, 406, 407, 2416, 2417, 2456,
2457, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 640, 641,
2050, 2051, 2178, 2179, 528, 529, 530, 531, 532, 533, 534, 535, 536,
537, 656, 657, 2066, 2067, 2194, 2195, 544, 545, 546, 547, 548, 549,
550, 551, 552, 553, 642, 643, 2082, 2083, 2088, 2089, 560, 561, 562,
563, 564, 565, 566, 567, 568, 569, 658, 659, 2098, 2099, 2104, 2105,
576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 644, 645, 2114,
2115, 648, 649, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601,
660, 661, 2130, 2131, 664, 665, 608, 609, 610, 611, 612, 613, 614,
615, 616, 617, 646, 647, 2146, 2147, 2184, 2185, 624, 625, 626, 627,
628, 629, 630, 631, 632, 633, 662, 663, 2162, 2163, 2200, 2201, 768,
769, 770, 771, 772, 773, 774, 775, 776, 777, 896, 897, 2306, 2307,
2434, 2435, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 912,
913, 2322, 2323, 2450, 2451, 800, 801, 802, 803, 804, 805, 806, 807,
808, 809, 898, 899, 2338, 2339, 2344, 2345, 816, 817, 818, 819, 820,
821, 822, 823, 824, 825, 914, 915, 2354, 2355, 2360, 2361, 832, 833,
834, 835, 836, 837, 838, 839, 840, 841, 900, 901, 2370, 2371, 904,
905, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 916, 917,
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,
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,
2181,
1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1168, 1169,
2068,
2069, 2196, 2197, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064,
1065,
1154, 1155, 2084, 2085, 2120, 2121, 1072, 1073, 1074, 1075, 1076, 1077,
1078,
1079, 1080, 1081, 1170, 1171, 2100, 2101, 2136, 2137, 1088, 1089, 1090,
1091,
1092, 1093, 1094, 1095, 1096, 1097, 1156, 1157, 2116, 2117, 1160, 1161,
1104,
1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1172, 1173, 2132,
2133,
1176, 1177, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129,
1158,
1159, 2148, 2149, 2184, 2185, 1136, 1137, 1138, 1139, 1140, 1141, 1142,
1143,
1144, 1145, 1174, 1175, 2164, 2165, 2200, 2201, 1280, 1281, 1282, 1283,
1284,
1285, 1286, 1287, 1288, 1289, 1408, 1409, 2308, 2309, 2436, 2437, 1296,
1297,
1298, 1299, 1300, 1301, 1302, 1303, 1304, 1305, 1424, 1425, 2324, 2325,
2452,
2453, 1312, 1313, 1314, 1315, 1316, 1317, 1318, 1319, 1320, 1321, 1410,
1411,
2340, 2341, 2376, 2377, 1328, 1329, 1330, 1331, 1332, 1333, 1334, 1335,
1336,
1337, 1426, 1427, 2356, 2357, 2392, 2393, 1344, 1345, 1346, 1347, 1348,
1349,
1350, 1351, 1352, 1353, 1412, 1413, 2372, 2373, 1416, 1417, 1360, 1361,
1362,
1363, 1364, 1365, 1366, 1367, 1368, 1369, 1428, 1429, 2388, 2389, 1432,
1433,
1376, 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1414, 1415,
2404,
2405, 2440, 2441, 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400,
1401,
1430, 1431, 2420, 2421, 2456, 2457, 1536, 1537, 1538, 1539, 1540, 1541,
1542,
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
#if DEC_BIN2DPD==1
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,
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,
71, 72, 73, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 112, 113, 114,
115, 116, 117, 118, 119, 120, 121, 10, 11, 42, 43, 74, 75,
106, 107, 78, 79, 26, 27, 58, 59, 90, 91, 122, 123, 94,
95, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 144, 145,
146, 147, 148, 149, 150, 151, 152, 153, 160, 161, 162, 163, 164,
165, 166, 167, 168, 169, 176, 177, 178, 179, 180, 181, 182, 183,
184, 185, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 208,
209, 210, 211, 212, 213, 214, 215, 216, 217, 224, 225, 226, 227,
228, 229, 230, 231, 232, 233, 240, 241, 242, 243, 244, 245, 246,
247, 248, 249, 138, 139, 170, 171, 202, 203, 234, 235, 206, 207,
154, 155, 186, 187, 218, 219, 250, 251, 222, 223, 256, 257, 258,
259, 260, 261, 262, 263, 264, 265, 272, 273, 274, 275, 276, 277,
278, 279, 280, 281, 288, 289, 290, 291, 292, 293, 294, 295, 296,
297, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 320, 321,
322, 323, 324, 325, 326, 327, 328, 329, 336, 337, 338, 339, 340,
341, 342, 343, 344, 345, 352, 353, 354, 355, 356, 357, 358, 359,
360, 361, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 266,
267, 298, 299, 330, 331, 362, 363, 334, 335, 282, 283, 314, 315,
346, 347, 378, 379, 350, 351, 384, 385, 386, 387, 388, 389, 390,
391, 392, 393, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409,
416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 432, 433, 434,
435, 436, 437, 438, 439, 440, 441, 448, 449, 450, 451, 452, 453,
454, 455, 456, 457, 464, 465, 466, 467, 468, 469, 470, 471, 472,
473, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 496, 497,
498, 499, 500, 501, 502, 503, 504, 505, 394, 395, 426, 427, 458,
459, 490, 491, 462, 463, 410, 411, 442, 443, 474, 475, 506, 507,
478, 479, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 528,
529, 530, 531, 532, 533, 534, 535, 536, 537, 544, 545, 546, 547,
548, 549, 550, 551, 552, 553, 560, 561, 562, 563, 564, 565, 566,
567, 568, 569, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585,
592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 608, 609, 610,
611, 612, 613, 614, 615, 616, 617, 624, 625, 626, 627, 628, 629,
630, 631, 632, 633, 522, 523, 554, 555, 586, 587, 618, 619, 590,
591, 538, 539, 570, 571, 602, 603, 634, 635, 606, 607, 640, 641,
642, 643, 644, 645, 646, 647, 648, 649, 656, 657, 658, 659, 660,
661, 662, 663, 664, 665, 672, 673, 674, 675, 676, 677, 678, 679,
680, 681, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 704,
705, 706, 707, 708, 709, 710, 711, 712, 713, 720, 721, 722, 723,
724, 725, 726, 727, 728, 729, 736, 737, 738, 739, 740, 741, 742,
743, 744, 745, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761,
650, 651, 682, 683, 714, 715, 746, 747, 718, 719, 666, 667, 698,
699, 730, 731, 762, 763, 734, 735, 768, 769, 770, 771, 772, 773,
774, 775, 776, 777, 784, 785, 786, 787, 788, 789, 790, 791, 792,
793, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 816, 817,
818, 819, 820, 821, 822, 823, 824, 825, 832, 833, 834, 835, 836,
837, 838, 839, 840, 841, 848, 849, 850, 851, 852, 853, 854, 855,
856, 857, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 880,
881, 882, 883, 884, 885, 886, 887, 888, 889, 778, 779, 810, 811,
842, 843, 874, 875, 846, 847, 794, 795, 826, 827, 858, 859, 890,
891, 862, 863, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905,
912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 928, 929, 930,
931, 932, 933, 934, 935, 936, 937, 944, 945, 946, 947, 948, 949,
950, 951, 952, 953, 960, 961, 962, 963, 964, 965, 966, 967, 968,
969, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 992, 993,
994, 995, 996, 997, 998, 999, 1000, 1001, 1008, 1009, 1010, 1011, 1012,
1013, 1014, 1015, 1016, 1017, 906, 907, 938, 939, 970, 971, 1002, 1003,
974, 975, 922, 923, 954, 955, 986, 987, 1018, 1019, 990, 991, 12,
13, 268, 269, 524, 525, 780, 781, 46, 47, 28, 29, 284, 285,
540, 541, 796, 797, 62, 63, 44, 45, 300, 301, 556, 557, 812,
813, 302, 303, 60, 61, 316, 317, 572, 573, 828, 829, 318, 319,
76, 77, 332, 333, 588, 589, 844, 845, 558, 559, 92, 93, 348,
349, 604, 605, 860, 861, 574, 575, 108, 109, 364, 365, 620, 621,
876, 877, 814, 815, 124, 125, 380, 381, 636, 637, 892, 893, 830,
831, 14, 15, 270, 271, 526, 527, 782, 783, 110, 111, 30, 31,
286, 287, 542, 543, 798, 799, 126, 127, 140, 141, 396, 397, 652,
653, 908, 909, 174, 175, 156, 157, 412, 413, 668, 669, 924, 925,
190, 191, 172, 173, 428, 429, 684, 685, 940, 941, 430, 431, 188,
189, 444, 445, 700, 701, 956, 957, 446, 447, 204, 205, 460, 461,
716, 717, 972, 973, 686, 687, 220, 221, 476, 477, 732, 733, 988,
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,
399, 654, 655, 910, 911, 238, 239, 158, 159, 414, 415, 670, 671,
926, 927, 254, 255
};
#endif
#if DEC_DPD2BIN==1
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,
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,
809, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 92, 93,
830, 831, 818, 819, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 84, 85, 840, 841, 88, 89, 50, 51, 52, 53, 54, 55,
56, 57, 58, 59, 94, 95, 850, 851, 98, 99, 60, 61, 62,
63, 64, 65, 66, 67, 68, 69, 86, 87, 860, 861, 888, 889,
70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 96, 97, 870,
871, 898, 899, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
180, 181, 900, 901, 980, 981, 110, 111, 112, 113, 114, 115, 116,
117, 118, 119, 190, 191, 910, 911, 990, 991, 120, 121, 122, 123,
124, 125, 126, 127, 128, 129, 182, 183, 920, 921, 908, 909, 130,
131, 132, 133, 134, 135, 136, 137, 138, 139, 192, 193, 930, 931,
918, 919, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 184,
185, 940, 941, 188, 189, 150, 151, 152, 153, 154, 155, 156, 157,
158, 159, 194, 195, 950, 951, 198, 199, 160, 161, 162, 163, 164,
165, 166, 167, 168, 169, 186, 187, 960, 961, 988, 989, 170, 171,
172, 173, 174, 175, 176, 177, 178, 179, 196, 197, 970, 971, 998,
999, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 280, 281,
802, 803, 882, 883, 210, 211, 212, 213, 214, 215, 216, 217, 218,
219, 290, 291, 812, 813, 892, 893, 220, 221, 222, 223, 224, 225,
226, 227, 228, 229, 282, 283, 822, 823, 828, 829, 230, 231, 232,
233, 234, 235, 236, 237, 238, 239, 292, 293, 832, 833, 838, 839,
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 284, 285, 842,
843, 288, 289, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259,
294, 295, 852, 853, 298, 299, 260, 261, 262, 263, 264, 265, 266,
267, 268, 269, 286, 287, 862, 863, 888, 889, 270, 271, 272, 273,
274, 275, 276, 277, 278, 279, 296, 297, 872, 873, 898, 899, 300,
301, 302, 303, 304, 305, 306, 307, 308, 309, 380, 381, 902, 903,
982, 983, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 390,
391, 912, 913, 992, 993, 320, 321, 322, 323, 324, 325, 326, 327,
328, 329, 382, 383, 922, 923, 928, 929, 330, 331, 332, 333, 334,
335, 336, 337, 338, 339, 392, 393, 932, 933, 938, 939, 340, 341,
342, 343, 344, 345, 346, 347, 348, 349, 384, 385, 942, 943, 388,
389, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 394, 395,
952, 953, 398, 399, 360, 361, 362, 363, 364, 365, 366, 367, 368,
369, 386, 387, 962, 963, 988, 989, 370, 371, 372, 373, 374, 375,
376, 377, 378, 379, 396, 397, 972, 973, 998, 999, 400, 401, 402,
403, 404, 405, 406, 407, 408, 409, 480, 481, 804, 805, 884, 885,
410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 490, 491, 814,
815, 894, 895, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429,
482, 483, 824, 825, 848, 849, 430, 431, 432, 433, 434, 435, 436,
437, 438, 439, 492, 493, 834, 835, 858, 859, 440, 441, 442, 443,
444, 445, 446, 447, 448, 449, 484, 485, 844, 845, 488, 489, 450,
451, 452, 453, 454, 455, 456, 457, 458, 459, 494, 495, 854, 855,
498, 499, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 486,
487, 864, 865, 888, 889, 470, 471, 472, 473, 474, 475, 476, 477,
478, 479, 496, 497, 874, 875, 898, 899, 500, 501, 502, 503, 504,
505, 506, 507, 508, 509, 580, 581, 904, 905, 984, 985, 510, 511,
512, 513, 514, 515, 516, 517, 518, 519, 590, 591, 914, 915, 994,
995, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 582, 583,
924, 925, 948, 949, 530, 531, 532, 533, 534, 535, 536, 537, 538,
539, 592, 593, 934, 935, 958, 959, 540, 541, 542, 543, 544, 545,
546, 547, 548, 549, 584, 585, 944, 945, 588, 589, 550, 551, 552,
553, 554, 555, 556, 557, 558, 559, 594, 595, 954, 955, 598, 599,
560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 586, 587, 964,
965, 988, 989, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579,
596, 597, 974, 975, 998, 999, 600, 601, 602, 603, 604, 605, 606,
607, 608, 609, 680, 681, 806, 807, 886, 887, 610, 611, 612, 613,
614, 615, 616, 617, 618, 619, 690, 691, 816, 817, 896, 897, 620,
621, 622, 623, 624, 625, 626, 627, 628, 629, 682, 683, 826, 827,
868, 869, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 692,
693, 836, 837, 878, 879, 640, 641, 642, 643, 644, 645, 646, 647,
648, 649, 684, 685, 846, 847, 688, 689, 650, 651, 652, 653, 654,
655, 656, 657, 658, 659, 694, 695, 856, 857, 698, 699, 660, 661,
662, 663, 664, 665, 666, 667, 668, 669, 686, 687, 866, 867, 888,
889, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 696, 697,
876, 877, 898, 899, 700, 701, 702, 703, 704, 705, 706, 707, 708,
709, 780, 781, 906, 907, 986, 987, 710, 711, 712, 713, 714, 715,
716, 717, 718, 719, 790, 791, 916, 917, 996, 997, 720, 721, 722,
723, 724, 725, 726, 727, 728, 729, 782, 783, 926, 927, 968, 969,
730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 792, 793, 936,
937, 978, 979, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749,
784, 785, 946, 947, 788, 789, 750, 751, 752, 753, 754, 755, 756,
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,
771, 772, 773, 774, 775, 776, 777, 778, 779, 796, 797, 976, 977,
998, 999
};
#endif

81
libdecnumber/decLibrary.c Normal file
View file

@ -0,0 +1,81 @@
/* Temporary library support for decimal floating point.
Copyright (C) 2005 Free Software Foundation, Inc.
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.
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 "decContext.h"
#include "decimal128.h"
#include "decimal64.h"
#include "decimal32.h"
void __host_to_ieee_32 (_Decimal32, decimal32 *);
void __host_to_ieee_64 (_Decimal64, decimal64 *);
void __host_to_ieee_128 (_Decimal128, decimal128 *);
extern int isinfd32 (_Decimal32);
extern int isinfd64 (_Decimal64);
extern int isinfd128 (_Decimal128);
extern void __dfp_enable_traps (void);
extern void __dfp_raise (int exception __attribute__ ((unused)));
int
isinfd32 (_Decimal32 arg)
{
decNumber dn;
decimal32 d32;
__host_to_ieee_32 (arg, &d32);
decimal32ToNumber (&d32, &dn);
return (decNumberIsInfinite (&dn));
}
int
isinfd64 (_Decimal64 arg)
{
decNumber dn;
decimal64 d64;
__host_to_ieee_64 (arg, &d64);
decimal64ToNumber (&d64, &dn);
return (decNumberIsInfinite (&dn));
}
int
isinfd128 (_Decimal128 arg)
{
decNumber dn;
decimal128 d128;
__host_to_ieee_128 (arg, &d128);
decimal128ToNumber (&d128, &dn);
return (decNumberIsInfinite (&dn));
}
int __dfp_traps;
void
__dfp_enable_traps (void)
{
__dfp_traps = 1;
}
void
__dfp_raise (int exception __attribute__ ((unused)))
{
raise (SIGFPE);
}

5939
libdecnumber/decNumber.c Normal file

File diff suppressed because it is too large Load diff

183
libdecnumber/decNumber.h Normal file
View file

@ -0,0 +1,183 @@
/* Decimal Number 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.
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, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#if !defined(DECNUMBER)
#define DECNUMBER
#define DECNAME "decNumber" /* Short name */
#define DECVERSION "decNumber 3.24" /* Version [16 max.] */
#define DECFULLNAME "Decimal Number Module" /* Verbose name */
#define DECAUTHOR "Mike Cowlishaw" /* Who to blame */
#if !defined(DECCONTEXT)
#include "decContext.h"
#endif
/* Bit settings for decNumber.bits */
#define DECNEG 0x80 /* Sign; 1=negative, 0=positive or zero */
#define DECINF 0x40 /* 1=Infinity */
#define DECNAN 0x20 /* 1=NaN */
#define DECSNAN 0x10 /* 1=sNaN */
/* The remaining bits are reserved; they must be 0 */
#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 */
/* units array in the structure is determined by the following */
/* constant. This must not be changed without recompiling the */
/* decNumber library modules. */
#define DECDPUN 4 /* Decimal Digits Per UNit [must be in */
/* range 1-9; power of 2 recommended]. */
/* The size (integer data type) of each unit is determined by the */
/* number of digits it will hold. */
#if DECDPUN<=2
#define decNumberUnit uint8_t
#elif DECDPUN<=4
#define decNumberUnit uint16_t
#else
#define decNumberUnit uint32_t
#endif
/* The number of decNumberUnits we need is ceiling of DECNUMDIGITS/DECDPUN */
#define DECNUMUNITS ((DECNUMDIGITS+DECDPUN-1)/DECDPUN)
/* The data structure... */
typedef struct
{
int32_t digits; /* Count of digits in the coefficient; >0 */
int32_t exponent; /* Unadjusted exponent, unbiased, in */
/* range: -1999999997 through 999999999 */
uint8_t bits; /* Indicator bits (see above) */
decNumberUnit lsu[DECNUMUNITS]; /* Coefficient, from least significant unit */
} decNumber;
/* Notes: */
/* 1. If digits is > DECDPUN then there will be more than one */
/* decNumberUnits immediately following the first element of lsu. */
/* These contain the remaining (more significant) digits of the */
/* number, and may be in the lsu array, or may be guaranteed by */
/* some other mechanism (such as being contained in another */
/* structure, or being overlaid on dynamically allocated storage). */
/* */
/* Each integer of the coefficient (except the possibly the last) */
/* 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). */
/* */
/* 2. A decNumber converted to a string may need up to digits+14 */
/* characters. The worst cases (non-exponential and exponential */
/* formats) are: -0.00000{9...}# */
/* and: -9.{9...}E+999999999# (where # is '\0') */
/* ------------------------------------------------------------------ */
/* decNumber public functions and macros */
/* ------------------------------------------------------------------ */
#ifdef IN_LIBGCC2
#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 */
decNumber *decNumberFromString (decNumber *, char *, decContext *);
char *decNumberToString (decNumber *, char *);
char *decNumberToEngString (decNumber *, char *);
/* Operators */
decNumber *decNumberAbs (decNumber *, decNumber *, decContext *);
decNumber *decNumberAdd (decNumber *, decNumber *, decNumber *, decContext *);
decNumber *decNumberCompare (decNumber *, decNumber *, decNumber *,
decContext *);
decNumber *decNumberDivide (decNumber *, decNumber *, decNumber *,
decContext *);
decNumber *decNumberDivideInteger (decNumber *, decNumber *, decNumber *,
decContext *);
decNumber *decNumberMax (decNumber *, decNumber *, decNumber *, decContext *);
decNumber *decNumberMin (decNumber *, decNumber *, decNumber *, decContext *);
decNumber *decNumberMinus (decNumber *, decNumber *, decContext *);
decNumber *decNumberMultiply (decNumber *, decNumber *, decNumber *,
decContext *);
decNumber *decNumberNormalize (decNumber *, decNumber *, decContext *);
decNumber *decNumberPlus (decNumber *, decNumber *, decContext *);
decNumber *decNumberPower (decNumber *, decNumber *, decNumber *,
decContext *);
decNumber *decNumberQuantize (decNumber *, decNumber *, decNumber *,
decContext *);
decNumber *decNumberRemainder (decNumber *, decNumber *, decNumber *,
decContext *);
decNumber *decNumberRemainderNear (decNumber *, decNumber *, decNumber *,
decContext *);
decNumber *decNumberRescale (decNumber *, decNumber *, decNumber *,
decContext *);
decNumber *decNumberSameQuantum (decNumber *, decNumber *, decNumber *);
decNumber *decNumberSquareRoot (decNumber *, decNumber *, decContext *);
decNumber *decNumberSubtract (decNumber *, decNumber *, decNumber *,
decContext *);
decNumber *decNumberToIntegralValue (decNumber *, decNumber *, decContext *);
/* Utilities */
decNumber *decNumberCopy (decNumber *, decNumber *);
decNumber *decNumberTrim (decNumber *);
const char *decNumberVersion (void);
decNumber *decNumberZero (decNumber *);
/* Macros */
#define decNumberIsZero(dn) (*(dn)->lsu==0 \
&& (dn)->digits==1 \
&& (((dn)->bits&DECSPECIAL)==0))
#define decNumberIsNegative(dn) (((dn)->bits&DECNEG)!=0)
#define decNumberIsNaN(dn) (((dn)->bits&(DECNAN|DECSNAN))!=0)
#define decNumberIsInfinite(dn) (((dn)->bits&DECINF)!=0)
#define decNumberNegate(dn) (((dn)->bits)^=DECNEG)
#endif

View file

@ -0,0 +1,127 @@
/* decNumber package local type, tuning, and macro definitions.
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.
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, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
/* ------------------------------------------------------------------ */
/* This header file is included by all modules in the decNumber */
/* library, and contains local type definitions, tuning parameters, */
/* etc. It must only be included once, and should not need to be */
/* used by application programs. decNumber.h must be included first. */
/* ------------------------------------------------------------------ */
#if !defined(DECNUMBERLOC)
#define DECNUMBERLOC
#define DECNLAUTHOR "Mike Cowlishaw" /* Who to blame */
/* Local names for common types -- 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
/* Tuning parameter */
#define DECBUFFER 36 /* Maximum size basis for local buffers. */
/* Should be a common maximum precision */
/* rounded up to a multiple of 4; must */
/* be non-negative. */
/* Conditional code flags -- set these to 0 for best performance */
#define DECCHECK 0 /* 1 to enable robust checking */
#define DECALLOC 0 /* 1 to enable memory allocation accounting */
#define DECTRACE 0 /* 1 to trace critical intermediates, etc. */
/* Development use defines */
#if DECALLOC
/* if these interfere with your C includes, just comment them out */
#define int ? /* enable to ensure we do not use plain C */
#define long ?? /* .. 'int' or 'long' types from here on */
#endif
/* Limits and constants */
#define DECNUMMAXP 999999999 /* maximum precision we can handle (9 digits) */
#define DECNUMMAXE 999999999 /* maximum adjusted exponent ditto (9 digits) */
#define DECNUMMINE -999999999 /* minimum adjusted exponent ditto (9 digits) */
#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 */
#if DECDPUN==1
#define DECDPUNMAX 9
#elif DECDPUN==2
#define DECDPUNMAX 99
#elif DECDPUN==3
#define DECDPUNMAX 999
#elif DECDPUN==4
#define DECDPUNMAX 9999
#elif DECDPUN==5
#define DECDPUNMAX 99999
#elif DECDPUN==6
#define DECDPUNMAX 999999
#elif DECDPUN==7
#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
/* ----- Shared data ----- */
/* The powers of of ten array (powers[n]==10**n, 0<=n<=10) */
extern const uInt powers[];
/* ----- 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 */
/* X10 and X100 -- multiply integer i by 10 or 100 */
/* [shifts are usually faster than multiply; could be conditional] */
#define X10(i) (((i)<<1)+((i)<<3))
#define X100(i) (((i)<<2)+((i)<<5)+((i)<<6))
/* D2U -- return the number of Units needed to hold d digits */
#if DECDPUN==8
#define D2U(d) ((unsigned)((d)+7)>>3)
#elif DECDPUN==4
#define D2U(d) ((unsigned)((d)+3)>>2)
#else
#define D2U(d) (((d)+DECDPUN-1)/DECDPUN)
#endif
#else
#error decNumberLocal included more than once
#endif

92
libdecnumber/decRound.c Normal file
View file

@ -0,0 +1,92 @@
/* Temporary support for a libc-like fp environment for decimal float.
Copyright (C) 2005 Free Software Foundation, Inc.
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.
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 "decContext.h"
#define FE_DEC_DOWNWARD 0
#define FE_DEC_TONEAREST 1
#define FE_DEC_TONEARESTFROMZERO 2
#define FE_DEC_TOWARDZERO 3
#define FE_DEC_UPWARD 4
#define FE_DEC_MAX 5
extern void __dfp_set_round (int);
extern int __dfp_get_round (void);
extern enum rounding __decGetRound (void);
/* FIXME: these should be in thread-local storage for runtime support. */
static enum rounding __dfp_rounding_mode = DEC_ROUND_HALF_EVEN;
/* Set the decNumber rounding mode from the FE_DEC_* value in MODE. */
void
__dfp_set_round (int mode)
{
switch (mode)
{
case FE_DEC_DOWNWARD:
__dfp_rounding_mode = DEC_ROUND_FLOOR; break;
case FE_DEC_TONEAREST:
__dfp_rounding_mode = DEC_ROUND_HALF_EVEN; break;
case FE_DEC_TONEARESTFROMZERO:
__dfp_rounding_mode = DEC_ROUND_HALF_UP; break;
case FE_DEC_TOWARDZERO:
__dfp_rounding_mode = DEC_ROUND_DOWN; break;
case FE_DEC_UPWARD:
__dfp_rounding_mode = DEC_ROUND_CEILING; break;
default:
/* We can't use assert in libgcc, so just return the default mode. */
__dfp_rounding_mode = DEC_ROUND_HALF_EVEN; break;
}
}
/* Return the decNumber rounding mode as an FE_DEC_* value. */
int
__dfp_get_round (void)
{
int mode;
switch (__dfp_rounding_mode)
{
case DEC_ROUND_FLOOR:
mode = FE_DEC_DOWNWARD; break;
case DEC_ROUND_HALF_EVEN:
mode = FE_DEC_TONEAREST; break;
case DEC_ROUND_HALF_UP:
mode = FE_DEC_TONEARESTFROMZERO; break;
case DEC_ROUND_DOWN:
mode = FE_DEC_TOWARDZERO; break;
case DEC_ROUND_CEILING:
mode = FE_DEC_UPWARD; break;
default:
/* We shouldn't get here, but can't use assert in libgcc. */
mode = -1;
}
return mode;
}
/* Return the decNumber version of the current rounding mode. */
enum rounding
__decGetRound (void)
{
return __dfp_rounding_mode;
}

372
libdecnumber/decUtility.c Normal file
View file

@ -0,0 +1,372 @@
/* 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.
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, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#include "decNumber.h" /* base number library */
#include "decNumberLocal.h" /* decNumber local types, etc. */
#include "decUtility.h" /* utility routines */
#include "tconfig.h"
#include "coretypes.h"
#include "tm.h"
/* ================================================================== */
/* 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 (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 */
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, *source, *first; /* 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 (uByte * bytes, Int len, decNumber * dn,
Int bunches, Int odd)
{
uInt dpd = 0; /* collector for 10 bits */
Int n; /* counter */
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;
}
unsigned long
__dec_byte_swap (unsigned long in)
{
unsigned long out;
unsigned char *p = (unsigned char *) &out;
union {
unsigned long 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;
}

29
libdecnumber/decUtility.h Normal file
View file

@ -0,0 +1,29 @@
/* 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.
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, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#ifdef IN_LIBGCC2
#define decDensePackCoeff __decDensePackCoeff
#define decDenseUnpackCoeff __decDenseUnpackCoeff
#endif
extern void decDensePackCoeff (decNumber *, uByte *, Int, Int);
extern void decDenseUnpackCoeff (uByte *, Int, decNumber *, Int, Int);
extern unsigned long __dec_byte_swap (unsigned long in);

337
libdecnumber/decimal128.c Normal file
View file

@ -0,0 +1,337 @@
/* Decimal 128-bit format module from 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.
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, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
/* ------------------------------------------------------------------ */
/* This module comprises the routines for decimal128 format numbers. */
/* Conversions are supplied to and from decNumber and String. */
/* */
/* No arithmetic routines are included; decNumber provides these. */
/* */
/* Error handling is the same as decNumber (qv.). */
/* ------------------------------------------------------------------ */
#include <string.h> /* [for memset/memcpy] */
#include <stdio.h> /* [for printf] */
#define DECNUMDIGITS 34 /* we need decNumbers with space for 34 */
#include "decNumber.h" /* base number library */
#include "decNumberLocal.h" /* decNumber local types, etc. */
#include "decimal128.h" /* our primary include */
#include "decUtility.h" /* utility routines */
#if DECTRACE || DECCHECK
void decimal128Show (decimal128 *); /* for debug */
void decNumberShow (decNumber *); /* .. */
#endif
/* Useful macro */
/* Clear a structure (e.g., a decNumber) */
#define DEC_clear(d) memset(d, 0, sizeof(*d))
/* ------------------------------------------------------------------ */
/* decimal128FromNumber -- convert decNumber to decimal128 */
/* */
/* ds is the target decimal128 */
/* dn is the source number (assumed valid) */
/* set is the context, used only for reporting errors */
/* */
/* The set argument is used only for status reporting and for the */
/* rounding mode (used if the coefficient is more than DECIMAL128_Pmax*/
/* digits or an overflow is detected). If the exponent is out of the */
/* valid range then Overflow or Underflow will be raised. */
/* After Underflow a subnormal result is possible. */
/* */
/* DEC_Clamped is set if the number has to be 'folded down' to fit, */
/* by reducing its exponent and multiplying the coefficient by a */
/* power of ten, or if the exponent on a zero had to be clamped. */
/* ------------------------------------------------------------------ */
decimal128 *
decimal128FromNumber (decimal128 * d128, decNumber * dn, decContext * set)
{
uInt status = 0; /* status accumulator */
Int pad = 0; /* coefficient pad digits */
decNumber dw; /* work */
decContext dc; /* .. */
uByte isneg = dn->bits & DECNEG; /* non-0 if original sign set */
uInt comb, exp; /* work */
/* 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 > 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 (dn->bits & DECSPECIAL)
{ /* a special value */
uByte top; /* work */
if (dn->bits & DECINF)
top = DECIMAL_Inf;
else
{ /* sNaN or qNaN */
if ((*dn->lsu != 0 || dn->digits > 1) /* non-zero coefficient */
&& (dn->digits < DECIMAL128_Pmax))
{ /* coefficient fits */
decDensePackCoeff (dn, d128->bytes, sizeof (d128->bytes), 0);
}
if (dn->bits & DECNAN)
top = DECIMAL_NaN;
else
top = DECIMAL_sNaN;
}
d128->bytes[0] = top;
}
else if (decNumberIsZero (dn))
{ /* a zero */
/* set and clamp exponent */
if (dn->exponent < -DECIMAL128_Bias)
{
exp = 0;
status |= DEC_Clamped;
}
else
{
exp = dn->exponent + DECIMAL128_Bias; /* bias exponent */
if (exp > DECIMAL128_Ehigh)
{ /* top clamp */
exp = DECIMAL128_Ehigh;
status |= DEC_Clamped;
}
}
comb = (exp >> 9) & 0x18; /* combination field */
d128->bytes[0] = (uByte) (comb << 2);
exp &= 0xfff; /* remaining exponent bits */
decimal128SetExpCon (d128, exp);
}
else
{ /* non-zero finite number */
uInt msd; /* work */
/* we have a dn that fits, but it may need to be padded */
exp = (uInt) (dn->exponent + DECIMAL128_Bias); /* bias exponent */
if (exp > DECIMAL128_Ehigh)
{ /* fold-down case */
pad = exp - DECIMAL128_Ehigh;
exp = DECIMAL128_Ehigh; /* [to maximum] */
status |= DEC_Clamped;
}
decDensePackCoeff (dn, d128->bytes, sizeof (d128->bytes), pad);
/* save and clear the top digit */
msd = ((unsigned) d128->bytes[1] << 2) & 0x0c; /* top 2 bits */
msd |= ((unsigned) d128->bytes[2] >> 6); /* low 2 bits */
d128->bytes[1] &= 0xfc;
d128->bytes[2] &= 0x3f;
/* create the combination field */
if (msd >= 8)
comb = 0x18 | (msd & 0x01) | ((exp >> 11) & 0x06);
else
comb = (msd & 0x07) | ((exp >> 9) & 0x18);
d128->bytes[0] = (uByte) (comb << 2);
exp &= 0xfff; /* remaining exponent bits */
decimal128SetExpCon (d128, exp);
}
if (isneg)
decimal128SetSign (d128, 1);
if (status != 0)
decContextSetStatus (set, status); /* pass on status */
/* decimal128Show(d128); */
return d128;
}
/* ------------------------------------------------------------------ */
/* decimal128ToNumber -- convert decimal128 to decNumber */
/* d128 is the source decimal128 */
/* dn is the target number, with appropriate space */
/* No error is possible. */
/* ------------------------------------------------------------------ */
decNumber *
decimal128ToNumber (decimal128 * d128, decNumber * dn)
{
uInt msd; /* coefficient MSD */
decimal128 wk; /* working copy, if needed */
uInt top = d128->bytes[0] & 0x7f; /* top byte, less sign bit */
decNumberZero (dn); /* clean target */
/* set the sign if negative */
if (decimal128Sign (d128))
dn->bits = DECNEG;
if (top >= 0x78)
{ /* is a special */
if ((top & 0x7c) == (DECIMAL_Inf & 0x7c))
dn->bits |= DECINF;
else if ((top & 0x7e) == (DECIMAL_NaN & 0x7e))
dn->bits |= DECNAN;
else
dn->bits |= DECSNAN;
msd = 0; /* no top digit */
}
else
{ /* have a finite number */
uInt comb = top >> 2; /* combination field */
uInt exp; /* exponent */
if (comb >= 0x18)
{
msd = 8 + (comb & 0x01);
exp = (comb & 0x06) << 11; /* MSBs */
}
else
{
msd = comb & 0x07;
exp = (comb & 0x18) << 9;
}
dn->exponent = exp + decimal128ExpCon (d128) - DECIMAL128_Bias; /* remove bias */
}
/* get the coefficient, unless infinite */
if (!(dn->bits & DECINF))
{
Int bunches = DECIMAL128_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 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);
}
/* decNumberShow(dn); */
return dn;
}
/* ------------------------------------------------------------------ */
/* to-scientific-string -- conversion to numeric string */
/* to-engineering-string -- conversion to numeric string */
/* */
/* decimal128ToString(d128, string); */
/* decimal128ToEngString(d128, string); */
/* */
/* d128 is the decimal128 format number to convert */
/* string is the string where the result will be laid out */
/* */
/* string must be at least 24 characters */
/* */
/* No error is possible, and no status can be set. */
/* ------------------------------------------------------------------ */
char *
decimal128ToString (decimal128 * d128, char *string)
{
decNumber dn; /* work */
decimal128ToNumber (d128, &dn);
decNumberToString (&dn, string);
return string;
}
char *
decimal128ToEngString (decimal128 * d128, char *string)
{
decNumber dn; /* work */
decimal128ToNumber (d128, &dn);
decNumberToEngString (&dn, string);
return string;
}
/* ------------------------------------------------------------------ */
/* to-number -- conversion from numeric string */
/* */
/* decimal128FromString(result, string, set); */
/* */
/* result is the decimal128 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) */
/* set is the context */
/* */
/* The context is supplied to this routine is used for error handling */
/* (setting of status and traps) and for the rounding mode, only. */
/* If an error occurs, the result will be a valid decimal128 NaN. */
/* ------------------------------------------------------------------ */
decimal128 *
decimal128FromString (decimal128 * result, char *string, decContext * set)
{
decContext dc; /* work */
decNumber dn; /* .. */
decContextDefault (&dc, DEC_INIT_DECIMAL128); /* no traps, please */
dc.round = set->round; /* use supplied rounding */
decNumberFromString (&dn, string, &dc); /* will round if needed */
decimal128FromNumber (result, &dn, &dc);
if (dc.status != 0)
{ /* something happened */
decContextSetStatus (set, dc.status); /* .. pass it on */
}
return result;
}
#if DECTRACE || DECCHECK
/* ------------------------------------------------------------------ */
/* decimal128Show -- display a single in hexadecimal [debug aid] */
/* d128 -- the number to show */
/* ------------------------------------------------------------------ */
/* Also shows sign/cob/expconfields extracted */
void
decimal128Show (decimal128 * d128)
{
char buf[DECIMAL128_Bytes * 2 + 1];
Int i, j;
j = 0;
for (i = 0; i < DECIMAL128_Bytes; i++)
{
sprintf (&buf[j], "%02x", d128->bytes[i]);
j = j + 2;
}
printf (" D128> %s [S:%d Cb:%02x E:%d]\n", buf,
decimal128Sign (d128), decimal128Comb (d128),
decimal128ExpCon (d128));
}
#endif

113
libdecnumber/decimal128.h Normal file
View file

@ -0,0 +1,113 @@
/* Decimal 128-bit format 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.
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, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#if !defined(DECIMAL128)
#define DECIMAL128
#define DEC128NAME "decimal128" /* Short name */
#define DEC128FULLNAME "Decimal 128-bit Number" /* Verbose name */
#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 */
#define DECIMAL128_Bytes 16 /* length */
#define DECIMAL128_Pmax 34 /* maximum precision (digits) */
#define DECIMAL128_Emax 6144 /* maximum adjusted exponent */
#define DECIMAL128_Emin -6143 /* minimum adjusted exponent */
#define DECIMAL128_Bias 6176 /* bias for the exponent */
#define DECIMAL128_String 43 /* maximum string length, +1 */
/* highest biased exponent (Elimit-1) */
#define DECIMAL128_Ehigh (DECIMAL128_Emax+DECIMAL128_Bias-DECIMAL128_Pmax+1)
#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 */
typedef struct
{
uint8_t bytes[DECIMAL128_Bytes]; /* decimal128: 1, 5, 12, 110 bits */
} 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 */
#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);}
/* ------------------------------------------------------------------ */
/* Routines */
/* ------------------------------------------------------------------ */
#ifdef IN_LIBGCC2
#define decimal128FromString __decimal128FromString
#define decimal128ToString __decimal128ToString
#define decimal128ToEngString __decimal128ToEngString
#define decimal128FromNumber __decimal128FromNumber
#define decimal128ToNumber __decimal128ToNumber
#endif
/* String conversions */
decimal128 *decimal128FromString (decimal128 *, char *, decContext *);
char *decimal128ToString (decimal128 *, char *);
char *decimal128ToEngString (decimal128 *, char *);
/* decNumber conversions */
decimal128 *decimal128FromNumber (decimal128 *, decNumber *, decContext *);
decNumber *decimal128ToNumber (decimal128 *, decNumber *);
#endif

327
libdecnumber/decimal32.c Normal file
View file

@ -0,0 +1,327 @@
/* Decimal 32-bit format module 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.
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, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
/* ------------------------------------------------------------------ */
/* This module comprises the routines for decimal32 format numbers. */
/* Conversions are supplied to and from decNumber and String. */
/* */
/* No arithmetic routines are included; decNumber provides these. */
/* */
/* Error handling is the same as decNumber (qv.). */
/* ------------------------------------------------------------------ */
#include <string.h> /* [for memset/memcpy] */
#include <stdio.h> /* [for printf] */
#define DECNUMDIGITS 7 /* we need decNumbers with space for 7 */
#include "decNumber.h" /* base number library */
#include "decNumberLocal.h" /* decNumber local types, etc. */
#include "decimal32.h" /* our primary include */
#include "decUtility.h" /* utility routines */
#if DECTRACE || DECCHECK
void decimal32Show (decimal32 *); /* for debug */
void decNumberShow (decNumber *); /* .. */
#endif
/* Useful macro */
/* Clear a structure (e.g., a decNumber) */
#define DEC_clear(d) memset(d, 0, sizeof(*d))
/* ------------------------------------------------------------------ */
/* decimal32FromNumber -- convert decNumber to decimal32 */
/* */
/* ds is the target decimal32 */
/* dn is the source number (assumed valid) */
/* set is the context, used only for reporting errors */
/* */
/* The set argument is used only for status reporting and for the */
/* rounding mode (used if the coefficient is more than DECIMAL32_Pmax */
/* digits or an overflow is detected). If the exponent is out of the */
/* valid range then Overflow or Underflow will be raised. */
/* After Underflow a subnormal result is possible. */
/* */
/* DEC_Clamped is set if the number has to be 'folded down' to fit, */
/* by reducing its exponent and multiplying the coefficient by a */
/* power of ten, or if the exponent on a zero had to be clamped. */
/* ------------------------------------------------------------------ */
decimal32 *
decimal32FromNumber (decimal32 * d32, decNumber * dn, decContext * set)
{
uInt status = 0; /* status accumulator */
Int pad = 0; /* coefficient pad digits */
decNumber dw; /* work */
decContext dc; /* .. */
uByte isneg = dn->bits & DECNEG; /* non-0 if original sign set */
uInt comb, exp; /* work */
/* 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 (dn->bits & DECSPECIAL)
{ /* a special value */
uByte top; /* work */
if (dn->bits & DECINF)
top = DECIMAL_Inf;
else
{ /* sNaN or qNaN */
if ((*dn->lsu != 0 || dn->digits > 1) /* non-zero coefficient */
&& (dn->digits < DECIMAL32_Pmax))
{ /* coefficient fits */
decDensePackCoeff (dn, d32->bytes, sizeof (d32->bytes), 0);
}
if (dn->bits & DECNAN)
top = DECIMAL_NaN;
else
top = DECIMAL_sNaN;
}
d32->bytes[0] = top;
}
else if (decNumberIsZero (dn))
{ /* a zero */
/* set and clamp exponent */
if (dn->exponent < -DECIMAL32_Bias)
{
exp = 0;
status |= DEC_Clamped;
}
else
{
exp = dn->exponent + DECIMAL32_Bias; /* bias exponent */
if (exp > DECIMAL32_Ehigh)
{ /* top clamp */
exp = DECIMAL32_Ehigh;
status |= DEC_Clamped;
}
}
comb = (exp >> 3) & 0x18; /* combination field */
d32->bytes[0] = (uByte) (comb << 2);
exp &= 0x3f; /* remaining exponent bits */
decimal32SetExpCon (d32, exp);
}
else
{ /* non-zero finite number */
uInt msd; /* work */
/* we have a dn that fits, but it may need to be padded */
exp = (uInt) (dn->exponent + DECIMAL32_Bias); /* bias exponent */
if (exp > DECIMAL32_Ehigh)
{ /* fold-down case */
pad = exp - DECIMAL32_Ehigh;
exp = DECIMAL32_Ehigh; /* [to maximum] */
status |= DEC_Clamped;
}
decDensePackCoeff (dn, d32->bytes, sizeof (d32->bytes), pad);
/* save and clear the top digit */
msd = ((unsigned) d32->bytes[1] >> 4);
d32->bytes[1] &= 0x0f;
/* create the combination field */
if (msd >= 8)
comb = 0x18 | (msd & 0x01) | ((exp >> 5) & 0x06);
else
comb = (msd & 0x07) | ((exp >> 3) & 0x18);
d32->bytes[0] = (uByte) (comb << 2);
exp &= 0x3f; /* remaining exponent bits */
decimal32SetExpCon (d32, exp);
}
if (isneg)
decimal32SetSign (d32, 1);
if (status != 0)
decContextSetStatus (set, status); /* pass on status */
/*decimal32Show(d32); */
return d32;
}
/* ------------------------------------------------------------------ */
/* decimal32ToNumber -- convert decimal32 to decNumber */
/* d32 is the source decimal32 */
/* dn is the target number, with appropriate space */
/* No error is possible. */
/* ------------------------------------------------------------------ */
decNumber *
decimal32ToNumber (decimal32 * d32, decNumber * dn)
{
uInt msd; /* coefficient MSD */
decimal32 wk; /* working copy, if needed */
uInt top = d32->bytes[0] & 0x7f; /* top byte, less sign bit */
decNumberZero (dn); /* clean target */
/* set the sign if negative */
if (decimal32Sign (d32))
dn->bits = DECNEG;
if (top >= 0x78)
{ /* is a special */
if ((top & 0x7c) == (DECIMAL_Inf & 0x7c))
dn->bits |= DECINF;
else if ((top & 0x7e) == (DECIMAL_NaN & 0x7e))
dn->bits |= DECNAN;
else
dn->bits |= DECSNAN;
msd = 0; /* no top digit */
}
else
{ /* have a finite number */
uInt comb = top >> 2; /* combination field */
uInt exp; /* working exponent */
if (comb >= 0x18)
{
msd = 8 + (comb & 0x01);
exp = (comb & 0x06) << 5; /* MSBs */
}
else
{
msd = comb & 0x07;
exp = (comb & 0x18) << 3;
}
dn->exponent = exp + decimal32ExpCon (d32) - DECIMAL32_Bias; /* remove bias */
}
/* get the coefficient, unless infinite */
if (!(dn->bits & DECINF))
{
Int bunches = DECIMAL32_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 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);
}
return dn;
}
/* ------------------------------------------------------------------ */
/* to-scientific-string -- conversion to numeric string */
/* to-engineering-string -- conversion to numeric string */
/* */
/* decimal32ToString(d32, string); */
/* decimal32ToEngString(d32, string); */
/* */
/* d32 is the decimal32 format number to convert */
/* string is the string where the result will be laid out */
/* */
/* string must be at least 24 characters */
/* */
/* No error is possible, and no status can be set. */
/* ------------------------------------------------------------------ */
char *
decimal32ToString (decimal32 * d32, char *string)
{
decNumber dn; /* work */
decimal32ToNumber (d32, &dn);
decNumberToString (&dn, string);
return string;
}
char *
decimal32ToEngString (decimal32 * d32, char *string)
{
decNumber dn; /* work */
decimal32ToNumber (d32, &dn);
decNumberToEngString (&dn, string);
return string;
}
/* ------------------------------------------------------------------ */
/* to-number -- conversion from numeric string */
/* */
/* decimal32FromString(result, string, set); */
/* */
/* result is the decimal32 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) */
/* set is the context */
/* */
/* The context is supplied to this routine is used for error handling */
/* (setting of status and traps) and for the rounding mode, only. */
/* If an error occurs, the result will be a valid decimal32 NaN. */
/* ------------------------------------------------------------------ */
decimal32 *
decimal32FromString (decimal32 * result, char *string, decContext * set)
{
decContext dc; /* work */
decNumber dn; /* .. */
decContextDefault (&dc, DEC_INIT_DECIMAL32); /* no traps, please */
dc.round = set->round; /* use supplied rounding */
decNumberFromString (&dn, string, &dc); /* will round if needed */
decimal32FromNumber (result, &dn, &dc);
if (dc.status != 0)
{ /* something happened */
decContextSetStatus (set, dc.status); /* .. pass it on */
}
return result;
}
#if DECTRACE || DECCHECK
/* ------------------------------------------------------------------ */
/* decimal32Show -- display a single in hexadecimal [debug aid] */
/* d32 -- the number to show */
/* ------------------------------------------------------------------ */
/* Also shows sign/cob/expconfields extracted */
void
decimal32Show (decimal32 * d32)
{
char buf[DECIMAL32_Bytes * 2 + 1];
Int i, j;
j = 0;
for (i = 0; i < DECIMAL32_Bytes; i++)
{
sprintf (&buf[j], "%02x", d32->bytes[i]);
j = j + 2;
}
printf (" D32> %s [S:%d Cb:%02x E:%d]\n", buf,
decimal32Sign (d32), decimal32Comb (d32), decimal32ExpCon (d32));
}
#endif

103
libdecnumber/decimal32.h Normal file
View file

@ -0,0 +1,103 @@
/* Decimal 32-bit format 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.
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, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#if !defined(DECIMAL32)
#define DECIMAL32
#define DEC32NAME "decimal32" /* Short name */
#define DEC32FULLNAME "Decimal 32-bit Number" /* Verbose name */
#define DEC32AUTHOR "Mike Cowlishaw" /* Who to blame */
/* parameters for decimal32s */
#define DECIMAL32_Bytes 4 /* length */
#define DECIMAL32_Pmax 7 /* maximum precision (digits) */
#define DECIMAL32_Emax 96 /* maximum adjusted exponent */
#define DECIMAL32_Emin -95 /* minimum adjusted exponent */
#define DECIMAL32_Bias 101 /* bias for the exponent */
#define DECIMAL32_String 15 /* maximum string length, +1 */
/* highest biased exponent (Elimit-1) */
#define DECIMAL32_Ehigh (DECIMAL32_Emax+DECIMAL32_Bias-DECIMAL32_Pmax+1)
#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 */
typedef struct
{
uint8_t bytes[DECIMAL32_Bytes]; /* decimal32: 1, 5, 6, 20 bits */
} decimal32;
/* 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 decimal32 fields. These assume the argument
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);}
/* 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);}
/* ------------------------------------------------------------------ */
/* Routines */
/* ------------------------------------------------------------------ */
#ifdef IN_LIBGCC2
#define decimal32FromString __decimal32FromString
#define decimal32ToString __decimal32ToString
#define decimal32ToEngString __decimal32ToEngString
#define decimal32FromNumber __decimal32FromNumber
#define decimal32ToNumber __decimal32ToNumber
#endif
/* String conversions. */
decimal32 *decimal32FromString (decimal32 *, char *, decContext *);
char *decimal32ToString (decimal32 *, char *);
char *decimal32ToEngString (decimal32 *, char *);
/* decNumber conversions. */
decimal32 *decimal32FromNumber (decimal32 *, decNumber *, decContext *);
decNumber *decimal32ToNumber (decimal32 *, decNumber *);
#endif

327
libdecnumber/decimal64.c Normal file
View file

@ -0,0 +1,327 @@
/* Decimal 64-bit format module 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.
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, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
/* ------------------------------------------------------------------ */
/* This module comprises the routines for decimal64 format numbers. */
/* Conversions are supplied to and from decNumber and String. */
/* */
/* No arithmetic routines are included; decNumber provides these. */
/* */
/* Error handling is the same as decNumber (qv.). */
/* ------------------------------------------------------------------ */
#include <string.h> /* [for memset/memcpy] */
#include <stdio.h> /* [for printf] */
#define DECNUMDIGITS 16 /* we need decNumbers with space for 16 */
#include "decNumber.h" /* base number library */
#include "decNumberLocal.h" /* decNumber local types, etc. */
#include "decimal64.h" /* our primary include */
#include "decUtility.h" /* utility routines */
#if DECTRACE || DECCHECK
void decimal64Show (decimal64 *); /* for debug */
void decNumberShow (decNumber *); /* .. */
#endif
/* Useful macro */
/* Clear a structure (e.g., a decNumber) */
#define DEC_clear(d) memset(d, 0, sizeof(*d))
/* ------------------------------------------------------------------ */
/* decimal64FromNumber -- convert decNumber to decimal64 */
/* */
/* ds is the target decimal64 */
/* dn is the source number (assumed valid) */
/* set is the context, used only for reporting errors */
/* */
/* The set argument is used only for status reporting and for the */
/* rounding mode (used if the coefficient is more than DECIMAL64_Pmax */
/* digits or an overflow is detected). If the exponent is out of the */
/* valid range then Overflow or Underflow will be raised. */
/* After Underflow a subnormal result is possible. */
/* */
/* DEC_Clamped is set if the number has to be 'folded down' to fit, */
/* by reducing its exponent and multiplying the coefficient by a */
/* power of ten, or if the exponent on a zero had to be clamped. */
/* ------------------------------------------------------------------ */
decimal64 *
decimal64FromNumber (decimal64 * d64, decNumber * dn, decContext * set)
{
uInt status = 0; /* status accumulator */
Int pad = 0; /* coefficient pad digits */
decNumber dw; /* work */
decContext dc; /* .. */
uByte isneg = dn->bits & DECNEG; /* non-0 if original sign set */
uInt comb, exp; /* work */
/* 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 > DECIMAL64_Pmax /* too many digits */
|| ae > DECIMAL64_Emax /* likely overflow */
|| ae < DECIMAL64_Emin)
{ /* likely underflow */
decContextDefault (&dc, DEC_INIT_DECIMAL64); /* [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 decimal64] */
}
DEC_clear (d64); /* clean the target */
if (dn->bits & DECSPECIAL)
{ /* a special value */
uByte top; /* work */
if (dn->bits & DECINF)
top = DECIMAL_Inf;
else
{ /* sNaN or qNaN */
if ((*dn->lsu != 0 || dn->digits > 1) /* non-zero coefficient */
&& (dn->digits < DECIMAL64_Pmax))
{ /* coefficient fits */
decDensePackCoeff (dn, d64->bytes, sizeof (d64->bytes), 0);
}
if (dn->bits & DECNAN)
top = DECIMAL_NaN;
else
top = DECIMAL_sNaN;
}
d64->bytes[0] = top;
}
else if (decNumberIsZero (dn))
{ /* a zero */
/* set and clamp exponent */
if (dn->exponent < -DECIMAL64_Bias)
{
exp = 0;
status |= DEC_Clamped;
}
else
{
exp = dn->exponent + DECIMAL64_Bias; /* bias exponent */
if (exp > DECIMAL64_Ehigh)
{ /* top clamp */
exp = DECIMAL64_Ehigh;
status |= DEC_Clamped;
}
}
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 */
/* we have a dn that fits, but it may need to be padded */
exp = (uInt) (dn->exponent + DECIMAL64_Bias); /* bias exponent */
if (exp > DECIMAL64_Ehigh)
{ /* fold-down case */
pad = exp - DECIMAL64_Ehigh;
exp = DECIMAL64_Ehigh; /* [to maximum] */
status |= DEC_Clamped;
}
decDensePackCoeff (dn, d64->bytes, sizeof (d64->bytes), pad);
/* save and clear the top digit */
msd = ((unsigned) d64->bytes[1] >> 2) & 0x0f;
d64->bytes[1] &= 0x03;
/* create the combination field */
if (msd >= 8)
comb = 0x18 | (msd & 0x01) | ((exp >> 7) & 0x06);
else
comb = (msd & 0x07) | ((exp >> 5) & 0x18);
d64->bytes[0] = (uByte) (comb << 2);
exp &= 0xff; /* remaining exponent bits */
decimal64SetExpCon (d64, exp);
}
if (isneg)
decimal64SetSign (d64, 1);
if (status != 0)
decContextSetStatus (set, status); /* pass on status */
/*decimal64Show(d64); */
return d64;
}
/* ------------------------------------------------------------------ */
/* decimal64ToNumber -- convert decimal64 to decNumber */
/* d64 is the source decimal64 */
/* dn is the target number, with appropriate space */
/* No error is possible. */
/* ------------------------------------------------------------------ */
decNumber *
decimal64ToNumber (decimal64 * d64, decNumber * dn)
{
uInt msd; /* coefficient MSD */
decimal64 wk; /* working copy, if needed */
uInt top = d64->bytes[0] & 0x7f; /* top byte, less sign bit */
decNumberZero (dn); /* clean target */
/* set the sign if negative */
if (decimal64Sign (d64))
dn->bits = DECNEG;
if (top >= 0x78)
{ /* is a special */
if ((top & 0x7c) == (DECIMAL_Inf & 0x7c))
dn->bits |= DECINF;
else if ((top & 0x7e) == (DECIMAL_NaN & 0x7e))
dn->bits |= DECNAN;
else
dn->bits |= DECSNAN;
msd = 0; /* no top digit */
}
else
{ /* have a finite number */
uInt comb = top >> 2; /* combination field */
uInt exp; /* exponent */
if (comb >= 0x18)
{
msd = 8 + (comb & 0x01);
exp = (comb & 0x06) << 7; /* MSBs */
}
else
{
msd = comb & 0x07;
exp = (comb & 0x18) << 5;
}
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);
}
return dn;
}
/* ------------------------------------------------------------------ */
/* to-scientific-string -- conversion to numeric string */
/* to-engineering-string -- conversion to numeric string */
/* */
/* decimal64ToString(d64, string); */
/* decimal64ToEngString(d64, string); */
/* */
/* d64 is the decimal64 format number to convert */
/* string is the string where the result will be laid out */
/* */
/* string must be at least 24 characters */
/* */
/* No error is possible, and no status can be set. */
/* ------------------------------------------------------------------ */
char *
decimal64ToString (decimal64 * d64, char *string)
{
decNumber dn; /* work */
decimal64ToNumber (d64, &dn);
decNumberToString (&dn, string);
return string;
}
char *
decimal64ToEngString (decimal64 * d64, char *string)
{
decNumber dn; /* work */
decimal64ToNumber (d64, &dn);
decNumberToEngString (&dn, string);
return string;
}
/* ------------------------------------------------------------------ */
/* to-number -- conversion from numeric string */
/* */
/* decimal64FromString(result, string, set); */
/* */
/* result is the decimal64 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) */
/* set is the context */
/* */
/* The context is supplied to this routine is used for error handling */
/* (setting of status and traps) and for the rounding mode, only. */
/* If an error occurs, the result will be a valid decimal64 NaN. */
/* ------------------------------------------------------------------ */
decimal64 *
decimal64FromString (decimal64 * result, char *string, decContext * set)
{
decContext dc; /* work */
decNumber dn; /* .. */
decContextDefault (&dc, DEC_INIT_DECIMAL64); /* no traps, please */
dc.round = set->round; /* use supplied rounding */
decNumberFromString (&dn, string, &dc); /* will round if needed */
decimal64FromNumber (result, &dn, &dc);
if (dc.status != 0)
{ /* something happened */
decContextSetStatus (set, dc.status); /* .. pass it on */
}
return result;
}
#if DECTRACE || DECCHECK
/* ------------------------------------------------------------------ */
/* decimal64Show -- display a single in hexadecimal [debug aid] */
/* d64 -- the number to show */
/* ------------------------------------------------------------------ */
/* Also shows sign/cob/expconfields extracted */
void
decimal64Show (decimal64 * d64)
{
char buf[DECIMAL64_Bytes * 2 + 1];
Int i, j;
j = 0;
for (i = 0; i < DECIMAL64_Bytes; i++)
{
sprintf (&buf[j], "%02x", d64->bytes[i]);
j = j + 2;
}
printf (" D64> %s [S:%d Cb:%02x E:%d]\n", buf,
decimal64Sign (d64), decimal64Comb (d64), decimal64ExpCon (d64));
}
#endif

107
libdecnumber/decimal64.h Normal file
View file

@ -0,0 +1,107 @@
/* Decimal 64-bit format 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.
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, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#if !defined(DECIMAL64)
#define DECIMAL64
#define DEC64NAME "decimal64" /* Short name */
#define DEC64FULLNAME "Decimal 64-bit Number" /* Verbose name */
#define DEC64AUTHOR "Mike Cowlishaw" /* Who to blame */
#if defined(DECIMAL32)
#error decimal64.h must precede decimal32.h for correct DECNUMDIGITS
#endif
/* parameters for decimal64s */
#define DECIMAL64_Bytes 8 /* length */
#define DECIMAL64_Pmax 16 /* maximum precision (digits) */
#define DECIMAL64_Emax 384 /* maximum adjusted exponent */
#define DECIMAL64_Emin -383 /* minimum adjusted exponent */
#define DECIMAL64_Bias 398 /* bias for the exponent */
#define DECIMAL64_String 24 /* maximum string length, +1 */
/* highest biased exponent (Elimit-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 */
#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);}
/* ------------------------------------------------------------------ */
/* Routines */
/* ------------------------------------------------------------------ */
#ifdef IN_LIBGCC2
#define decimal64FromString __decimal64FromString
#define decimal64ToString __decimal64ToString
#define decimal64ToEngString __decimal64ToEngString
#define decimal64FromNumber __decimal64FromNumber
#define decimal64ToNumber __decimal64ToNumber
#endif
/* String conversions */
decimal64 *decimal64FromString (decimal64 *, char *, decContext *);
char *decimal64ToString (decimal64 *, char *);
char *decimal64ToEngString (decimal64 *, char *);
/* decNumber conversions */
decimal64 *decimal64FromNumber (decimal64 *, decNumber *, decContext *);
decNumber *decimal64ToNumber (decimal64 *, decNumber *);
#endif