* libdecnumber: Import decNumber sources from the dfp-branch.
From-SVN: r107629
This commit is contained in:
parent
e669bd2b69
commit
473a74b91e
18 changed files with 9071 additions and 0 deletions
|
@ -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
9
libdecnumber/ChangeLog
Normal 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
218
libdecnumber/decContext.c
Normal 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
178
libdecnumber/decContext.h
Normal 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
525
libdecnumber/decDPD.h
Normal 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
81
libdecnumber/decLibrary.c
Normal 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
5939
libdecnumber/decNumber.c
Normal file
File diff suppressed because it is too large
Load diff
183
libdecnumber/decNumber.h
Normal file
183
libdecnumber/decNumber.h
Normal 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
|
127
libdecnumber/decNumberLocal.h
Normal file
127
libdecnumber/decNumberLocal.h
Normal 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
92
libdecnumber/decRound.c
Normal 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
372
libdecnumber/decUtility.c
Normal 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
29
libdecnumber/decUtility.h
Normal 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
337
libdecnumber/decimal128.c
Normal 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
113
libdecnumber/decimal128.h
Normal 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
327
libdecnumber/decimal32.c
Normal 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
103
libdecnumber/decimal32.h
Normal 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
327
libdecnumber/decimal64.c
Normal 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
107
libdecnumber/decimal64.h
Normal 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
|
Loading…
Add table
Reference in a new issue