merge from gcc
This commit is contained in:
parent
f2be950300
commit
87d32bb7b0
23 changed files with 1977 additions and 1607 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
2009-03-30 Ben Elliston <bje@au.ibm.com>
|
||||||
|
|
||||||
|
* decNumber.c, decNumber.h, decNumberLocal.h, decDouble.c,
|
||||||
|
decDouble.h, decSingle.c, decContext.c, decSingle.h, decPacked.c,
|
||||||
|
decCommon.c, decContext.h, decQuad.c, decPacked.h, decQuad.h,
|
||||||
|
decDPD.h, decBasic.c: Upgrade to decNumber 3.61.
|
||||||
|
* dpd/decimal128.h, dpd/decimal32.c, dpd/decimal32.h,
|
||||||
|
dpd/decimal64.c, dpd/decimal128.c, dpd/decimal64.h: Likewise.
|
||||||
|
|
||||||
2009-02-10 Joseph Myers <joseph@codesourcery.com>
|
2009-02-10 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
* Makefile.in (clean): Don't remove makedepend$(EXEEXT).
|
* Makefile.in (clean): Don't remove makedepend$(EXEEXT).
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -38,15 +38,13 @@
|
||||||
#include <string.h> /* for strcmp */
|
#include <string.h> /* for strcmp */
|
||||||
#include <stdio.h> /* for printf if DECCHECK */
|
#include <stdio.h> /* for printf if DECCHECK */
|
||||||
#include "dconfig.h" /* for GCC definitions */
|
#include "dconfig.h" /* for GCC definitions */
|
||||||
#include "decContext.h" /* context and base types */
|
#include "decContext.h" /* context and base types */
|
||||||
#include "decNumberLocal.h" /* decNumber local types, etc. */
|
#include "decNumberLocal.h" /* decNumber local types, etc. */
|
||||||
|
|
||||||
#if DECCHECK
|
|
||||||
/* compile-time endian tester [assumes sizeof(Int)>1] */
|
/* compile-time endian tester [assumes sizeof(Int)>1] */
|
||||||
static const Int mfcone=1; /* constant 1 */
|
static const Int mfcone=1; /* constant 1 */
|
||||||
static const Flag *mfctop=(Flag *)&mfcone; /* -> top byte */
|
static const Flag *mfctop=(const Flag *)&mfcone; /* -> top byte */
|
||||||
#define LITEND *mfctop /* named flag; 1=little-endian */
|
#define LITEND *mfctop /* named flag; 1=little-endian */
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* round-for-reround digits */
|
/* round-for-reround digits */
|
||||||
|
@ -64,7 +62,7 @@ const uInt DECPOWERS[10]={1, 10, 100, 1000, 10000, 100000, 1000000,
|
||||||
/* */
|
/* */
|
||||||
/* context is the context structure to be queried */
|
/* context is the context structure to be queried */
|
||||||
/* mask indicates the bits to be cleared (the status bit that */
|
/* mask indicates the bits to be cleared (the status bit that */
|
||||||
/* corresponds to each 1 bit in the mask is cleared) */
|
/* corresponds to each 1 bit in the mask is cleared) */
|
||||||
/* returns context */
|
/* returns context */
|
||||||
/* */
|
/* */
|
||||||
/* No error is possible. */
|
/* No error is possible. */
|
||||||
|
@ -80,9 +78,9 @@ decContext *decContextClearStatus(decContext *context, uInt mask) {
|
||||||
/* context is the structure to be initialized */
|
/* context is the structure to be initialized */
|
||||||
/* kind selects the required set of default values, one of: */
|
/* kind selects the required set of default values, one of: */
|
||||||
/* DEC_INIT_BASE -- select ANSI X3-274 defaults */
|
/* DEC_INIT_BASE -- select ANSI X3-274 defaults */
|
||||||
/* DEC_INIT_DECIMAL32 -- select IEEE 754r defaults, 32-bit */
|
/* DEC_INIT_DECIMAL32 -- select IEEE 754 defaults, 32-bit */
|
||||||
/* DEC_INIT_DECIMAL64 -- select IEEE 754r defaults, 64-bit */
|
/* DEC_INIT_DECIMAL64 -- select IEEE 754 defaults, 64-bit */
|
||||||
/* DEC_INIT_DECIMAL128 -- select IEEE 754r defaults, 128-bit */
|
/* DEC_INIT_DECIMAL128 -- select IEEE 754 defaults, 128-bit */
|
||||||
/* For any other value a valid context is returned, but with */
|
/* For any other value a valid context is returned, but with */
|
||||||
/* Invalid_operation set in the status field. */
|
/* Invalid_operation set in the status field. */
|
||||||
/* returns a context structure with the appropriate initial values. */
|
/* returns a context structure with the appropriate initial values. */
|
||||||
|
@ -105,11 +103,11 @@ decContext * decContextDefault(decContext *context, Int kind) {
|
||||||
break;
|
break;
|
||||||
case DEC_INIT_DECIMAL32:
|
case DEC_INIT_DECIMAL32:
|
||||||
context->digits=7; /* digits */
|
context->digits=7; /* digits */
|
||||||
context->emax=96; /* Emax */
|
context->emax=96; /* Emax */
|
||||||
context->emin=-95; /* Emin */
|
context->emin=-95; /* Emin */
|
||||||
context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
|
context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
|
||||||
context->traps=0; /* no traps set */
|
context->traps=0; /* no traps set */
|
||||||
context->clamp=1; /* clamp exponents */
|
context->clamp=1; /* clamp exponents */
|
||||||
#if DECSUBSET
|
#if DECSUBSET
|
||||||
context->extended=1; /* set */
|
context->extended=1; /* set */
|
||||||
#endif
|
#endif
|
||||||
|
@ -119,8 +117,8 @@ decContext * decContextDefault(decContext *context, Int kind) {
|
||||||
context->emax=384; /* Emax */
|
context->emax=384; /* Emax */
|
||||||
context->emin=-383; /* Emin */
|
context->emin=-383; /* Emin */
|
||||||
context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
|
context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
|
||||||
context->traps=0; /* no traps set */
|
context->traps=0; /* no traps set */
|
||||||
context->clamp=1; /* clamp exponents */
|
context->clamp=1; /* clamp exponents */
|
||||||
#if DECSUBSET
|
#if DECSUBSET
|
||||||
context->extended=1; /* set */
|
context->extended=1; /* set */
|
||||||
#endif
|
#endif
|
||||||
|
@ -130,8 +128,8 @@ decContext * decContextDefault(decContext *context, Int kind) {
|
||||||
context->emax=6144; /* Emax */
|
context->emax=6144; /* Emax */
|
||||||
context->emin=-6143; /* Emin */
|
context->emin=-6143; /* Emin */
|
||||||
context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
|
context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
|
||||||
context->traps=0; /* no traps set */
|
context->traps=0; /* no traps set */
|
||||||
context->clamp=1; /* clamp exponents */
|
context->clamp=1; /* clamp exponents */
|
||||||
#if DECSUBSET
|
#if DECSUBSET
|
||||||
context->extended=1; /* set */
|
context->extended=1; /* set */
|
||||||
#endif
|
#endif
|
||||||
|
@ -142,15 +140,6 @@ decContext * decContextDefault(decContext *context, Int kind) {
|
||||||
decContextSetStatus(context, DEC_Invalid_operation); /* trap */
|
decContextSetStatus(context, DEC_Invalid_operation); /* trap */
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DECCHECK
|
|
||||||
if (LITEND!=DECLITEND) {
|
|
||||||
const char *adj;
|
|
||||||
if (LITEND) adj="little";
|
|
||||||
else adj="big";
|
|
||||||
printf("Warning: DECLITEND is set to %d, but this computer appears to be %s-endian\n",
|
|
||||||
DECLITEND, adj);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return context;} /* decContextDefault */
|
return context;} /* decContextDefault */
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
@ -166,7 +155,7 @@ enum rounding decContextGetRounding(decContext *context) {
|
||||||
} /* decContextGetRounding */
|
} /* decContextGetRounding */
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decContextGetStatus -- return current status */
|
/* decContextGetStatus -- return current status */
|
||||||
/* */
|
/* */
|
||||||
/* context is the context structure to be queried */
|
/* context is the context structure to be queried */
|
||||||
/* returns status */
|
/* returns status */
|
||||||
|
@ -181,8 +170,8 @@ uInt decContextGetStatus(decContext *context) {
|
||||||
/* decContextRestoreStatus -- restore bits in current status */
|
/* decContextRestoreStatus -- restore bits in current status */
|
||||||
/* */
|
/* */
|
||||||
/* context is the context structure to be updated */
|
/* context is the context structure to be updated */
|
||||||
/* newstatus is the source for the bits to be restored */
|
/* newstatus is the source for the bits to be restored */
|
||||||
/* mask indicates the bits to be restored (the status bit that */
|
/* mask indicates the bits to be restored (the status bit that */
|
||||||
/* corresponds to each 1 bit in the mask is set to the value of */
|
/* corresponds to each 1 bit in the mask is set to the value of */
|
||||||
/* the correspnding bit in newstatus) */
|
/* the correspnding bit in newstatus) */
|
||||||
/* returns context */
|
/* returns context */
|
||||||
|
@ -252,7 +241,7 @@ decContext * decContextSetStatus(decContext *context, uInt status) {
|
||||||
/* */
|
/* */
|
||||||
/* returns the context structure, unless the string is equal to */
|
/* returns the context structure, unless the string is equal to */
|
||||||
/* DEC_Condition_MU or is not recognized. In these cases NULL is */
|
/* DEC_Condition_MU or is not recognized. In these cases NULL is */
|
||||||
/* returned. */
|
/* returned. */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
decContext * decContextSetStatusFromString(decContext *context,
|
decContext * decContextSetStatusFromString(decContext *context,
|
||||||
const char *string) {
|
const char *string) {
|
||||||
|
@ -303,7 +292,7 @@ decContext * decContextSetStatusFromString(decContext *context,
|
||||||
/* */
|
/* */
|
||||||
/* returns the context structure, unless the string is equal to */
|
/* returns the context structure, unless the string is equal to */
|
||||||
/* DEC_Condition_MU or is not recognized. In these cases NULL is */
|
/* DEC_Condition_MU or is not recognized. In these cases NULL is */
|
||||||
/* returned. */
|
/* returned. */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
decContext * decContextSetStatusFromStringQuiet(decContext *context,
|
decContext * decContextSetStatusFromStringQuiet(decContext *context,
|
||||||
const char *string) {
|
const char *string) {
|
||||||
|
@ -356,11 +345,11 @@ decContext * decContextSetStatusQuiet(decContext *context, uInt status) {
|
||||||
return context;} /* decContextSetStatusQuiet */
|
return context;} /* decContextSetStatusQuiet */
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decContextStatusToString -- convert status flags to a string */
|
/* decContextStatusToString -- convert status flags to a string */
|
||||||
/* */
|
/* */
|
||||||
/* context is a context with valid status field */
|
/* context is a context with valid status field */
|
||||||
/* */
|
/* */
|
||||||
/* returns a constant string describing the condition. If multiple */
|
/* returns a constant string describing the condition. If multiple */
|
||||||
/* (or no) flags are set, a generic constant message is returned. */
|
/* (or no) flags are set, a generic constant message is returned. */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
const char *decContextStatusToString(const decContext *context) {
|
const char *decContextStatusToString(const decContext *context) {
|
||||||
|
@ -385,10 +374,40 @@ const char *decContextStatusToString(const decContext *context) {
|
||||||
#if DECSUBSET
|
#if DECSUBSET
|
||||||
if (status==DEC_Lost_digits ) return DEC_Condition_LD;
|
if (status==DEC_Lost_digits ) return DEC_Condition_LD;
|
||||||
#endif
|
#endif
|
||||||
if (status==0 ) return DEC_Condition_ZE;
|
if (status==0 ) return DEC_Condition_ZE;
|
||||||
return DEC_Condition_MU; /* Multiple errors */
|
return DEC_Condition_MU; /* Multiple errors */
|
||||||
} /* decContextStatusToString */
|
} /* decContextStatusToString */
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* decContextTestEndian -- test whether DECLITEND is set correctly */
|
||||||
|
/* */
|
||||||
|
/* quiet is 1 to suppress message; 0 otherwise */
|
||||||
|
/* returns 0 if DECLITEND is correct */
|
||||||
|
/* 1 if DECLITEND is incorrect and should be 1 */
|
||||||
|
/* -1 if DECLITEND is incorrect and should be 0 */
|
||||||
|
/* */
|
||||||
|
/* A message is displayed if the return value is not 0 and quiet==0. */
|
||||||
|
/* */
|
||||||
|
/* No error is possible. */
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
Int decContextTestEndian(Flag quiet) {
|
||||||
|
Int res=0; /* optimist */
|
||||||
|
uInt dle=(uInt)DECLITEND; /* unsign */
|
||||||
|
if (dle>1) dle=1; /* ensure 0 or 1 */
|
||||||
|
|
||||||
|
if (LITEND!=DECLITEND) {
|
||||||
|
const char *adj;
|
||||||
|
if (!quiet) {
|
||||||
|
if (LITEND) adj="little";
|
||||||
|
else adj="big";
|
||||||
|
printf("Warning: DECLITEND is set to %d, but this computer appears to be %s-endian\n",
|
||||||
|
DECLITEND, adj);
|
||||||
|
}
|
||||||
|
res=(Int)LITEND-dle;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
} /* decContextTestEndian */
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decContextTestSavedStatus -- test bits in saved status */
|
/* decContextTestSavedStatus -- test bits in saved status */
|
||||||
/* */
|
/* */
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
/* */
|
/* */
|
||||||
/* Context variables must always have valid values: */
|
/* Context variables must always have valid values: */
|
||||||
/* */
|
/* */
|
||||||
/* status -- [any bits may be cleared, but not set, by user] */
|
/* status -- [any bits may be cleared, but not set, by user] */
|
||||||
/* round -- must be one of the enumerated rounding modes */
|
/* round -- must be one of the enumerated rounding modes */
|
||||||
/* */
|
/* */
|
||||||
/* The following variables are implied for fixed size formats (i.e., */
|
/* The following variables are implied for fixed size formats (i.e., */
|
||||||
|
@ -54,36 +54,42 @@
|
||||||
#define DECCONTEXT
|
#define DECCONTEXT
|
||||||
#define DECCNAME "decContext" /* Short name */
|
#define DECCNAME "decContext" /* Short name */
|
||||||
#define DECCFULLNAME "Decimal Context Descriptor" /* Verbose name */
|
#define DECCFULLNAME "Decimal Context Descriptor" /* Verbose name */
|
||||||
#define DECCAUTHOR "Mike Cowlishaw" /* Who to blame */
|
#define DECCAUTHOR "Mike Cowlishaw" /* Who to blame */
|
||||||
|
|
||||||
#include "gstdint.h" /* C99 standard integers */
|
#if !defined(int32_t)
|
||||||
|
#include <stdint.h> /* C99 standard integers */
|
||||||
|
#endif
|
||||||
#include <stdio.h> /* for printf, etc. */
|
#include <stdio.h> /* for printf, etc. */
|
||||||
#include <signal.h> /* for traps */
|
#include <signal.h> /* for traps */
|
||||||
|
|
||||||
/* Extended flags setting -- set this to 0 to use only IEEE flags */
|
/* Extended flags setting -- set this to 0 to use only IEEE flags */
|
||||||
|
#if !defined(DECEXTFLAG)
|
||||||
#define DECEXTFLAG 1 /* 1=enable extended flags */
|
#define DECEXTFLAG 1 /* 1=enable extended flags */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Conditional code flag -- set this to 0 for best performance */
|
/* Conditional code flag -- set this to 0 for best performance */
|
||||||
|
#if !defined(DECSUBSET)
|
||||||
#define DECSUBSET 0 /* 1=enable subset arithmetic */
|
#define DECSUBSET 0 /* 1=enable subset arithmetic */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Context for operations, with associated constants */
|
/* Context for operations, with associated constants */
|
||||||
enum rounding {
|
enum rounding {
|
||||||
DEC_ROUND_CEILING, /* round towards +infinity */
|
DEC_ROUND_CEILING, /* round towards +infinity */
|
||||||
DEC_ROUND_UP, /* round away from 0 */
|
DEC_ROUND_UP, /* round away from 0 */
|
||||||
DEC_ROUND_HALF_UP, /* 0.5 rounds up */
|
DEC_ROUND_HALF_UP, /* 0.5 rounds up */
|
||||||
DEC_ROUND_HALF_EVEN, /* 0.5 rounds to nearest even */
|
DEC_ROUND_HALF_EVEN, /* 0.5 rounds to nearest even */
|
||||||
DEC_ROUND_HALF_DOWN, /* 0.5 rounds down */
|
DEC_ROUND_HALF_DOWN, /* 0.5 rounds down */
|
||||||
DEC_ROUND_DOWN, /* round towards 0 (truncate) */
|
DEC_ROUND_DOWN, /* round towards 0 (truncate) */
|
||||||
DEC_ROUND_FLOOR, /* round towards -infinity */
|
DEC_ROUND_FLOOR, /* round towards -infinity */
|
||||||
DEC_ROUND_05UP, /* round for reround */
|
DEC_ROUND_05UP, /* round for reround */
|
||||||
DEC_ROUND_MAX /* enum must be less than this */
|
DEC_ROUND_MAX /* enum must be less than this */
|
||||||
};
|
};
|
||||||
#define DEC_ROUND_DEFAULT DEC_ROUND_HALF_EVEN;
|
#define DEC_ROUND_DEFAULT DEC_ROUND_HALF_EVEN;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t digits; /* working precision */
|
int32_t digits; /* working precision */
|
||||||
int32_t emax; /* maximum positive exponent */
|
int32_t emax; /* maximum positive exponent */
|
||||||
int32_t emin; /* minimum negative exponent */
|
int32_t emin; /* minimum negative exponent */
|
||||||
enum rounding round; /* rounding mode */
|
enum rounding round; /* rounding mode */
|
||||||
uint32_t traps; /* trap-enabler flags */
|
uint32_t traps; /* trap-enabler flags */
|
||||||
uint32_t status; /* status flags */
|
uint32_t status; /* status flags */
|
||||||
|
@ -102,9 +108,9 @@
|
||||||
#define DEC_MIN_EMIN -999999999
|
#define DEC_MIN_EMIN -999999999
|
||||||
#define DEC_MAX_MATH 999999 /* max emax, etc., for math funcs. */
|
#define DEC_MAX_MATH 999999 /* max emax, etc., for math funcs. */
|
||||||
|
|
||||||
/* Classifications for decimal numbers, aligned with 754r (note */
|
/* Classifications for decimal numbers, aligned with 754 (note that */
|
||||||
/* that 'normal' and 'subnormal' are meaningful only with a */
|
/* 'normal' and 'subnormal' are meaningful only with a decContext */
|
||||||
/* decContext or a fixed size format). */
|
/* or a fixed size format). */
|
||||||
enum decClass {
|
enum decClass {
|
||||||
DEC_CLASS_SNAN,
|
DEC_CLASS_SNAN,
|
||||||
DEC_CLASS_QNAN,
|
DEC_CLASS_QNAN,
|
||||||
|
@ -139,15 +145,15 @@
|
||||||
#define DEC_Division_impossible 0x00000004
|
#define DEC_Division_impossible 0x00000004
|
||||||
#define DEC_Division_undefined 0x00000008
|
#define DEC_Division_undefined 0x00000008
|
||||||
#define DEC_Insufficient_storage 0x00000010 /* [when malloc fails] */
|
#define DEC_Insufficient_storage 0x00000010 /* [when malloc fails] */
|
||||||
#define DEC_Inexact 0x00000020
|
#define DEC_Inexact 0x00000020
|
||||||
#define DEC_Invalid_context 0x00000040
|
#define DEC_Invalid_context 0x00000040
|
||||||
#define DEC_Invalid_operation 0x00000080
|
#define DEC_Invalid_operation 0x00000080
|
||||||
#if DECSUBSET
|
#if DECSUBSET
|
||||||
#define DEC_Lost_digits 0x00000100
|
#define DEC_Lost_digits 0x00000100
|
||||||
#endif
|
#endif
|
||||||
#define DEC_Overflow 0x00000200
|
#define DEC_Overflow 0x00000200
|
||||||
#define DEC_Clamped 0x00000400
|
#define DEC_Clamped 0x00000400
|
||||||
#define DEC_Rounded 0x00000800
|
#define DEC_Rounded 0x00000800
|
||||||
#define DEC_Subnormal 0x00001000
|
#define DEC_Subnormal 0x00001000
|
||||||
#define DEC_Underflow 0x00002000
|
#define DEC_Underflow 0x00002000
|
||||||
#else
|
#else
|
||||||
|
@ -157,43 +163,43 @@
|
||||||
#define DEC_Division_impossible 0x00000010
|
#define DEC_Division_impossible 0x00000010
|
||||||
#define DEC_Division_undefined 0x00000010
|
#define DEC_Division_undefined 0x00000010
|
||||||
#define DEC_Insufficient_storage 0x00000010 /* [when malloc fails] */
|
#define DEC_Insufficient_storage 0x00000010 /* [when malloc fails] */
|
||||||
#define DEC_Inexact 0x00000001
|
#define DEC_Inexact 0x00000001
|
||||||
#define DEC_Invalid_context 0x00000010
|
#define DEC_Invalid_context 0x00000010
|
||||||
#define DEC_Invalid_operation 0x00000010
|
#define DEC_Invalid_operation 0x00000010
|
||||||
#if DECSUBSET
|
#if DECSUBSET
|
||||||
#define DEC_Lost_digits 0x00000000
|
#define DEC_Lost_digits 0x00000000
|
||||||
#endif
|
#endif
|
||||||
#define DEC_Overflow 0x00000008
|
#define DEC_Overflow 0x00000008
|
||||||
#define DEC_Clamped 0x00000000
|
#define DEC_Clamped 0x00000000
|
||||||
#define DEC_Rounded 0x00000000
|
#define DEC_Rounded 0x00000000
|
||||||
#define DEC_Subnormal 0x00000000
|
#define DEC_Subnormal 0x00000000
|
||||||
#define DEC_Underflow 0x00000004
|
#define DEC_Underflow 0x00000004
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* IEEE 854 groupings for the flags */
|
/* IEEE 754 groupings for the flags */
|
||||||
/* [DEC_Clamped, DEC_Lost_digits, DEC_Rounded, and DEC_Subnormal */
|
/* [DEC_Clamped, DEC_Lost_digits, DEC_Rounded, and DEC_Subnormal */
|
||||||
/* are not in IEEE 854] */
|
/* are not in IEEE 754] */
|
||||||
#define DEC_IEEE_854_Division_by_zero (DEC_Division_by_zero)
|
#define DEC_IEEE_754_Division_by_zero (DEC_Division_by_zero)
|
||||||
#if DECSUBSET
|
#if DECSUBSET
|
||||||
#define DEC_IEEE_854_Inexact (DEC_Inexact | DEC_Lost_digits)
|
#define DEC_IEEE_754_Inexact (DEC_Inexact | DEC_Lost_digits)
|
||||||
#else
|
#else
|
||||||
#define DEC_IEEE_854_Inexact (DEC_Inexact)
|
#define DEC_IEEE_754_Inexact (DEC_Inexact)
|
||||||
#endif
|
#endif
|
||||||
#define DEC_IEEE_854_Invalid_operation (DEC_Conversion_syntax | \
|
#define DEC_IEEE_754_Invalid_operation (DEC_Conversion_syntax | \
|
||||||
DEC_Division_impossible | \
|
DEC_Division_impossible | \
|
||||||
DEC_Division_undefined | \
|
DEC_Division_undefined | \
|
||||||
DEC_Insufficient_storage | \
|
DEC_Insufficient_storage | \
|
||||||
DEC_Invalid_context | \
|
DEC_Invalid_context | \
|
||||||
DEC_Invalid_operation)
|
DEC_Invalid_operation)
|
||||||
#define DEC_IEEE_854_Overflow (DEC_Overflow)
|
#define DEC_IEEE_754_Overflow (DEC_Overflow)
|
||||||
#define DEC_IEEE_854_Underflow (DEC_Underflow)
|
#define DEC_IEEE_754_Underflow (DEC_Underflow)
|
||||||
|
|
||||||
/* flags which are normally errors (result is qNaN, infinite, or 0) */
|
/* flags which are normally errors (result is qNaN, infinite, or 0) */
|
||||||
#define DEC_Errors (DEC_IEEE_854_Division_by_zero | \
|
#define DEC_Errors (DEC_IEEE_754_Division_by_zero | \
|
||||||
DEC_IEEE_854_Invalid_operation | \
|
DEC_IEEE_754_Invalid_operation | \
|
||||||
DEC_IEEE_854_Overflow | DEC_IEEE_854_Underflow)
|
DEC_IEEE_754_Overflow | DEC_IEEE_754_Underflow)
|
||||||
/* flags which cause a result to become qNaN */
|
/* flags which cause a result to become qNaN */
|
||||||
#define DEC_NaNs DEC_IEEE_854_Invalid_operation
|
#define DEC_NaNs DEC_IEEE_754_Invalid_operation
|
||||||
|
|
||||||
/* flags which are normally for information only (finite results) */
|
/* flags which are normally for information only (finite results) */
|
||||||
#if DECSUBSET
|
#if DECSUBSET
|
||||||
|
@ -203,6 +209,13 @@
|
||||||
#define DEC_Information (DEC_Clamped | DEC_Rounded | DEC_Inexact)
|
#define DEC_Information (DEC_Clamped | DEC_Rounded | DEC_Inexact)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* IEEE 854 names (for compatibility with older decNumber versions) */
|
||||||
|
#define DEC_IEEE_854_Division_by_zero DEC_IEEE_754_Division_by_zero
|
||||||
|
#define DEC_IEEE_854_Inexact DEC_IEEE_754_Inexact
|
||||||
|
#define DEC_IEEE_854_Invalid_operation DEC_IEEE_754_Invalid_operation
|
||||||
|
#define DEC_IEEE_854_Overflow DEC_IEEE_754_Overflow
|
||||||
|
#define DEC_IEEE_854_Underflow DEC_IEEE_754_Underflow
|
||||||
|
|
||||||
/* Name strings for the exceptional conditions */
|
/* Name strings for the exceptional conditions */
|
||||||
#define DEC_Condition_CS "Conversion syntax"
|
#define DEC_Condition_CS "Conversion syntax"
|
||||||
#define DEC_Condition_DZ "Division by zero"
|
#define DEC_Condition_DZ "Division by zero"
|
||||||
|
@ -226,7 +239,7 @@
|
||||||
/* including terminator */
|
/* including terminator */
|
||||||
|
|
||||||
/* Initialization descriptors, used by decContextDefault */
|
/* Initialization descriptors, used by decContextDefault */
|
||||||
#define DEC_INIT_BASE 0
|
#define DEC_INIT_BASE 0
|
||||||
#define DEC_INIT_DECIMAL32 32
|
#define DEC_INIT_DECIMAL32 32
|
||||||
#define DEC_INIT_DECIMAL64 64
|
#define DEC_INIT_DECIMAL64 64
|
||||||
#define DEC_INIT_DECIMAL128 128
|
#define DEC_INIT_DECIMAL128 128
|
||||||
|
@ -251,6 +264,7 @@
|
||||||
extern decContext * decContextSetStatusFromStringQuiet(decContext *, const char *);
|
extern decContext * decContextSetStatusFromStringQuiet(decContext *, const char *);
|
||||||
extern decContext * decContextSetStatusQuiet(decContext *, uint32_t);
|
extern decContext * decContextSetStatusQuiet(decContext *, uint32_t);
|
||||||
extern const char * decContextStatusToString(const decContext *);
|
extern const char * decContextStatusToString(const decContext *);
|
||||||
|
extern int32_t decContextTestEndian(uint8_t);
|
||||||
extern uint32_t decContextTestSavedStatus(uint32_t, uint32_t);
|
extern uint32_t decContextTestSavedStatus(uint32_t, uint32_t);
|
||||||
extern uint32_t decContextTestStatus(decContext *, uint32_t);
|
extern uint32_t decContextTestStatus(decContext *, uint32_t);
|
||||||
extern decContext * decContextZeroStatus(decContext *);
|
extern decContext * decContextZeroStatus(decContext *);
|
||||||
|
|
|
@ -30,10 +30,9 @@
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
/* Binary Coded Decimal and Densely Packed Decimal conversion lookup tables */
|
/* Binary Coded Decimal and Densely Packed Decimal conversion lookup tables */
|
||||||
/* [Automatically generated -- do not edit. 2007.05.05] */
|
/* [Automatically generated -- do not edit. 2008.06.21] */
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
/* ------------------------------------------------------------------------ */
|
/* For details, see DPDecimal.html on the General Decimal Arithmetic page. */
|
||||||
/* For details, see: http://www2.hursley.ibm.com/decimal/DPDecimal.html */
|
|
||||||
|
|
||||||
#include "decDPDSymbols.h"
|
#include "decDPDSymbols.h"
|
||||||
|
|
||||||
|
@ -43,9 +42,9 @@
|
||||||
/* uint16_t BIN2DPD[1000]; -- Bin -> DPD (999 => 2457) */
|
/* uint16_t BIN2DPD[1000]; -- Bin -> DPD (999 => 2457) */
|
||||||
/* uint8_t BIN2CHAR[4001]; -- Bin -> CHAR (999 => '\3' '9' '9' '9') */
|
/* uint8_t BIN2CHAR[4001]; -- Bin -> CHAR (999 => '\3' '9' '9' '9') */
|
||||||
/* uint8_t BIN2BCD8[4000]; -- Bin -> bytes (999 => 9 9 9 3) */
|
/* uint8_t BIN2BCD8[4000]; -- Bin -> bytes (999 => 9 9 9 3) */
|
||||||
/* uint16_t DPD2BCD[1024]; -- DPD -> BCD (0x3FF => 0x999) */
|
/* uint16_t DPD2BCD[1024]; -- DPD -> BCD (0x3FF => 0x999) */
|
||||||
/* uint16_t DPD2BIN[1024]; -- DPD -> BIN (0x3FF => 999) */
|
/* uint16_t DPD2BIN[1024]; -- DPD -> BIN (0x3FF => 999) */
|
||||||
/* uint32_t DPD2BINK[1024]; -- DPD -> BIN * 1000 (0x3FF => 999000) */
|
/* uint32_t DPD2BINK[1024]; -- DPD -> BIN * 1000 (0x3FF => 999000) */
|
||||||
/* uint32_t DPD2BINM[1024]; -- DPD -> BIN * 1E+6 (0x3FF => 999000000) */
|
/* uint32_t DPD2BINM[1024]; -- DPD -> BIN * 1E+6 (0x3FF => 999000000) */
|
||||||
/* uint8_t DPD2BCD8[4096]; -- DPD -> bytes (x3FF => 9 9 9 3) */
|
/* uint8_t DPD2BCD8[4096]; -- DPD -> bytes (x3FF => 9 9 9 3) */
|
||||||
/* */
|
/* */
|
||||||
|
@ -53,10 +52,10 @@
|
||||||
/* in the table entry. BIN2CHAR entries are a single byte length (0 for */
|
/* in the table entry. BIN2CHAR entries are a single byte length (0 for */
|
||||||
/* value 0) followed by three digit characters; a trailing terminator is */
|
/* value 0) followed by three digit characters; a trailing terminator is */
|
||||||
/* included to allow 4-char moves always. BIN2BCD8 and DPD2BCD8 entries */
|
/* included to allow 4-char moves always. BIN2BCD8 and DPD2BCD8 entries */
|
||||||
/* are similar with the three BCD8 digits followed by a one-byte length */
|
/* are similar with the three BCD8 digits followed by a one-byte length */
|
||||||
/* (again, length=0 for value 0). */
|
/* (again, length=0 for value 0). */
|
||||||
/* */
|
/* */
|
||||||
/* To use a table, its name, prefixed with DEC_, must be defined with a */
|
/* To use a table, its name, prefixed with DEC_, must be defined with a */
|
||||||
/* value of 1 before this header file is included. For example: */
|
/* value of 1 before this header file is included. For example: */
|
||||||
/* #define DEC_BCD2DPD 1 */
|
/* #define DEC_BCD2DPD 1 */
|
||||||
/* This mechanism allows software to only include tables that are needed. */
|
/* This mechanism allows software to only include tables that are needed. */
|
||||||
|
@ -513,7 +512,7 @@ const uint16_t DPD2BIN[1024]={ 0, 1, 2, 3, 4, 5, 6, 7,
|
||||||
#if defined(DEC_DPD2BINK) && DEC_DPD2BINK==1 && !defined(DECDPD2BINK)
|
#if defined(DEC_DPD2BINK) && DEC_DPD2BINK==1 && !defined(DECDPD2BINK)
|
||||||
#define DECDPD2BINK
|
#define DECDPD2BINK
|
||||||
|
|
||||||
const uint32_t DPD2BINK[1024]={ 0, 1000, 2000, 3000, 4000, 5000,
|
const uint32_t DPD2BINK[1024]={ 0, 1000, 2000, 3000, 4000, 5000,
|
||||||
6000, 7000, 8000, 9000, 80000, 81000, 800000, 801000, 880000, 881000,
|
6000, 7000, 8000, 9000, 80000, 81000, 800000, 801000, 880000, 881000,
|
||||||
10000, 11000, 12000, 13000, 14000, 15000, 16000, 17000, 18000, 19000,
|
10000, 11000, 12000, 13000, 14000, 15000, 16000, 17000, 18000, 19000,
|
||||||
90000, 91000, 810000, 811000, 890000, 891000, 20000, 21000, 22000, 23000,
|
90000, 91000, 810000, 811000, 890000, 891000, 20000, 21000, 22000, 23000,
|
||||||
|
@ -621,24 +620,24 @@ const uint32_t DPD2BINK[1024]={ 0, 1000, 2000, 3000, 4000, 5000,
|
||||||
#if defined(DEC_DPD2BINM) && DEC_DPD2BINM==1 && !defined(DECDPD2BINM)
|
#if defined(DEC_DPD2BINM) && DEC_DPD2BINM==1 && !defined(DECDPD2BINM)
|
||||||
#define DECDPD2BINM
|
#define DECDPD2BINM
|
||||||
|
|
||||||
const uint32_t DPD2BINM[1024]={0, 1000000, 2000000, 3000000, 4000000,
|
const uint32_t DPD2BINM[1024]={0, 1000000, 2000000, 3000000, 4000000,
|
||||||
5000000, 6000000, 7000000, 8000000, 9000000, 80000000, 81000000,
|
5000000, 6000000, 7000000, 8000000, 9000000, 80000000, 81000000,
|
||||||
800000000, 801000000, 880000000, 881000000, 10000000, 11000000, 12000000,
|
800000000, 801000000, 880000000, 881000000, 10000000, 11000000, 12000000,
|
||||||
13000000, 14000000, 15000000, 16000000, 17000000, 18000000, 19000000,
|
13000000, 14000000, 15000000, 16000000, 17000000, 18000000, 19000000,
|
||||||
90000000, 91000000, 810000000, 811000000, 890000000, 891000000, 20000000,
|
90000000, 91000000, 810000000, 811000000, 890000000, 891000000, 20000000,
|
||||||
21000000, 22000000, 23000000, 24000000, 25000000, 26000000, 27000000,
|
21000000, 22000000, 23000000, 24000000, 25000000, 26000000, 27000000,
|
||||||
28000000, 29000000, 82000000, 83000000, 820000000, 821000000, 808000000,
|
28000000, 29000000, 82000000, 83000000, 820000000, 821000000, 808000000,
|
||||||
809000000, 30000000, 31000000, 32000000, 33000000, 34000000, 35000000,
|
809000000, 30000000, 31000000, 32000000, 33000000, 34000000, 35000000,
|
||||||
36000000, 37000000, 38000000, 39000000, 92000000, 93000000, 830000000,
|
36000000, 37000000, 38000000, 39000000, 92000000, 93000000, 830000000,
|
||||||
831000000, 818000000, 819000000, 40000000, 41000000, 42000000, 43000000,
|
831000000, 818000000, 819000000, 40000000, 41000000, 42000000, 43000000,
|
||||||
44000000, 45000000, 46000000, 47000000, 48000000, 49000000, 84000000,
|
44000000, 45000000, 46000000, 47000000, 48000000, 49000000, 84000000,
|
||||||
85000000, 840000000, 841000000, 88000000, 89000000, 50000000, 51000000,
|
85000000, 840000000, 841000000, 88000000, 89000000, 50000000, 51000000,
|
||||||
52000000, 53000000, 54000000, 55000000, 56000000, 57000000, 58000000,
|
52000000, 53000000, 54000000, 55000000, 56000000, 57000000, 58000000,
|
||||||
59000000, 94000000, 95000000, 850000000, 851000000, 98000000, 99000000,
|
59000000, 94000000, 95000000, 850000000, 851000000, 98000000, 99000000,
|
||||||
60000000, 61000000, 62000000, 63000000, 64000000, 65000000, 66000000,
|
60000000, 61000000, 62000000, 63000000, 64000000, 65000000, 66000000,
|
||||||
67000000, 68000000, 69000000, 86000000, 87000000, 860000000, 861000000,
|
67000000, 68000000, 69000000, 86000000, 87000000, 860000000, 861000000,
|
||||||
888000000, 889000000, 70000000, 71000000, 72000000, 73000000, 74000000,
|
888000000, 889000000, 70000000, 71000000, 72000000, 73000000, 74000000,
|
||||||
75000000, 76000000, 77000000, 78000000, 79000000, 96000000, 97000000,
|
75000000, 76000000, 77000000, 78000000, 79000000, 96000000, 97000000,
|
||||||
870000000, 871000000, 898000000, 899000000, 100000000, 101000000, 102000000,
|
870000000, 871000000, 898000000, 899000000, 100000000, 101000000, 102000000,
|
||||||
103000000, 104000000, 105000000, 106000000, 107000000, 108000000, 109000000,
|
103000000, 104000000, 105000000, 106000000, 107000000, 108000000, 109000000,
|
||||||
180000000, 181000000, 900000000, 901000000, 980000000, 981000000, 110000000,
|
180000000, 181000000, 900000000, 901000000, 980000000, 981000000, 110000000,
|
||||||
|
|
|
@ -34,19 +34,19 @@
|
||||||
/* This module comprises decDouble operations (including conversions) */
|
/* This module comprises decDouble operations (including conversions) */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
|
||||||
#include "decContext.h" /* public includes */
|
#include "decContext.h" /* public includes */
|
||||||
#include "decDouble.h" /* .. */
|
#include "decDouble.h" /* .. */
|
||||||
|
|
||||||
/* Constant mappings for shared code */
|
/* Constant mappings for shared code */
|
||||||
#define DECPMAX DECDOUBLE_Pmax
|
#define DECPMAX DECDOUBLE_Pmax
|
||||||
#define DECEMIN DECDOUBLE_Emin
|
#define DECEMIN DECDOUBLE_Emin
|
||||||
#define DECEMAX DECDOUBLE_Emax
|
#define DECEMAX DECDOUBLE_Emax
|
||||||
#define DECEMAXD DECDOUBLE_EmaxD
|
#define DECEMAXD DECDOUBLE_EmaxD
|
||||||
#define DECBYTES DECDOUBLE_Bytes
|
#define DECBYTES DECDOUBLE_Bytes
|
||||||
#define DECSTRING DECDOUBLE_String
|
#define DECSTRING DECDOUBLE_String
|
||||||
#define DECECONL DECDOUBLE_EconL
|
#define DECECONL DECDOUBLE_EconL
|
||||||
#define DECBIAS DECDOUBLE_Bias
|
#define DECBIAS DECDOUBLE_Bias
|
||||||
#define DECLETS DECDOUBLE_Declets
|
#define DECLETS DECDOUBLE_Declets
|
||||||
#define DECQTINY (-DECDOUBLE_Bias)
|
#define DECQTINY (-DECDOUBLE_Bias)
|
||||||
/* parameters of next-wider format */
|
/* parameters of next-wider format */
|
||||||
#define DECWBYTES DECQUAD_Bytes
|
#define DECWBYTES DECQUAD_Bytes
|
||||||
|
@ -55,100 +55,98 @@
|
||||||
#define DECWBIAS DECQUAD_Bias
|
#define DECWBIAS DECQUAD_Bias
|
||||||
|
|
||||||
/* Type and function mappings for shared code */
|
/* Type and function mappings for shared code */
|
||||||
#define decFloat decDouble /* Type name */
|
#define decFloat decDouble /* Type name */
|
||||||
#define decFloatWider decQuad /* Type name */
|
#define decFloatWider decQuad /* Type name */
|
||||||
|
|
||||||
/* Utilities and conversions (binary results, extractors, etc.) */
|
/* Utilities and conversions (binary results, extractors, etc.) */
|
||||||
#define decFloatFromBCD decDoubleFromBCD
|
#define decFloatFromBCD decDoubleFromBCD
|
||||||
#define decFloatFromInt32 decDoubleFromInt32
|
#define decFloatFromInt32 decDoubleFromInt32
|
||||||
#define decFloatFromPacked decDoubleFromPacked
|
#define decFloatFromPacked decDoubleFromPacked
|
||||||
#define decFloatFromString decDoubleFromString
|
#define decFloatFromPackedChecked decDoubleFromPackedChecked
|
||||||
#define decFloatFromUInt32 decDoubleFromUInt32
|
#define decFloatFromString decDoubleFromString
|
||||||
#define decFloatFromWider decDoubleFromWider
|
#define decFloatFromUInt32 decDoubleFromUInt32
|
||||||
#define decFloatGetCoefficient decDoubleGetCoefficient
|
#define decFloatFromWider decDoubleFromWider
|
||||||
#define decFloatGetExponent decDoubleGetExponent
|
#define decFloatGetCoefficient decDoubleGetCoefficient
|
||||||
#define decFloatSetCoefficient decDoubleSetCoefficient
|
#define decFloatGetExponent decDoubleGetExponent
|
||||||
#define decFloatSetExponent decDoubleSetExponent
|
#define decFloatSetCoefficient decDoubleSetCoefficient
|
||||||
#define decFloatShow decDoubleShow
|
#define decFloatSetExponent decDoubleSetExponent
|
||||||
#define decFloatToBCD decDoubleToBCD
|
#define decFloatShow decDoubleShow
|
||||||
#define decFloatToEngString decDoubleToEngString
|
#define decFloatToBCD decDoubleToBCD
|
||||||
#define decFloatToInt32 decDoubleToInt32
|
#define decFloatToEngString decDoubleToEngString
|
||||||
#define decFloatToInt32Exact decDoubleToInt32Exact
|
#define decFloatToInt32 decDoubleToInt32
|
||||||
#define decFloatToPacked decDoubleToPacked
|
#define decFloatToInt32Exact decDoubleToInt32Exact
|
||||||
#define decFloatToString decDoubleToString
|
#define decFloatToPacked decDoubleToPacked
|
||||||
#define decFloatToUInt32 decDoubleToUInt32
|
#define decFloatToString decDoubleToString
|
||||||
#define decFloatToUInt32Exact decDoubleToUInt32Exact
|
#define decFloatToUInt32 decDoubleToUInt32
|
||||||
#define decFloatToWider decDoubleToWider
|
#define decFloatToUInt32Exact decDoubleToUInt32Exact
|
||||||
#define decFloatZero decDoubleZero
|
#define decFloatToWider decDoubleToWider
|
||||||
|
#define decFloatZero decDoubleZero
|
||||||
|
|
||||||
/* Computational (result is a decFloat) */
|
/* Computational (result is a decFloat) */
|
||||||
#define decFloatAbs decDoubleAbs
|
#define decFloatAbs decDoubleAbs
|
||||||
#define decFloatAdd decDoubleAdd
|
#define decFloatAdd decDoubleAdd
|
||||||
#define decFloatAnd decDoubleAnd
|
#define decFloatAnd decDoubleAnd
|
||||||
#define decFloatDivide decDoubleDivide
|
#define decFloatDivide decDoubleDivide
|
||||||
#define decFloatDivideInteger decDoubleDivideInteger
|
#define decFloatDivideInteger decDoubleDivideInteger
|
||||||
#define decFloatFMA decDoubleFMA
|
#define decFloatFMA decDoubleFMA
|
||||||
#define decFloatInvert decDoubleInvert
|
#define decFloatInvert decDoubleInvert
|
||||||
#define decFloatLogB decDoubleLogB
|
#define decFloatLogB decDoubleLogB
|
||||||
#define decFloatMax decDoubleMax
|
#define decFloatMax decDoubleMax
|
||||||
#define decFloatMaxMag decDoubleMaxMag
|
#define decFloatMaxMag decDoubleMaxMag
|
||||||
#define decFloatMin decDoubleMin
|
#define decFloatMin decDoubleMin
|
||||||
#define decFloatMinMag decDoubleMinMag
|
#define decFloatMinMag decDoubleMinMag
|
||||||
#define decFloatMinus decDoubleMinus
|
#define decFloatMinus decDoubleMinus
|
||||||
#define decFloatMultiply decDoubleMultiply
|
#define decFloatMultiply decDoubleMultiply
|
||||||
#define decFloatNextMinus decDoubleNextMinus
|
#define decFloatNextMinus decDoubleNextMinus
|
||||||
#define decFloatNextPlus decDoubleNextPlus
|
#define decFloatNextPlus decDoubleNextPlus
|
||||||
#define decFloatNextToward decDoubleNextToward
|
#define decFloatNextToward decDoubleNextToward
|
||||||
#define decFloatOr decDoubleOr
|
#define decFloatOr decDoubleOr
|
||||||
#define decFloatPlus decDoublePlus
|
#define decFloatPlus decDoublePlus
|
||||||
#define decFloatQuantize decDoubleQuantize
|
#define decFloatQuantize decDoubleQuantize
|
||||||
#define decFloatReduce decDoubleReduce
|
#define decFloatReduce decDoubleReduce
|
||||||
#define decFloatRemainder decDoubleRemainder
|
#define decFloatRemainder decDoubleRemainder
|
||||||
#define decFloatRemainderNear decDoubleRemainderNear
|
#define decFloatRemainderNear decDoubleRemainderNear
|
||||||
#define decFloatRotate decDoubleRotate
|
#define decFloatRotate decDoubleRotate
|
||||||
#define decFloatScaleB decDoubleScaleB
|
#define decFloatScaleB decDoubleScaleB
|
||||||
#define decFloatShift decDoubleShift
|
#define decFloatShift decDoubleShift
|
||||||
#define decFloatSubtract decDoubleSubtract
|
#define decFloatSubtract decDoubleSubtract
|
||||||
#define decFloatToIntegralValue decDoubleToIntegralValue
|
#define decFloatToIntegralValue decDoubleToIntegralValue
|
||||||
#define decFloatToIntegralExact decDoubleToIntegralExact
|
#define decFloatToIntegralExact decDoubleToIntegralExact
|
||||||
#define decFloatXor decDoubleXor
|
#define decFloatXor decDoubleXor
|
||||||
|
|
||||||
/* Comparisons */
|
/* Comparisons */
|
||||||
#define decFloatCompare decDoubleCompare
|
#define decFloatCompare decDoubleCompare
|
||||||
#define decFloatCompareSignal decDoubleCompareSignal
|
#define decFloatCompareSignal decDoubleCompareSignal
|
||||||
#define decFloatCompareTotal decDoubleCompareTotal
|
#define decFloatCompareTotal decDoubleCompareTotal
|
||||||
#define decFloatCompareTotalMag decDoubleCompareTotalMag
|
#define decFloatCompareTotalMag decDoubleCompareTotalMag
|
||||||
|
|
||||||
/* Copies */
|
/* Copies */
|
||||||
#define decFloatCanonical decDoubleCanonical
|
#define decFloatCanonical decDoubleCanonical
|
||||||
#define decFloatCopy decDoubleCopy
|
#define decFloatCopy decDoubleCopy
|
||||||
#define decFloatCopyAbs decDoubleCopyAbs
|
#define decFloatCopyAbs decDoubleCopyAbs
|
||||||
#define decFloatCopyNegate decDoubleCopyNegate
|
#define decFloatCopyNegate decDoubleCopyNegate
|
||||||
#define decFloatCopySign decDoubleCopySign
|
#define decFloatCopySign decDoubleCopySign
|
||||||
|
|
||||||
/* Non-computational */
|
/* Non-computational */
|
||||||
#define decFloatClass decDoubleClass
|
#define decFloatClass decDoubleClass
|
||||||
#define decFloatClassString decDoubleClassString
|
#define decFloatClassString decDoubleClassString
|
||||||
#define decFloatDigits decDoubleDigits
|
#define decFloatDigits decDoubleDigits
|
||||||
#define decFloatIsCanonical decDoubleIsCanonical
|
#define decFloatIsCanonical decDoubleIsCanonical
|
||||||
#define decFloatIsFinite decDoubleIsFinite
|
#define decFloatIsFinite decDoubleIsFinite
|
||||||
#define decFloatIsInfinite decDoubleIsInfinite
|
#define decFloatIsInfinite decDoubleIsInfinite
|
||||||
#define decFloatIsInteger decDoubleIsInteger
|
#define decFloatIsInteger decDoubleIsInteger
|
||||||
#define decFloatIsNaN decDoubleIsNaN
|
#define decFloatIsNaN decDoubleIsNaN
|
||||||
#define decFloatIsNormal decDoubleIsNormal
|
#define decFloatIsNormal decDoubleIsNormal
|
||||||
#define decFloatIsSignaling decDoubleIsSignaling
|
#define decFloatIsSignaling decDoubleIsSignaling
|
||||||
#define decFloatIsSignalling decDoubleIsSignalling
|
#define decFloatIsSignalling decDoubleIsSignalling
|
||||||
#define decFloatIsSigned decDoubleIsSigned
|
#define decFloatIsSigned decDoubleIsSigned
|
||||||
#define decFloatIsSubnormal decDoubleIsSubnormal
|
#define decFloatIsSubnormal decDoubleIsSubnormal
|
||||||
#define decFloatIsZero decDoubleIsZero
|
#define decFloatIsZero decDoubleIsZero
|
||||||
#define decFloatRadix decDoubleRadix
|
#define decFloatRadix decDoubleRadix
|
||||||
#define decFloatSameQuantum decDoubleSameQuantum
|
#define decFloatSameQuantum decDoubleSameQuantum
|
||||||
#define decFloatVersion decDoubleVersion
|
#define decFloatVersion decDoubleVersion
|
||||||
|
|
||||||
|
|
||||||
#include "decNumberLocal.h" /* local includes (need DECPMAX) */
|
#include "decNumberLocal.h" /* local includes (need DECPMAX) */
|
||||||
#include "decCommon.c" /* non-arithmetic decFloat routines */
|
#include "decCommon.c" /* non-arithmetic decFloat routines */
|
||||||
#include "decBasic.c" /* basic formats routines */
|
#include "decBasic.c" /* basic formats routines */
|
||||||
|
|
||||||
/* Below here will move to shared file as completed */
|
|
||||||
|
|
||||||
|
|
|
@ -31,24 +31,22 @@
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decDouble.h -- Decimal 64-bit format module header */
|
/* decDouble.h -- Decimal 64-bit format module header */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* Please see decFloats.h for an overview and documentation details. */
|
|
||||||
/* ------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
#if !defined(DECDOUBLE)
|
#if !defined(DECDOUBLE)
|
||||||
#define DECDOUBLE
|
#define DECDOUBLE
|
||||||
|
|
||||||
#define DECDOUBLENAME "decimalDouble" /* Short name */
|
#define DECDOUBLENAME "decimalDouble" /* Short name */
|
||||||
#define DECDOUBLETITLE "Decimal 64-bit datum" /* Verbose name */
|
#define DECDOUBLETITLE "Decimal 64-bit datum" /* Verbose name */
|
||||||
#define DECDOUBLEAUTHOR "Mike Cowlishaw" /* Who to blame */
|
#define DECDOUBLEAUTHOR "Mike Cowlishaw" /* Who to blame */
|
||||||
|
|
||||||
/* parameters for decDoubles */
|
/* parameters for decDoubles */
|
||||||
#define DECDOUBLE_Bytes 8 /* length */
|
#define DECDOUBLE_Bytes 8 /* length */
|
||||||
#define DECDOUBLE_Pmax 16 /* maximum precision (digits) */
|
#define DECDOUBLE_Pmax 16 /* maximum precision (digits) */
|
||||||
#define DECDOUBLE_Emin -383 /* minimum adjusted exponent */
|
#define DECDOUBLE_Emin -383 /* minimum adjusted exponent */
|
||||||
#define DECDOUBLE_Emax 384 /* maximum adjusted exponent */
|
#define DECDOUBLE_Emax 384 /* maximum adjusted exponent */
|
||||||
#define DECDOUBLE_EmaxD 3 /* maximum exponent digits */
|
#define DECDOUBLE_EmaxD 3 /* maximum exponent digits */
|
||||||
#define DECDOUBLE_Bias 398 /* bias for the exponent */
|
#define DECDOUBLE_Bias 398 /* bias for the exponent */
|
||||||
#define DECDOUBLE_String 25 /* maximum string length, +1 */
|
#define DECDOUBLE_String 25 /* maximum string length, +1 */
|
||||||
#define DECDOUBLE_EconL 8 /* exponent continuation length */
|
#define DECDOUBLE_EconL 8 /* exponent continuation length */
|
||||||
#define DECDOUBLE_Declets 5 /* count of declets */
|
#define DECDOUBLE_Declets 5 /* count of declets */
|
||||||
/* highest biased exponent (Elimit-1) */
|
/* highest biased exponent (Elimit-1) */
|
||||||
|
@ -58,11 +56,14 @@
|
||||||
#include "decContext.h"
|
#include "decContext.h"
|
||||||
#include "decQuad.h"
|
#include "decQuad.h"
|
||||||
|
|
||||||
/* The decDouble decimal 64-bit type, accessible by various types */
|
/* The decDouble decimal 64-bit type, accessible by all sizes */
|
||||||
typedef union {
|
typedef union {
|
||||||
uint8_t bytes[DECDOUBLE_Bytes]; /* fields: 1, 5, 8, 50 bits */
|
uint8_t bytes[DECDOUBLE_Bytes]; /* fields: 1, 5, 8, 50 bits */
|
||||||
uint16_t shorts[DECDOUBLE_Bytes/2];
|
uint16_t shorts[DECDOUBLE_Bytes/2];
|
||||||
uint32_t words[DECDOUBLE_Bytes/4];
|
uint32_t words[DECDOUBLE_Bytes/4];
|
||||||
|
#if DECUSE64
|
||||||
|
uint64_t longs[DECDOUBLE_Bytes/8];
|
||||||
|
#endif
|
||||||
} decDouble;
|
} decDouble;
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
|
@ -75,6 +76,7 @@
|
||||||
extern decDouble * decDoubleFromBCD(decDouble *, int32_t, const uint8_t *, int32_t);
|
extern decDouble * decDoubleFromBCD(decDouble *, int32_t, const uint8_t *, int32_t);
|
||||||
extern decDouble * decDoubleFromInt32(decDouble *, int32_t);
|
extern decDouble * decDoubleFromInt32(decDouble *, int32_t);
|
||||||
extern decDouble * decDoubleFromPacked(decDouble *, int32_t, const uint8_t *);
|
extern decDouble * decDoubleFromPacked(decDouble *, int32_t, const uint8_t *);
|
||||||
|
extern decDouble * decDoubleFromPackedChecked(decDouble *, int32_t, const uint8_t *);
|
||||||
extern decDouble * decDoubleFromString(decDouble *, const char *, decContext *);
|
extern decDouble * decDoubleFromString(decDouble *, const char *, decContext *);
|
||||||
extern decDouble * decDoubleFromUInt32(decDouble *, uint32_t);
|
extern decDouble * decDoubleFromUInt32(decDouble *, uint32_t);
|
||||||
extern decDouble * decDoubleFromWider(decDouble *, const decQuad *, decContext *);
|
extern decDouble * decDoubleFromWider(decDouble *, const decQuad *, decContext *);
|
||||||
|
@ -160,7 +162,8 @@
|
||||||
|
|
||||||
/* decNumber conversions; these are implemented as macros so as not */
|
/* decNumber conversions; these are implemented as macros so as not */
|
||||||
/* to force a dependency on decimal64 and decNumber in decDouble. */
|
/* to force a dependency on decimal64 and decNumber in decDouble. */
|
||||||
|
/* decDoubleFromNumber returns a decimal64 * to avoid warnings. */
|
||||||
#define decDoubleToNumber(dq, dn) decimal64ToNumber((decimal64 *)(dq), dn)
|
#define decDoubleToNumber(dq, dn) decimal64ToNumber((decimal64 *)(dq), dn)
|
||||||
#define decDoubleFromNumber(dq, dn, set) (decDouble *)decimal64FromNumber((decimal64 *)(dq), dn, set)
|
#define decDoubleFromNumber(dq, dn, set) decimal64FromNumber((decimal64 *)(dq), dn, set)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -46,7 +46,7 @@
|
||||||
#define DECNEG 0x80 /* Sign; 1=negative, 0=positive or zero */
|
#define DECNEG 0x80 /* Sign; 1=negative, 0=positive or zero */
|
||||||
#define DECINF 0x40 /* 1=Infinity */
|
#define DECINF 0x40 /* 1=Infinity */
|
||||||
#define DECNAN 0x20 /* 1=NaN */
|
#define DECNAN 0x20 /* 1=NaN */
|
||||||
#define DECSNAN 0x10 /* 1=sNaN */
|
#define DECSNAN 0x10 /* 1=sNaN */
|
||||||
/* The remaining bits are reserved; they must be 0 */
|
/* The remaining bits are reserved; they must be 0 */
|
||||||
#define DECSPECIAL (DECINF|DECNAN|DECSNAN) /* any special value */
|
#define DECSPECIAL (DECINF|DECNAN|DECSNAN) /* any special value */
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@
|
||||||
uint8_t * decNumberGetBCD(const decNumber *, uint8_t *);
|
uint8_t * decNumberGetBCD(const decNumber *, uint8_t *);
|
||||||
decNumber * decNumberSetBCD(decNumber *, const uint8_t *, uint32_t);
|
decNumber * decNumberSetBCD(decNumber *, const uint8_t *, uint32_t);
|
||||||
|
|
||||||
/* Operators and elementary functions */
|
/* Operators and elementary functions */
|
||||||
decNumber * decNumberAbs(decNumber *, const decNumber *, decContext *);
|
decNumber * decNumberAbs(decNumber *, const decNumber *, decContext *);
|
||||||
decNumber * decNumberAdd(decNumber *, const decNumber *, const decNumber *, decContext *);
|
decNumber * decNumberAdd(decNumber *, const decNumber *, const decNumber *, decContext *);
|
||||||
decNumber * decNumberAnd(decNumber *, const decNumber *, const decNumber *, decContext *);
|
decNumber * decNumberAnd(decNumber *, const decNumber *, const decNumber *, decContext *);
|
||||||
|
@ -185,7 +185,7 @@
|
||||||
|
|
||||||
/* Macros for testing decNumber *dn */
|
/* Macros for testing decNumber *dn */
|
||||||
#define decNumberIsCanonical(dn) (1) /* All decNumbers are saintly */
|
#define decNumberIsCanonical(dn) (1) /* All decNumbers are saintly */
|
||||||
#define decNumberIsFinite(dn) (((dn)->bits&DECSPECIAL)==0)
|
#define decNumberIsFinite(dn) (((dn)->bits&DECSPECIAL)==0)
|
||||||
#define decNumberIsInfinite(dn) (((dn)->bits&DECINF)!=0)
|
#define decNumberIsInfinite(dn) (((dn)->bits&DECINF)!=0)
|
||||||
#define decNumberIsNaN(dn) (((dn)->bits&(DECNAN|DECSNAN))!=0)
|
#define decNumberIsNaN(dn) (((dn)->bits&(DECNAN|DECSNAN))!=0)
|
||||||
#define decNumberIsNegative(dn) (((dn)->bits&DECNEG)!=0)
|
#define decNumberIsNegative(dn) (((dn)->bits&DECNEG)!=0)
|
||||||
|
|
|
@ -31,42 +31,56 @@
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decNumber package local type, tuning, and macro definitions */
|
/* decNumber package local type, tuning, and macro definitions */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* This header file is included by all modules in the decNumber */
|
/* This header file is included by all modules in the decNumber */
|
||||||
/* library, and contains local type definitions, tuning parameters, */
|
/* library, and contains local type definitions, tuning parameters, */
|
||||||
/* etc. It should not need to be used by application programs. */
|
/* etc. It should not need to be used by application programs. */
|
||||||
/* decNumber.h or one of decDouble (etc.) must be included first. */
|
/* decNumber.h or one of decDouble (etc.) must be included first. */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
|
||||||
#if !defined(DECNUMBERLOC)
|
#if !defined(DECNUMBERLOC)
|
||||||
#define DECNUMBERLOC
|
#define DECNUMBERLOC
|
||||||
#define DECVERSION "decNumber 3.53" /* Package Version [16 max.] */
|
#define DECVERSION "decNumber 3.61" /* Package Version [16 max.] */
|
||||||
#define DECNLAUTHOR "Mike Cowlishaw" /* Who to blame */
|
#define DECNLAUTHOR "Mike Cowlishaw" /* Who to blame */
|
||||||
|
|
||||||
#include <stdlib.h> /* for abs */
|
#include <stdlib.h> /* for abs */
|
||||||
#include <string.h> /* for memset, strcpy */
|
#include <string.h> /* for memset, strcpy */
|
||||||
#include "dconfig.h" /* for WORDS_BIGENDIAN */
|
#include "dconfig.h" /* for WORDS_BIGENDIAN */
|
||||||
|
|
||||||
/* Conditional code flag -- set this to match hardware platform */
|
/* Conditional code flag -- set this to match hardware platform */
|
||||||
/* 1=little-endian, 0=big-endian */
|
/* 1=little-endian, 0=big-endian */
|
||||||
#if WORDS_BIGENDIAN
|
#if WORDS_BIGENDIAN
|
||||||
#define DECLITEND 0
|
#define DECLITEND 0
|
||||||
#else
|
#else
|
||||||
#define DECLITEND 1
|
#define DECLITEND 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(DECLITEND)
|
||||||
|
#define DECLITEND 1 /* 1=little-endian, 0=big-endian */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Conditional code flag -- set this to 1 for best performance */
|
/* Conditional code flag -- set this to 1 for best performance */
|
||||||
|
#if !defined(DECUSE64)
|
||||||
#define DECUSE64 1 /* 1=use int64s, 0=int32 & smaller only */
|
#define DECUSE64 1 /* 1=use int64s, 0=int32 & smaller only */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Conditional check flags -- set these to 0 for best performance */
|
/* Conditional check flags -- set these to 0 for best performance */
|
||||||
|
#if !defined(DECCHECK)
|
||||||
#define DECCHECK 0 /* 1 to enable robust checking */
|
#define DECCHECK 0 /* 1 to enable robust checking */
|
||||||
|
#endif
|
||||||
|
#if !defined(DECALLOC)
|
||||||
#define DECALLOC 0 /* 1 to enable memory accounting */
|
#define DECALLOC 0 /* 1 to enable memory accounting */
|
||||||
|
#endif
|
||||||
|
#if !defined(DECTRACE)
|
||||||
#define DECTRACE 0 /* 1 to trace certain internals, etc. */
|
#define DECTRACE 0 /* 1 to trace certain internals, etc. */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Tuning parameter for decNumber (arbitrary precision) module */
|
/* Tuning parameter for decNumber (arbitrary precision) module */
|
||||||
|
#if !defined(DECBUFFER)
|
||||||
#define DECBUFFER 36 /* Size basis for local buffers. This */
|
#define DECBUFFER 36 /* Size basis for local buffers. This */
|
||||||
/* should be a common maximum precision */
|
/* should be a common maximum precision */
|
||||||
/* rounded up to a multiple of 4; must */
|
/* rounded up to a multiple of 4; must */
|
||||||
/* be zero or positive. */
|
/* be zero or positive. */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
/* Definitions for all modules (general-purpose) */
|
/* Definitions for all modules (general-purpose) */
|
||||||
|
@ -76,33 +90,34 @@
|
||||||
/* not use int or long directly. */
|
/* not use int or long directly. */
|
||||||
#define Flag uint8_t
|
#define Flag uint8_t
|
||||||
#define Byte int8_t
|
#define Byte int8_t
|
||||||
#define uByte uint8_t
|
#define uByte uint8_t
|
||||||
#define Short int16_t
|
#define Short int16_t
|
||||||
#define uShort uint16_t
|
#define uShort uint16_t
|
||||||
#define Int int32_t
|
#define Int int32_t
|
||||||
#define uInt uint32_t
|
#define uInt uint32_t
|
||||||
#define Unit decNumberUnit
|
#define Unit decNumberUnit
|
||||||
#if DECUSE64
|
#if DECUSE64
|
||||||
#define Long int64_t
|
#define Long int64_t
|
||||||
#define uLong uint64_t
|
#define uLong uint64_t
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Development-use definitions */
|
/* Development-use definitions */
|
||||||
typedef long int LI; /* for printf arguments only */
|
typedef long int LI; /* for printf arguments only */
|
||||||
#define DECNOINT 0 /* 1 to check no internal use of 'int' */
|
#define DECNOINT 0 /* 1 to check no internal use of 'int' */
|
||||||
|
/* or stdint types */
|
||||||
#if DECNOINT
|
#if DECNOINT
|
||||||
/* if these interfere with your C includes, do not set DECNOINT */
|
/* if these interfere with your C includes, do not set DECNOINT */
|
||||||
#define int ? /* enable to ensure that plain C 'int' */
|
#define int ? /* enable to ensure that plain C 'int' */
|
||||||
#define long ?? /* .. or 'long' types are not used */
|
#define long ?? /* .. or 'long' types are not used */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Shared lookup tables */
|
/* Shared lookup tables */
|
||||||
extern const uByte DECSTICKYTAB[10]; /* re-round digits if sticky */
|
extern const uByte DECSTICKYTAB[10]; /* re-round digits if sticky */
|
||||||
extern const uInt DECPOWERS[10]; /* powers of ten table */
|
extern const uInt DECPOWERS[10]; /* powers of ten table */
|
||||||
/* The following are included from decDPD.h */
|
/* The following are included from decDPD.h */
|
||||||
#include "decDPDSymbols.h"
|
#include "decDPDSymbols.h"
|
||||||
extern const uShort DPD2BIN[1024]; /* DPD -> 0-999 */
|
extern const uShort DPD2BIN[1024]; /* DPD -> 0-999 */
|
||||||
extern const uShort BIN2DPD[1000]; /* 0-999 -> DPD */
|
extern const uShort BIN2DPD[1000]; /* 0-999 -> DPD */
|
||||||
extern const uInt DPD2BINK[1024]; /* DPD -> 0-999000 */
|
extern const uInt DPD2BINK[1024]; /* DPD -> 0-999000 */
|
||||||
extern const uInt DPD2BINM[1024]; /* DPD -> 0-999000000 */
|
extern const uInt DPD2BINM[1024]; /* DPD -> 0-999000000 */
|
||||||
extern const uByte DPD2BCD8[4096]; /* DPD -> ddd + len */
|
extern const uByte DPD2BCD8[4096]; /* DPD -> ddd + len */
|
||||||
|
@ -111,32 +126,42 @@
|
||||||
|
|
||||||
/* LONGMUL32HI -- set w=(u*v)>>32, where w, u, and v are uInts */
|
/* LONGMUL32HI -- set w=(u*v)>>32, where w, u, and v are uInts */
|
||||||
/* (that is, sets w to be the high-order word of the 64-bit result; */
|
/* (that is, sets w to be the high-order word of the 64-bit result; */
|
||||||
/* the low-order word is simply u*v.) */
|
/* the low-order word is simply u*v.) */
|
||||||
/* This version is derived from Knuth via Hacker's Delight; */
|
/* This version is derived from Knuth via Hacker's Delight; */
|
||||||
/* it seems to optimize better than some others tried */
|
/* it seems to optimize better than some others tried */
|
||||||
#define LONGMUL32HI(w, u, v) { \
|
#define LONGMUL32HI(w, u, v) { \
|
||||||
uInt u0, u1, v0, v1, w0, w1, w2, t; \
|
uInt u0, u1, v0, v1, w0, w1, w2, t; \
|
||||||
u0=u & 0xffff; u1=u>>16; \
|
u0=u & 0xffff; u1=u>>16; \
|
||||||
v0=v & 0xffff; v1=v>>16; \
|
v0=v & 0xffff; v1=v>>16; \
|
||||||
w0=u0*v0; \
|
w0=u0*v0; \
|
||||||
t=u1*v0 + (w0>>16); \
|
t=u1*v0 + (w0>>16); \
|
||||||
w1=t & 0xffff; w2=t>>16; \
|
w1=t & 0xffff; w2=t>>16; \
|
||||||
w1=u0*v1 + w1; \
|
w1=u0*v1 + w1; \
|
||||||
(w)=u1*v1 + w2 + (w1>>16);}
|
(w)=u1*v1 + w2 + (w1>>16);}
|
||||||
|
|
||||||
/* ROUNDUP -- round an integer up to a multiple of n */
|
/* ROUNDUP -- round an integer up to a multiple of n */
|
||||||
#define ROUNDUP(i, n) ((((i)+(n)-1)/n)*n)
|
#define ROUNDUP(i, n) ((((i)+(n)-1)/n)*n)
|
||||||
|
#define ROUNDUP4(i) (((i)+3)&~3) /* special for n=4 */
|
||||||
|
|
||||||
/* ROUNDDOWN -- round an integer down to a multiple of n */
|
/* ROUNDDOWN -- round an integer down to a multiple of n */
|
||||||
#define ROUNDDOWN(i, n) (((i)/n)*n)
|
#define ROUNDDOWN(i, n) (((i)/n)*n)
|
||||||
#define ROUNDDOWN4(i) ((i)&~3) /* special for n=4 */
|
#define ROUNDDOWN4(i) ((i)&~3) /* special for n=4 */
|
||||||
|
|
||||||
/* References to multi-byte sequences under different sizes */
|
/* References to multi-byte sequences under different sizes; these */
|
||||||
/* Refer to a uInt from four bytes starting at a char* or uByte*, */
|
/* require locally declared variables, but do not violate strict */
|
||||||
/* etc. */
|
/* aliasing or alignment (as did the UINTAT simple cast to uInt). */
|
||||||
#define UINTAT(b) (*((uInt *)(b)))
|
/* Variables needed are uswork, uiwork, etc. [so do not use at same */
|
||||||
#define USHORTAT(b) (*((uShort *)(b)))
|
/* level in an expression, e.g., UBTOUI(x)==UBTOUI(y) may fail]. */
|
||||||
#define UBYTEAT(b) (*((uByte *)(b)))
|
|
||||||
|
/* Return a uInt, etc., from bytes starting at a char* or uByte* */
|
||||||
|
#define UBTOUS(b) (memcpy((void *)&uswork, b, 2), uswork)
|
||||||
|
#define UBTOUI(b) (memcpy((void *)&uiwork, b, 4), uiwork)
|
||||||
|
|
||||||
|
/* Store a uInt, etc., into bytes starting at a char* or uByte*. */
|
||||||
|
/* Returns i, evaluated, for convenience; has to use uiwork because */
|
||||||
|
/* i may be an expression. */
|
||||||
|
#define UBFROMUS(b, i) (uswork=(i), memcpy(b, (void *)&uswork, 2), uswork)
|
||||||
|
#define UBFROMUI(b, i) (uiwork=(i), memcpy(b, (void *)&uiwork, 4), uiwork)
|
||||||
|
|
||||||
/* X10 and X100 -- multiply integer i by 10 or 100 */
|
/* X10 and X100 -- multiply integer i by 10 or 100 */
|
||||||
/* [shifts are usually faster than multiply; could be conditional] */
|
/* [shifts are usually faster than multiply; could be conditional] */
|
||||||
|
@ -149,7 +174,7 @@
|
||||||
|
|
||||||
/* Useful constants */
|
/* Useful constants */
|
||||||
#define BILLION 1000000000 /* 10**9 */
|
#define BILLION 1000000000 /* 10**9 */
|
||||||
/* CHARMASK: 0x30303030 for ASCII/UTF8; 0xF0F0F0F0 for EBCDIC */
|
/* CHARMASK: 0x30303030 for ASCII/UTF8; 0xF0F0F0F0 for EBCDIC */
|
||||||
#define CHARMASK ((((((((uInt)'0')<<8)+'0')<<8)+'0')<<8)+'0')
|
#define CHARMASK ((((((((uInt)'0')<<8)+'0')<<8)+'0')<<8)+'0')
|
||||||
|
|
||||||
|
|
||||||
|
@ -172,7 +197,7 @@
|
||||||
#error Minimum exponent mismatch
|
#error Minimum exponent mismatch
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Set DECDPUNMAX -- the maximum integer that fits in DECDPUN */
|
/* Set DECDPUNMAX -- the maximum integer that fits in DECDPUN */
|
||||||
/* digits, and D2UTABLE -- the initializer for the D2U table */
|
/* digits, and D2UTABLE -- the initializer for the D2U table */
|
||||||
#if DECDPUN==1
|
#if DECDPUN==1
|
||||||
#define DECDPUNMAX 9
|
#define DECDPUNMAX 9
|
||||||
|
@ -253,7 +278,7 @@
|
||||||
/* D2N -- return the number of decNumber structs that would be */
|
/* D2N -- return the number of decNumber structs that would be */
|
||||||
/* needed to contain that number of digits (and the initial */
|
/* needed to contain that number of digits (and the initial */
|
||||||
/* decNumber struct) safely. Note that one Unit is included in the */
|
/* decNumber struct) safely. Note that one Unit is included in the */
|
||||||
/* initial structure. Used for allocating space that is aligned on */
|
/* initial structure. Used for allocating space that is aligned on */
|
||||||
/* a decNumber struct boundary. */
|
/* a decNumber struct boundary. */
|
||||||
#define D2N(d) \
|
#define D2N(d) \
|
||||||
((((SD2U(d)-1)*sizeof(Unit))+sizeof(decNumber)*2-1)/sizeof(decNumber))
|
((((SD2U(d)-1)*sizeof(Unit))+sizeof(decNumber)*2-1)/sizeof(decNumber))
|
||||||
|
@ -261,7 +286,7 @@
|
||||||
/* TODIGIT -- macro to remove the leading digit from the unsigned */
|
/* TODIGIT -- macro to remove the leading digit from the unsigned */
|
||||||
/* integer u at column cut (counting from the right, LSD=0) and */
|
/* integer u at column cut (counting from the right, LSD=0) and */
|
||||||
/* place it as an ASCII character into the character pointed to by */
|
/* place it as an ASCII character into the character pointed to by */
|
||||||
/* c. Note that cut must be <= 9, and the maximum value for u is */
|
/* c. Note that cut must be <= 9, and the maximum value for u is */
|
||||||
/* 2,000,000,000 (as is needed for negative exponents of */
|
/* 2,000,000,000 (as is needed for negative exponents of */
|
||||||
/* subnormals). The unsigned integer pow is used as a temporary */
|
/* subnormals). The unsigned integer pow is used as a temporary */
|
||||||
/* variable. */
|
/* variable. */
|
||||||
|
@ -274,7 +299,7 @@
|
||||||
pow/=2; \
|
pow/=2; \
|
||||||
if ((u)>=pow) {(u)-=pow; *(c)+=4;} \
|
if ((u)>=pow) {(u)-=pow; *(c)+=4;} \
|
||||||
pow/=2; \
|
pow/=2; \
|
||||||
} \
|
} \
|
||||||
if ((u)>=pow) {(u)-=pow; *(c)+=2;} \
|
if ((u)>=pow) {(u)-=pow; *(c)+=2;} \
|
||||||
pow/=2; \
|
pow/=2; \
|
||||||
if ((u)>=pow) {(u)-=pow; *(c)+=1;} \
|
if ((u)>=pow) {(u)-=pow; *(c)+=1;} \
|
||||||
|
@ -289,9 +314,9 @@
|
||||||
/* number, whose coefficient is a string of bcd8 uBytes */
|
/* number, whose coefficient is a string of bcd8 uBytes */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uByte *msd; /* -> most significant digit */
|
uByte *msd; /* -> most significant digit */
|
||||||
uByte *lsd; /* -> least ditto */
|
uByte *lsd; /* -> least ditto */
|
||||||
uInt sign; /* 0=positive, DECFLOAT_Sign=negative */
|
uInt sign; /* 0=positive, DECFLOAT_Sign=negative */
|
||||||
Int exponent; /* Unadjusted signed exponent (q), or */
|
Int exponent; /* Unadjusted signed exponent (q), or */
|
||||||
/* DECFLOAT_NaN etc. for a special */
|
/* DECFLOAT_NaN etc. for a special */
|
||||||
} bcdnum;
|
} bcdnum;
|
||||||
|
|
||||||
|
@ -308,12 +333,12 @@
|
||||||
#define DECWORDS (DECBYTES/4)
|
#define DECWORDS (DECBYTES/4)
|
||||||
#define DECWWORDS (DECWBYTES/4)
|
#define DECWWORDS (DECWBYTES/4)
|
||||||
#if DECLITEND
|
#if DECLITEND
|
||||||
#define DFWORD(df, off) ((df)->words[DECWORDS-1-(off)])
|
#define DFBYTE(df, off) ((df)->bytes[DECBYTES-1-(off)])
|
||||||
#define DFBYTE(df, off) ((df)->bytes[DECBYTES-1-(off)])
|
#define DFWORD(df, off) ((df)->words[DECWORDS-1-(off)])
|
||||||
#define DFWWORD(dfw, off) ((dfw)->words[DECWWORDS-1-(off)])
|
#define DFWWORD(dfw, off) ((dfw)->words[DECWWORDS-1-(off)])
|
||||||
#else
|
#else
|
||||||
#define DFWORD(df, off) ((df)->words[off])
|
#define DFBYTE(df, off) ((df)->bytes[off])
|
||||||
#define DFBYTE(df, off) ((df)->bytes[off])
|
#define DFWORD(df, off) ((df)->words[off])
|
||||||
#define DFWWORD(dfw, off) ((dfw)->words[off])
|
#define DFWWORD(dfw, off) ((dfw)->words[off])
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -338,7 +363,7 @@
|
||||||
/* Format-dependent macros and constants */
|
/* Format-dependent macros and constants */
|
||||||
#if defined(DECPMAX)
|
#if defined(DECPMAX)
|
||||||
|
|
||||||
/* Useful constants */
|
/* Useful constants */
|
||||||
#define DECPMAX9 (ROUNDUP(DECPMAX, 9)/9) /* 'Pmax' in 10**9s */
|
#define DECPMAX9 (ROUNDUP(DECPMAX, 9)/9) /* 'Pmax' in 10**9s */
|
||||||
/* Top words for a zero */
|
/* Top words for a zero */
|
||||||
#define SINGLEZERO 0x22500000
|
#define SINGLEZERO 0x22500000
|
||||||
|
@ -350,10 +375,10 @@
|
||||||
/* DFISZERO -- test for (any) zero */
|
/* DFISZERO -- test for (any) zero */
|
||||||
/* DFISCCZERO -- test for coefficient continuation being zero */
|
/* DFISCCZERO -- test for coefficient continuation being zero */
|
||||||
/* DFISCC01 -- test for coefficient contains only 0s and 1s */
|
/* DFISCC01 -- test for coefficient contains only 0s and 1s */
|
||||||
/* DFISINT -- test for finite and exponent q=0 */
|
/* DFISINT -- test for finite and exponent q=0 */
|
||||||
/* DFISUINT01 -- test for sign=0, finite, exponent q=0, and */
|
/* DFISUINT01 -- test for sign=0, finite, exponent q=0, and */
|
||||||
/* MSD=0 or 1 */
|
/* MSD=0 or 1 */
|
||||||
/* ZEROWORD is also defined here. */
|
/* ZEROWORD is also defined here. */
|
||||||
/* In DFISZERO the first test checks the least-significant word */
|
/* In DFISZERO the first test checks the least-significant word */
|
||||||
/* (most likely to be non-zero); the penultimate tests MSD and */
|
/* (most likely to be non-zero); the penultimate tests MSD and */
|
||||||
/* DPDs in the signword, and the final test excludes specials and */
|
/* DPDs in the signword, and the final test excludes specials and */
|
||||||
|
@ -407,26 +432,36 @@
|
||||||
|| ((dpd)&(((uInt)0x6e)<<(k)))!=(((uInt)0x6e)<<(k)))
|
|| ((dpd)&(((uInt)0x6e)<<(k)))!=(((uInt)0x6e)<<(k)))
|
||||||
/* declet is at offset k (a multiple of 2) in a pair of uInts: */
|
/* declet is at offset k (a multiple of 2) in a pair of uInts: */
|
||||||
/* [the top 2 bits will always be in the more-significant uInt] */
|
/* [the top 2 bits will always be in the more-significant uInt] */
|
||||||
#define CANONDPDTWO(hi, lo, k) (((hi)&(0x300>>(32-(k))))==0 \
|
#define CANONDPDTWO(hi, lo, k) (((hi)&(0x300>>(32-(k))))==0 \
|
||||||
|| ((hi)&(0x6e>>(32-(k))))!=(0x6e>>(32-(k))) \
|
|| ((hi)&(0x6e>>(32-(k))))!=(0x6e>>(32-(k))) \
|
||||||
|| ((lo)&(((uInt)0x6e)<<(k)))!=(((uInt)0x6e)<<(k)))
|
|| ((lo)&(((uInt)0x6e)<<(k)))!=(((uInt)0x6e)<<(k)))
|
||||||
|
|
||||||
/* Macro to test whether a full-length (length DECPMAX) BCD8 */
|
/* Macro to test whether a full-length (length DECPMAX) BCD8 */
|
||||||
/* coefficient is zero */
|
/* coefficient, starting at uByte u, is all zeros */
|
||||||
/* test just the LSWord first, then the remainder */
|
/* Test just the LSWord first, then the remainder as a sequence */
|
||||||
|
/* of tests in order to avoid same-level use of UBTOUI */
|
||||||
#if DECPMAX==7
|
#if DECPMAX==7
|
||||||
#define ISCOEFFZERO(u) (UINTAT((u)+DECPMAX-4)==0 \
|
#define ISCOEFFZERO(u) ( \
|
||||||
&& UINTAT((u)+DECPMAX-7)==0)
|
UBTOUI((u)+DECPMAX-4)==0 \
|
||||||
|
&& UBTOUS((u)+DECPMAX-6)==0 \
|
||||||
|
&& *(u)==0)
|
||||||
#elif DECPMAX==16
|
#elif DECPMAX==16
|
||||||
#define ISCOEFFZERO(u) (UINTAT((u)+DECPMAX-4)==0 \
|
#define ISCOEFFZERO(u) ( \
|
||||||
&& (UINTAT((u)+DECPMAX-8)+UINTAT((u)+DECPMAX-12) \
|
UBTOUI((u)+DECPMAX-4)==0 \
|
||||||
+UINTAT((u)+DECPMAX-16))==0)
|
&& UBTOUI((u)+DECPMAX-8)==0 \
|
||||||
|
&& UBTOUI((u)+DECPMAX-12)==0 \
|
||||||
|
&& UBTOUI(u)==0)
|
||||||
#elif DECPMAX==34
|
#elif DECPMAX==34
|
||||||
#define ISCOEFFZERO(u) (UINTAT((u)+DECPMAX-4)==0 \
|
#define ISCOEFFZERO(u) ( \
|
||||||
&& (UINTAT((u)+DECPMAX-8) +UINTAT((u)+DECPMAX-12) \
|
UBTOUI((u)+DECPMAX-4)==0 \
|
||||||
+UINTAT((u)+DECPMAX-16)+UINTAT((u)+DECPMAX-20) \
|
&& UBTOUI((u)+DECPMAX-8)==0 \
|
||||||
+UINTAT((u)+DECPMAX-24)+UINTAT((u)+DECPMAX-28) \
|
&& UBTOUI((u)+DECPMAX-12)==0 \
|
||||||
+UINTAT((u)+DECPMAX-32)+USHORTAT((u)+DECPMAX-34))==0)
|
&& UBTOUI((u)+DECPMAX-16)==0 \
|
||||||
|
&& UBTOUI((u)+DECPMAX-20)==0 \
|
||||||
|
&& UBTOUI((u)+DECPMAX-24)==0 \
|
||||||
|
&& UBTOUI((u)+DECPMAX-28)==0 \
|
||||||
|
&& UBTOUI((u)+DECPMAX-32)==0 \
|
||||||
|
&& UBTOUS(u)==0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Macros and masks for the exponent continuation field and MSD */
|
/* Macros and masks for the exponent continuation field and MSD */
|
||||||
|
@ -448,29 +483,24 @@
|
||||||
#define ECONNANMASK ((0x01ffffff>>(32-6-DECECONL))<<(32-6-DECECONL))
|
#define ECONNANMASK ((0x01ffffff>>(32-6-DECECONL))<<(32-6-DECECONL))
|
||||||
|
|
||||||
/* Macros to decode the coefficient in a finite decFloat *df into */
|
/* Macros to decode the coefficient in a finite decFloat *df into */
|
||||||
/* a BCD string (uByte *bcdin) of length DECPMAX uBytes */
|
/* a BCD string (uByte *bcdin) of length DECPMAX uBytes. */
|
||||||
|
|
||||||
/* In-line sequence to convert 10 bits at right end of uInt dpd */
|
/* In-line sequence to convert least significant 10 bits of uInt */
|
||||||
/* to three BCD8 digits starting at uByte u. Note that an extra */
|
/* dpd to three BCD8 digits starting at uByte u. Note that an */
|
||||||
/* byte is written to the right of the three digits because this */
|
/* extra byte is written to the right of the three digits because */
|
||||||
/* moves four at a time for speed; the alternative macro moves */
|
/* four bytes are moved at a time for speed; the alternative */
|
||||||
/* exactly three bytes */
|
/* macro moves exactly three bytes (usually slower). */
|
||||||
#define dpd2bcd8(u, dpd) { \
|
#define dpd2bcd8(u, dpd) memcpy(u, &DPD2BCD8[((dpd)&0x3ff)*4], 4)
|
||||||
UINTAT(u)=UINTAT(&DPD2BCD8[((dpd)&0x3ff)*4]);}
|
#define dpd2bcd83(u, dpd) memcpy(u, &DPD2BCD8[((dpd)&0x3ff)*4], 3)
|
||||||
|
|
||||||
#define dpd2bcd83(u, dpd) { \
|
|
||||||
*(u)=DPD2BCD8[((dpd)&0x3ff)*4]; \
|
|
||||||
*(u+1)=DPD2BCD8[((dpd)&0x3ff)*4+1]; \
|
|
||||||
*(u+2)=DPD2BCD8[((dpd)&0x3ff)*4+2];}
|
|
||||||
|
|
||||||
/* Decode the declets. After extracting each one, it is decoded */
|
/* Decode the declets. After extracting each one, it is decoded */
|
||||||
/* to BCD8 using a table lookup (also used for variable-length */
|
/* to BCD8 using a table lookup (also used for variable-length */
|
||||||
/* decode). Each DPD decode is 3 bytes BCD8 plus a one-byte */
|
/* decode). Each DPD decode is 3 bytes BCD8 plus a one-byte */
|
||||||
/* length which is not used, here). Fixed-length 4-byte moves */
|
/* length which is not used, here). Fixed-length 4-byte moves */
|
||||||
/* are fast, however, almost everywhere, and so are used except */
|
/* are fast, however, almost everywhere, and so are used except */
|
||||||
/* for the final three bytes (to avoid overrun). The code below */
|
/* for the final three bytes (to avoid overrun). The code below */
|
||||||
/* is 36 instructions for Doubles and about 70 for Quads, even */
|
/* is 36 instructions for Doubles and about 70 for Quads, even */
|
||||||
/* on IA32. */
|
/* on IA32. */
|
||||||
|
|
||||||
/* Two macros are defined for each format: */
|
/* Two macros are defined for each format: */
|
||||||
/* GETCOEFF extracts the coefficient of the current format */
|
/* GETCOEFF extracts the coefficient of the current format */
|
||||||
|
@ -478,7 +508,7 @@
|
||||||
/* The latter is a copy of the next-wider GETCOEFF using DFWWORD. */
|
/* The latter is a copy of the next-wider GETCOEFF using DFWWORD. */
|
||||||
|
|
||||||
#if DECPMAX==7
|
#if DECPMAX==7
|
||||||
#define GETCOEFF(df, bcd) { \
|
#define GETCOEFF(df, bcd) { \
|
||||||
uInt sourhi=DFWORD(df, 0); \
|
uInt sourhi=DFWORD(df, 0); \
|
||||||
*(bcd)=(uByte)DECCOMBMSD[sourhi>>26]; \
|
*(bcd)=(uByte)DECCOMBMSD[sourhi>>26]; \
|
||||||
dpd2bcd8(bcd+1, sourhi>>10); \
|
dpd2bcd8(bcd+1, sourhi>>10); \
|
||||||
|
@ -494,7 +524,7 @@
|
||||||
dpd2bcd83(bcd+13, sourlo);}
|
dpd2bcd83(bcd+13, sourlo);}
|
||||||
|
|
||||||
#elif DECPMAX==16
|
#elif DECPMAX==16
|
||||||
#define GETCOEFF(df, bcd) { \
|
#define GETCOEFF(df, bcd) { \
|
||||||
uInt sourhi=DFWORD(df, 0); \
|
uInt sourhi=DFWORD(df, 0); \
|
||||||
uInt sourlo=DFWORD(df, 1); \
|
uInt sourlo=DFWORD(df, 1); \
|
||||||
*(bcd)=(uByte)DECCOMBMSD[sourhi>>26]; \
|
*(bcd)=(uByte)DECCOMBMSD[sourhi>>26]; \
|
||||||
|
@ -522,7 +552,7 @@
|
||||||
dpd2bcd83(bcd+31, sourlo);}
|
dpd2bcd83(bcd+31, sourlo);}
|
||||||
|
|
||||||
#elif DECPMAX==34
|
#elif DECPMAX==34
|
||||||
#define GETCOEFF(df, bcd) { \
|
#define GETCOEFF(df, bcd) { \
|
||||||
uInt sourhi=DFWORD(df, 0); \
|
uInt sourhi=DFWORD(df, 0); \
|
||||||
uInt sourmh=DFWORD(df, 1); \
|
uInt sourmh=DFWORD(df, 1); \
|
||||||
uInt sourml=DFWORD(df, 2); \
|
uInt sourml=DFWORD(df, 2); \
|
||||||
|
@ -540,12 +570,12 @@
|
||||||
dpd2bcd8(bcd+28, sourlo>>10); \
|
dpd2bcd8(bcd+28, sourlo>>10); \
|
||||||
dpd2bcd83(bcd+31, sourlo);}
|
dpd2bcd83(bcd+31, sourlo);}
|
||||||
|
|
||||||
#define GETWCOEFF(df, bcd) {??} /* [should never be used] */
|
#define GETWCOEFF(df, bcd) {??} /* [should never be used] */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Macros to decode the coefficient in a finite decFloat *df into */
|
/* Macros to decode the coefficient in a finite decFloat *df into */
|
||||||
/* a base-billion uInt array, with the least-significant */
|
/* a base-billion uInt array, with the least-significant */
|
||||||
/* 0-999999999 'digit' at offset 0. */
|
/* 0-999999999 'digit' at offset 0. */
|
||||||
|
|
||||||
/* Decode the declets. After extracting each one, it is decoded */
|
/* Decode the declets. After extracting each one, it is decoded */
|
||||||
/* to binary using a table lookup. Three tables are used; one */
|
/* to binary using a table lookup. Three tables are used; one */
|
||||||
|
@ -597,8 +627,8 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Macros to decode the coefficient in a finite decFloat *df into */
|
/* Macros to decode the coefficient in a finite decFloat *df into */
|
||||||
/* a base-thousand uInt array, with the least-significant 0-999 */
|
/* a base-thousand uInt array (of size DECLETS+1, to allow for */
|
||||||
/* 'digit' at offset 0. */
|
/* the MSD), with the least-significant 0-999 'digit' at offset 0.*/
|
||||||
|
|
||||||
/* Decode the declets. After extracting each one, it is decoded */
|
/* Decode the declets. After extracting each one, it is decoded */
|
||||||
/* to binary using a table lookup. */
|
/* to binary using a table lookup. */
|
||||||
|
@ -640,9 +670,72 @@
|
||||||
(buf)[9]=DPD2BIN[((sourhi<<6) | (sourmh>>26))&0x3ff]; \
|
(buf)[9]=DPD2BIN[((sourhi<<6) | (sourmh>>26))&0x3ff]; \
|
||||||
(buf)[10]=DPD2BIN[(sourhi>>4)&0x3ff]; \
|
(buf)[10]=DPD2BIN[(sourhi>>4)&0x3ff]; \
|
||||||
(buf)[11]=DECCOMBMSD[sourhi>>26];}
|
(buf)[11]=DECCOMBMSD[sourhi>>26];}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Macros to decode the coefficient in a finite decFloat *df and */
|
||||||
|
/* add to a base-thousand uInt array (as for GETCOEFFTHOU). */
|
||||||
|
/* After the addition then most significant 'digit' in the array */
|
||||||
|
/* might have a value larger then 10 (with a maximum of 19). */
|
||||||
|
#if DECPMAX==7
|
||||||
|
#define ADDCOEFFTHOU(df, buf) { \
|
||||||
|
uInt sourhi=DFWORD(df, 0); \
|
||||||
|
(buf)[0]+=DPD2BIN[sourhi&0x3ff]; \
|
||||||
|
if (buf[0]>999) {buf[0]-=1000; buf[1]++;} \
|
||||||
|
(buf)[1]+=DPD2BIN[(sourhi>>10)&0x3ff]; \
|
||||||
|
if (buf[1]>999) {buf[1]-=1000; buf[2]++;} \
|
||||||
|
(buf)[2]+=DECCOMBMSD[sourhi>>26];}
|
||||||
|
|
||||||
|
#elif DECPMAX==16
|
||||||
|
#define ADDCOEFFTHOU(df, buf) { \
|
||||||
|
uInt sourhi, sourlo; \
|
||||||
|
sourlo=DFWORD(df, 1); \
|
||||||
|
(buf)[0]+=DPD2BIN[sourlo&0x3ff]; \
|
||||||
|
if (buf[0]>999) {buf[0]-=1000; buf[1]++;} \
|
||||||
|
(buf)[1]+=DPD2BIN[(sourlo>>10)&0x3ff]; \
|
||||||
|
if (buf[1]>999) {buf[1]-=1000; buf[2]++;} \
|
||||||
|
(buf)[2]+=DPD2BIN[(sourlo>>20)&0x3ff]; \
|
||||||
|
if (buf[2]>999) {buf[2]-=1000; buf[3]++;} \
|
||||||
|
sourhi=DFWORD(df, 0); \
|
||||||
|
(buf)[3]+=DPD2BIN[((sourhi<<2) | (sourlo>>30))&0x3ff]; \
|
||||||
|
if (buf[3]>999) {buf[3]-=1000; buf[4]++;} \
|
||||||
|
(buf)[4]+=DPD2BIN[(sourhi>>8)&0x3ff]; \
|
||||||
|
if (buf[4]>999) {buf[4]-=1000; buf[5]++;} \
|
||||||
|
(buf)[5]+=DECCOMBMSD[sourhi>>26];}
|
||||||
|
|
||||||
|
#elif DECPMAX==34
|
||||||
|
#define ADDCOEFFTHOU(df, buf) { \
|
||||||
|
uInt sourhi, sourmh, sourml, sourlo; \
|
||||||
|
sourlo=DFWORD(df, 3); \
|
||||||
|
(buf)[0]+=DPD2BIN[sourlo&0x3ff]; \
|
||||||
|
if (buf[0]>999) {buf[0]-=1000; buf[1]++;} \
|
||||||
|
(buf)[1]+=DPD2BIN[(sourlo>>10)&0x3ff]; \
|
||||||
|
if (buf[1]>999) {buf[1]-=1000; buf[2]++;} \
|
||||||
|
(buf)[2]+=DPD2BIN[(sourlo>>20)&0x3ff]; \
|
||||||
|
if (buf[2]>999) {buf[2]-=1000; buf[3]++;} \
|
||||||
|
sourml=DFWORD(df, 2); \
|
||||||
|
(buf)[3]+=DPD2BIN[((sourml<<2) | (sourlo>>30))&0x3ff]; \
|
||||||
|
if (buf[3]>999) {buf[3]-=1000; buf[4]++;} \
|
||||||
|
(buf)[4]+=DPD2BIN[(sourml>>8)&0x3ff]; \
|
||||||
|
if (buf[4]>999) {buf[4]-=1000; buf[5]++;} \
|
||||||
|
(buf)[5]+=DPD2BIN[(sourml>>18)&0x3ff]; \
|
||||||
|
if (buf[5]>999) {buf[5]-=1000; buf[6]++;} \
|
||||||
|
sourmh=DFWORD(df, 1); \
|
||||||
|
(buf)[6]+=DPD2BIN[((sourmh<<4) | (sourml>>28))&0x3ff]; \
|
||||||
|
if (buf[6]>999) {buf[6]-=1000; buf[7]++;} \
|
||||||
|
(buf)[7]+=DPD2BIN[(sourmh>>6)&0x3ff]; \
|
||||||
|
if (buf[7]>999) {buf[7]-=1000; buf[8]++;} \
|
||||||
|
(buf)[8]+=DPD2BIN[(sourmh>>16)&0x3ff]; \
|
||||||
|
if (buf[8]>999) {buf[8]-=1000; buf[9]++;} \
|
||||||
|
sourhi=DFWORD(df, 0); \
|
||||||
|
(buf)[9]+=DPD2BIN[((sourhi<<6) | (sourmh>>26))&0x3ff]; \
|
||||||
|
if (buf[9]>999) {buf[9]-=1000; buf[10]++;} \
|
||||||
|
(buf)[10]+=DPD2BIN[(sourhi>>4)&0x3ff]; \
|
||||||
|
if (buf[10]>999) {buf[10]-=1000; buf[11]++;} \
|
||||||
|
(buf)[11]+=DECCOMBMSD[sourhi>>26];}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Set a decFloat to the maximum positive finite number (Nmax) */
|
/* Set a decFloat to the maximum positive finite number (Nmax) */
|
||||||
#if DECPMAX==7
|
#if DECPMAX==7
|
||||||
#define DFSETNMAX(df) \
|
#define DFSETNMAX(df) \
|
||||||
|
|
|
@ -31,12 +31,12 @@
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* Packed Decimal conversion module */
|
/* Packed Decimal conversion module */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* This module comprises the routines for Packed Decimal format */
|
/* This module comprises the routines for Packed Decimal format */
|
||||||
/* numbers. Conversions are supplied to and from decNumber, which in */
|
/* numbers. Conversions are supplied to and from decNumber, which in */
|
||||||
/* turn supports: */
|
/* turn supports: */
|
||||||
/* conversions to and from string */
|
/* conversions to and from string */
|
||||||
/* arithmetic routines */
|
/* arithmetic routines */
|
||||||
/* utilities. */
|
/* utilities. */
|
||||||
/* Conversions from decNumber to and from densely packed decimal */
|
/* Conversions from decNumber to and from densely packed decimal */
|
||||||
/* formats are provided by the decimal32 through decimal128 modules. */
|
/* formats are provided by the decimal32 through decimal128 modules. */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
@ -51,8 +51,8 @@
|
||||||
/* */
|
/* */
|
||||||
/* bcd is the BCD bytes */
|
/* bcd is the BCD bytes */
|
||||||
/* length is the length of the BCD array */
|
/* length is the length of the BCD array */
|
||||||
/* scale is the scale result */
|
/* scale is the scale result */
|
||||||
/* dn is the decNumber */
|
/* dn is the decNumber */
|
||||||
/* returns bcd, or NULL if error */
|
/* returns bcd, or NULL if error */
|
||||||
/* */
|
/* */
|
||||||
/* The number is converted to a BCD packed decimal byte array, */
|
/* The number is converted to a BCD packed decimal byte array, */
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
/* as necessary. */
|
/* as necessary. */
|
||||||
/* */
|
/* */
|
||||||
/* If there is an error (that is, the decNumber has too many digits */
|
/* If there is an error (that is, the decNumber has too many digits */
|
||||||
/* to fit in length bytes, or it is a NaN or Infinity), NULL is */
|
/* to fit in length bytes, or it is a NaN or Infinity), NULL is */
|
||||||
/* returned and the bcd and scale results are unchanged. Otherwise */
|
/* returned and the bcd and scale results are unchanged. Otherwise */
|
||||||
/* bcd is returned. */
|
/* bcd is returned. */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
@ -86,9 +86,9 @@ uByte * decPackedFromNumber(uByte *bcd, Int length, Int *scale,
|
||||||
if (dn->digits>length*2-1 /* too long .. */
|
if (dn->digits>length*2-1 /* too long .. */
|
||||||
||(dn->bits & DECSPECIAL)) return NULL; /* .. or special -- hopeless */
|
||(dn->bits & DECSPECIAL)) return NULL; /* .. or special -- hopeless */
|
||||||
|
|
||||||
if (dn->bits&DECNEG) obyte=DECPMINUS; /* set the sign .. */
|
if (dn->bits&DECNEG) obyte=DECPMINUS; /* set the sign .. */
|
||||||
else obyte=DECPPLUS;
|
else obyte=DECPPLUS;
|
||||||
*scale=-dn->exponent; /* .. and scale */
|
*scale=-dn->exponent; /* .. and scale */
|
||||||
|
|
||||||
/* loop from lowest (rightmost) byte */
|
/* loop from lowest (rightmost) byte */
|
||||||
out=bcd+length-1; /* -> final byte */
|
out=bcd+length-1; /* -> final byte */
|
||||||
|
@ -141,7 +141,7 @@ uByte * decPackedFromNumber(uByte *bcd, Int length, Int *scale,
|
||||||
/* bcd is the BCD bytes */
|
/* bcd is the BCD bytes */
|
||||||
/* length is the length of the BCD array */
|
/* length is the length of the BCD array */
|
||||||
/* scale is the scale associated with the BCD integer */
|
/* scale is the scale associated with the BCD integer */
|
||||||
/* dn is the decNumber [with space for length*2 digits] */
|
/* dn is the decNumber [with space for length*2 digits] */
|
||||||
/* returns dn, or NULL if error */
|
/* returns dn, or NULL if error */
|
||||||
/* */
|
/* */
|
||||||
/* The BCD packed decimal byte array, together with an associated */
|
/* The BCD packed decimal byte array, together with an associated */
|
||||||
|
@ -157,7 +157,7 @@ uByte * decPackedFromNumber(uByte *bcd, Int length, Int *scale,
|
||||||
/* no error is possible unless the adjusted exponent is out of range, */
|
/* no error is possible unless the adjusted exponent is out of range, */
|
||||||
/* no sign nibble was found, or a sign nibble was found before the */
|
/* no sign nibble was found, or a sign nibble was found before the */
|
||||||
/* final nibble. In these error cases, NULL is returned and the */
|
/* final nibble. In these error cases, NULL is returned and the */
|
||||||
/* decNumber will be 0. */
|
/* decNumber will be 0. */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
decNumber * decPackedToNumber(const uByte *bcd, Int length,
|
decNumber * decPackedToNumber(const uByte *bcd, Int length,
|
||||||
const Int *scale, decNumber *dn) {
|
const Int *scale, decNumber *dn) {
|
||||||
|
@ -165,7 +165,7 @@ decNumber * decPackedToNumber(const uByte *bcd, Int length,
|
||||||
const uByte *first; /* -> first non-zero byte */
|
const uByte *first; /* -> first non-zero byte */
|
||||||
uInt nib; /* work nibble */
|
uInt nib; /* work nibble */
|
||||||
Unit *up=dn->lsu; /* output pointer */
|
Unit *up=dn->lsu; /* output pointer */
|
||||||
Int digits; /* digits count */
|
Int digits; /* digits count */
|
||||||
Int cut=0; /* phase of output */
|
Int cut=0; /* phase of output */
|
||||||
|
|
||||||
decNumberZero(dn); /* default result */
|
decNumberZero(dn); /* default result */
|
||||||
|
@ -182,7 +182,7 @@ decNumber * decPackedToNumber(const uByte *bcd, Int length,
|
||||||
/* leave as 1] */
|
/* leave as 1] */
|
||||||
|
|
||||||
/* check the adjusted exponent; note that scale could be unbounded */
|
/* check the adjusted exponent; note that scale could be unbounded */
|
||||||
dn->exponent=-*scale; /* set the exponent */
|
dn->exponent=-*scale; /* set the exponent */
|
||||||
if (*scale>=0) { /* usual case */
|
if (*scale>=0) { /* usual case */
|
||||||
if ((dn->digits-*scale-1)<-DECNUMMAXE) { /* underflow */
|
if ((dn->digits-*scale-1)<-DECNUMMAXE) { /* underflow */
|
||||||
decNumberZero(dn);
|
decNumberZero(dn);
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
#define DECPACKED
|
#define DECPACKED
|
||||||
#define DECPNAME "decPacked" /* Short name */
|
#define DECPNAME "decPacked" /* Short name */
|
||||||
#define DECPFULLNAME "Packed Decimal conversions" /* Verbose name */
|
#define DECPFULLNAME "Packed Decimal conversions" /* Verbose name */
|
||||||
#define DECPAUTHOR "Mike Cowlishaw" /* Who to blame */
|
#define DECPAUTHOR "Mike Cowlishaw" /* Who to blame */
|
||||||
|
|
||||||
#define DECPACKED_DefP 32 /* default precision */
|
#define DECPACKED_DefP 32 /* default precision */
|
||||||
|
|
||||||
|
@ -47,12 +47,12 @@
|
||||||
|
|
||||||
/* Sign nibble constants */
|
/* Sign nibble constants */
|
||||||
#if !defined(DECPPLUSALT)
|
#if !defined(DECPPLUSALT)
|
||||||
#define DECPPLUSALT 0x0A /* alternate plus nibble */
|
#define DECPPLUSALT 0x0A /* alternate plus nibble */
|
||||||
#define DECPMINUSALT 0x0B /* alternate minus nibble */
|
#define DECPMINUSALT 0x0B /* alternate minus nibble */
|
||||||
#define DECPPLUS 0x0C /* preferred plus nibble */
|
#define DECPPLUS 0x0C /* preferred plus nibble */
|
||||||
#define DECPMINUS 0x0D /* preferred minus nibble */
|
#define DECPMINUS 0x0D /* preferred minus nibble */
|
||||||
#define DECPPLUSALT2 0x0E /* alternate plus nibble */
|
#define DECPPLUSALT2 0x0E /* alternate plus nibble */
|
||||||
#define DECPUNSIGNED 0x0F /* alternate plus nibble (unsigned) */
|
#define DECPUNSIGNED 0x0F /* alternate plus nibble (unsigned) */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
|
|
|
@ -34,111 +34,111 @@
|
||||||
/* This module comprises decQuad operations (including conversions) */
|
/* This module comprises decQuad operations (including conversions) */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
|
||||||
#include "decContext.h" /* public includes */
|
#include "decContext.h" /* public includes */
|
||||||
#include "decQuad.h" /* .. */
|
#include "decQuad.h" /* .. */
|
||||||
|
|
||||||
/* Constant mappings for shared code */
|
/* Constant mappings for shared code */
|
||||||
#define DECPMAX DECQUAD_Pmax
|
#define DECPMAX DECQUAD_Pmax
|
||||||
#define DECEMIN DECQUAD_Emin
|
#define DECEMIN DECQUAD_Emin
|
||||||
#define DECEMAX DECQUAD_Emax
|
#define DECEMAX DECQUAD_Emax
|
||||||
#define DECEMAXD DECQUAD_EmaxD
|
#define DECEMAXD DECQUAD_EmaxD
|
||||||
#define DECBYTES DECQUAD_Bytes
|
#define DECBYTES DECQUAD_Bytes
|
||||||
#define DECSTRING DECQUAD_String
|
#define DECSTRING DECQUAD_String
|
||||||
#define DECECONL DECQUAD_EconL
|
#define DECECONL DECQUAD_EconL
|
||||||
#define DECBIAS DECQUAD_Bias
|
#define DECBIAS DECQUAD_Bias
|
||||||
#define DECLETS DECQUAD_Declets
|
#define DECLETS DECQUAD_Declets
|
||||||
#define DECQTINY (-DECQUAD_Bias)
|
#define DECQTINY (-DECQUAD_Bias)
|
||||||
|
|
||||||
/* Type and function mappings for shared code */
|
/* Type and function mappings for shared code */
|
||||||
#define decFloat decQuad /* Type name */
|
#define decFloat decQuad /* Type name */
|
||||||
|
|
||||||
/* Utilities and conversions (binary results, extractors, etc.) */
|
/* Utilities and conversions (binary results, extractors, etc.) */
|
||||||
#define decFloatFromBCD decQuadFromBCD
|
#define decFloatFromBCD decQuadFromBCD
|
||||||
#define decFloatFromInt32 decQuadFromInt32
|
#define decFloatFromInt32 decQuadFromInt32
|
||||||
#define decFloatFromPacked decQuadFromPacked
|
#define decFloatFromPacked decQuadFromPacked
|
||||||
#define decFloatFromString decQuadFromString
|
#define decFloatFromPackedChecked decQuadFromPackedChecked
|
||||||
#define decFloatFromUInt32 decQuadFromUInt32
|
#define decFloatFromString decQuadFromString
|
||||||
#define decFloatFromWider decQuadFromWider
|
#define decFloatFromUInt32 decQuadFromUInt32
|
||||||
#define decFloatGetCoefficient decQuadGetCoefficient
|
#define decFloatFromWider decQuadFromWider
|
||||||
#define decFloatGetExponent decQuadGetExponent
|
#define decFloatGetCoefficient decQuadGetCoefficient
|
||||||
#define decFloatSetCoefficient decQuadSetCoefficient
|
#define decFloatGetExponent decQuadGetExponent
|
||||||
#define decFloatSetExponent decQuadSetExponent
|
#define decFloatSetCoefficient decQuadSetCoefficient
|
||||||
#define decFloatShow decQuadShow
|
#define decFloatSetExponent decQuadSetExponent
|
||||||
#define decFloatToBCD decQuadToBCD
|
#define decFloatShow decQuadShow
|
||||||
#define decFloatToEngString decQuadToEngString
|
#define decFloatToBCD decQuadToBCD
|
||||||
#define decFloatToInt32 decQuadToInt32
|
#define decFloatToEngString decQuadToEngString
|
||||||
#define decFloatToInt32Exact decQuadToInt32Exact
|
#define decFloatToInt32 decQuadToInt32
|
||||||
#define decFloatToPacked decQuadToPacked
|
#define decFloatToInt32Exact decQuadToInt32Exact
|
||||||
#define decFloatToString decQuadToString
|
#define decFloatToPacked decQuadToPacked
|
||||||
#define decFloatToUInt32 decQuadToUInt32
|
#define decFloatToString decQuadToString
|
||||||
#define decFloatToUInt32Exact decQuadToUInt32Exact
|
#define decFloatToUInt32 decQuadToUInt32
|
||||||
#define decFloatToWider decQuadToWider
|
#define decFloatToUInt32Exact decQuadToUInt32Exact
|
||||||
#define decFloatZero decQuadZero
|
#define decFloatToWider decQuadToWider
|
||||||
|
#define decFloatZero decQuadZero
|
||||||
|
|
||||||
/* Computational (result is a decFloat) */
|
/* Computational (result is a decFloat) */
|
||||||
#define decFloatAbs decQuadAbs
|
#define decFloatAbs decQuadAbs
|
||||||
#define decFloatAdd decQuadAdd
|
#define decFloatAdd decQuadAdd
|
||||||
#define decFloatAnd decQuadAnd
|
#define decFloatAnd decQuadAnd
|
||||||
#define decFloatDivide decQuadDivide
|
#define decFloatDivide decQuadDivide
|
||||||
#define decFloatDivideInteger decQuadDivideInteger
|
#define decFloatDivideInteger decQuadDivideInteger
|
||||||
#define decFloatFMA decQuadFMA
|
#define decFloatFMA decQuadFMA
|
||||||
#define decFloatInvert decQuadInvert
|
#define decFloatInvert decQuadInvert
|
||||||
#define decFloatLogB decQuadLogB
|
#define decFloatLogB decQuadLogB
|
||||||
#define decFloatMax decQuadMax
|
#define decFloatMax decQuadMax
|
||||||
#define decFloatMaxMag decQuadMaxMag
|
#define decFloatMaxMag decQuadMaxMag
|
||||||
#define decFloatMin decQuadMin
|
#define decFloatMin decQuadMin
|
||||||
#define decFloatMinMag decQuadMinMag
|
#define decFloatMinMag decQuadMinMag
|
||||||
#define decFloatMinus decQuadMinus
|
#define decFloatMinus decQuadMinus
|
||||||
#define decFloatMultiply decQuadMultiply
|
#define decFloatMultiply decQuadMultiply
|
||||||
#define decFloatNextMinus decQuadNextMinus
|
#define decFloatNextMinus decQuadNextMinus
|
||||||
#define decFloatNextPlus decQuadNextPlus
|
#define decFloatNextPlus decQuadNextPlus
|
||||||
#define decFloatNextToward decQuadNextToward
|
#define decFloatNextToward decQuadNextToward
|
||||||
#define decFloatOr decQuadOr
|
#define decFloatOr decQuadOr
|
||||||
#define decFloatPlus decQuadPlus
|
#define decFloatPlus decQuadPlus
|
||||||
#define decFloatQuantize decQuadQuantize
|
#define decFloatQuantize decQuadQuantize
|
||||||
#define decFloatReduce decQuadReduce
|
#define decFloatReduce decQuadReduce
|
||||||
#define decFloatRemainder decQuadRemainder
|
#define decFloatRemainder decQuadRemainder
|
||||||
#define decFloatRemainderNear decQuadRemainderNear
|
#define decFloatRemainderNear decQuadRemainderNear
|
||||||
#define decFloatRotate decQuadRotate
|
#define decFloatRotate decQuadRotate
|
||||||
#define decFloatScaleB decQuadScaleB
|
#define decFloatScaleB decQuadScaleB
|
||||||
#define decFloatShift decQuadShift
|
#define decFloatShift decQuadShift
|
||||||
#define decFloatSubtract decQuadSubtract
|
#define decFloatSubtract decQuadSubtract
|
||||||
#define decFloatToIntegralValue decQuadToIntegralValue
|
#define decFloatToIntegralValue decQuadToIntegralValue
|
||||||
#define decFloatToIntegralExact decQuadToIntegralExact
|
#define decFloatToIntegralExact decQuadToIntegralExact
|
||||||
#define decFloatXor decQuadXor
|
#define decFloatXor decQuadXor
|
||||||
|
|
||||||
/* Comparisons */
|
/* Comparisons */
|
||||||
#define decFloatCompare decQuadCompare
|
#define decFloatCompare decQuadCompare
|
||||||
#define decFloatCompareSignal decQuadCompareSignal
|
#define decFloatCompareSignal decQuadCompareSignal
|
||||||
#define decFloatCompareTotal decQuadCompareTotal
|
#define decFloatCompareTotal decQuadCompareTotal
|
||||||
#define decFloatCompareTotalMag decQuadCompareTotalMag
|
#define decFloatCompareTotalMag decQuadCompareTotalMag
|
||||||
|
|
||||||
/* Copies */
|
/* Copies */
|
||||||
#define decFloatCanonical decQuadCanonical
|
#define decFloatCanonical decQuadCanonical
|
||||||
#define decFloatCopy decQuadCopy
|
#define decFloatCopy decQuadCopy
|
||||||
#define decFloatCopyAbs decQuadCopyAbs
|
#define decFloatCopyAbs decQuadCopyAbs
|
||||||
#define decFloatCopyNegate decQuadCopyNegate
|
#define decFloatCopyNegate decQuadCopyNegate
|
||||||
#define decFloatCopySign decQuadCopySign
|
#define decFloatCopySign decQuadCopySign
|
||||||
|
|
||||||
/* Non-computational */
|
/* Non-computational */
|
||||||
#define decFloatClass decQuadClass
|
#define decFloatClass decQuadClass
|
||||||
#define decFloatClassString decQuadClassString
|
#define decFloatClassString decQuadClassString
|
||||||
#define decFloatDigits decQuadDigits
|
#define decFloatDigits decQuadDigits
|
||||||
#define decFloatIsCanonical decQuadIsCanonical
|
#define decFloatIsCanonical decQuadIsCanonical
|
||||||
#define decFloatIsFinite decQuadIsFinite
|
#define decFloatIsFinite decQuadIsFinite
|
||||||
#define decFloatIsInfinite decQuadIsInfinite
|
#define decFloatIsInfinite decQuadIsInfinite
|
||||||
#define decFloatIsInteger decQuadIsInteger
|
#define decFloatIsInteger decQuadIsInteger
|
||||||
#define decFloatIsNaN decQuadIsNaN
|
#define decFloatIsNaN decQuadIsNaN
|
||||||
#define decFloatIsNormal decQuadIsNormal
|
#define decFloatIsNormal decQuadIsNormal
|
||||||
#define decFloatIsSignaling decQuadIsSignaling
|
#define decFloatIsSignaling decQuadIsSignaling
|
||||||
#define decFloatIsSignalling decQuadIsSignalling
|
#define decFloatIsSignalling decQuadIsSignalling
|
||||||
#define decFloatIsSigned decQuadIsSigned
|
#define decFloatIsSigned decQuadIsSigned
|
||||||
#define decFloatIsSubnormal decQuadIsSubnormal
|
#define decFloatIsSubnormal decQuadIsSubnormal
|
||||||
#define decFloatIsZero decQuadIsZero
|
#define decFloatIsZero decQuadIsZero
|
||||||
#define decFloatRadix decQuadRadix
|
#define decFloatRadix decQuadRadix
|
||||||
#define decFloatSameQuantum decQuadSameQuantum
|
#define decFloatSameQuantum decQuadSameQuantum
|
||||||
#define decFloatVersion decQuadVersion
|
#define decFloatVersion decQuadVersion
|
||||||
|
|
||||||
|
|
||||||
#include "decNumberLocal.h" /* local includes (need DECPMAX) */
|
#include "decNumberLocal.h" /* local includes (need DECPMAX) */
|
||||||
#include "decCommon.c" /* non-arithmetic decFloat routines */
|
#include "decCommon.c" /* non-arithmetic decFloat routines */
|
||||||
|
|
|
@ -31,27 +31,25 @@
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decQuad.h -- Decimal 128-bit format module header */
|
/* decQuad.h -- Decimal 128-bit format module header */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* Please see decFloats.h for an overview and documentation details. */
|
|
||||||
/* ------------------------------------------------------------------ */
|
|
||||||
/* This include file is always included by decSingle and decDouble, */
|
/* This include file is always included by decSingle and decDouble, */
|
||||||
/* and therefore also holds useful constants used by all three. */
|
/* and therefore also holds useful constants used by all three. */
|
||||||
|
|
||||||
#if !defined(DECQUAD)
|
#if !defined(DECQUAD)
|
||||||
#define DECQUAD
|
#define DECQUAD
|
||||||
|
|
||||||
#define DECQUADNAME "decimalQuad" /* Short name */
|
#define DECQUADNAME "decimalQuad" /* Short name */
|
||||||
#define DECQUADTITLE "Decimal 128-bit datum" /* Verbose name */
|
#define DECQUADTITLE "Decimal 128-bit datum" /* Verbose name */
|
||||||
#define DECQUADAUTHOR "Mike Cowlishaw" /* Who to blame */
|
#define DECQUADAUTHOR "Mike Cowlishaw" /* Who to blame */
|
||||||
|
|
||||||
/* parameters for decQuads */
|
/* parameters for decQuads */
|
||||||
#define DECQUAD_Bytes 16 /* length */
|
#define DECQUAD_Bytes 16 /* length */
|
||||||
#define DECQUAD_Pmax 34 /* maximum precision (digits) */
|
#define DECQUAD_Pmax 34 /* maximum precision (digits) */
|
||||||
#define DECQUAD_Emin -6143 /* minimum adjusted exponent */
|
#define DECQUAD_Emin -6143 /* minimum adjusted exponent */
|
||||||
#define DECQUAD_Emax 6144 /* maximum adjusted exponent */
|
#define DECQUAD_Emax 6144 /* maximum adjusted exponent */
|
||||||
#define DECQUAD_EmaxD 4 /* maximum exponent digits */
|
#define DECQUAD_EmaxD 4 /* maximum exponent digits */
|
||||||
#define DECQUAD_Bias 6176 /* bias for the exponent */
|
#define DECQUAD_Bias 6176 /* bias for the exponent */
|
||||||
#define DECQUAD_String 43 /* maximum string length, +1 */
|
#define DECQUAD_String 43 /* maximum string length, +1 */
|
||||||
#define DECQUAD_EconL 12 /* exponent continuation length */
|
#define DECQUAD_EconL 12 /* exponent continuation length */
|
||||||
#define DECQUAD_Declets 11 /* count of declets */
|
#define DECQUAD_Declets 11 /* count of declets */
|
||||||
/* highest biased exponent (Elimit-1) */
|
/* highest biased exponent (Elimit-1) */
|
||||||
#define DECQUAD_Ehigh (DECQUAD_Emax + DECQUAD_Bias - (DECQUAD_Pmax-1))
|
#define DECQUAD_Ehigh (DECQUAD_Emax + DECQUAD_Bias - (DECQUAD_Pmax-1))
|
||||||
|
@ -59,11 +57,14 @@
|
||||||
/* Required include */
|
/* Required include */
|
||||||
#include "decContext.h"
|
#include "decContext.h"
|
||||||
|
|
||||||
/* The decQuad decimal 128-bit type, accessible by various types */
|
/* The decQuad decimal 128-bit type, accessible by all sizes */
|
||||||
typedef union {
|
typedef union {
|
||||||
uint8_t bytes[DECQUAD_Bytes]; /* fields: 1, 5, 12, 110 bits */
|
uint8_t bytes[DECQUAD_Bytes]; /* fields: 1, 5, 12, 110 bits */
|
||||||
uint16_t shorts[DECQUAD_Bytes/2];
|
uint16_t shorts[DECQUAD_Bytes/2];
|
||||||
uint32_t words[DECQUAD_Bytes/4];
|
uint32_t words[DECQUAD_Bytes/4];
|
||||||
|
#if DECUSE64
|
||||||
|
uint64_t longs[DECQUAD_Bytes/8];
|
||||||
|
#endif
|
||||||
} decQuad;
|
} decQuad;
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
|
@ -72,21 +73,21 @@
|
||||||
|
|
||||||
/* sign and special values [top 32-bits; last two bits are don't-care
|
/* sign and special values [top 32-bits; last two bits are don't-care
|
||||||
for Infinity on input, last bit don't-care for NaNs] */
|
for Infinity on input, last bit don't-care for NaNs] */
|
||||||
#define DECFLOAT_Sign 0x80000000 /* 1 00000 00 Sign */
|
#define DECFLOAT_Sign 0x80000000 /* 1 00000 00 Sign */
|
||||||
#define DECFLOAT_NaN 0x7c000000 /* 0 11111 00 NaN generic */
|
#define DECFLOAT_NaN 0x7c000000 /* 0 11111 00 NaN generic */
|
||||||
#define DECFLOAT_qNaN 0x7c000000 /* 0 11111 00 qNaN */
|
#define DECFLOAT_qNaN 0x7c000000 /* 0 11111 00 qNaN */
|
||||||
#define DECFLOAT_sNaN 0x7e000000 /* 0 11111 10 sNaN */
|
#define DECFLOAT_sNaN 0x7e000000 /* 0 11111 10 sNaN */
|
||||||
#define DECFLOAT_Inf 0x78000000 /* 0 11110 00 Infinity */
|
#define DECFLOAT_Inf 0x78000000 /* 0 11110 00 Infinity */
|
||||||
#define DECFLOAT_MinSp 0x78000000 /* minimum special value */
|
#define DECFLOAT_MinSp 0x78000000 /* minimum special value */
|
||||||
/* [specials are all >=MinSp] */
|
/* [specials are all >=MinSp] */
|
||||||
/* Sign nibble constants */
|
/* Sign nibble constants */
|
||||||
#if !defined(DECPPLUSALT)
|
#if !defined(DECPPLUSALT)
|
||||||
#define DECPPLUSALT 0x0A /* alternate plus nibble */
|
#define DECPPLUSALT 0x0A /* alternate plus nibble */
|
||||||
#define DECPMINUSALT 0x0B /* alternate minus nibble */
|
#define DECPMINUSALT 0x0B /* alternate minus nibble */
|
||||||
#define DECPPLUS 0x0C /* preferred plus nibble */
|
#define DECPPLUS 0x0C /* preferred plus nibble */
|
||||||
#define DECPMINUS 0x0D /* preferred minus nibble */
|
#define DECPMINUS 0x0D /* preferred minus nibble */
|
||||||
#define DECPPLUSALT2 0x0E /* alternate plus nibble */
|
#define DECPPLUSALT2 0x0E /* alternate plus nibble */
|
||||||
#define DECPUNSIGNED 0x0F /* alternate plus nibble (unsigned) */
|
#define DECPUNSIGNED 0x0F /* alternate plus nibble (unsigned) */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
|
@ -99,6 +100,7 @@
|
||||||
extern decQuad * decQuadFromBCD(decQuad *, int32_t, const uint8_t *, int32_t);
|
extern decQuad * decQuadFromBCD(decQuad *, int32_t, const uint8_t *, int32_t);
|
||||||
extern decQuad * decQuadFromInt32(decQuad *, int32_t);
|
extern decQuad * decQuadFromInt32(decQuad *, int32_t);
|
||||||
extern decQuad * decQuadFromPacked(decQuad *, int32_t, const uint8_t *);
|
extern decQuad * decQuadFromPacked(decQuad *, int32_t, const uint8_t *);
|
||||||
|
extern decQuad * decQuadFromPackedChecked(decQuad *, int32_t, const uint8_t *);
|
||||||
extern decQuad * decQuadFromString(decQuad *, const char *, decContext *);
|
extern decQuad * decQuadFromString(decQuad *, const char *, decContext *);
|
||||||
extern decQuad * decQuadFromUInt32(decQuad *, uint32_t);
|
extern decQuad * decQuadFromUInt32(decQuad *, uint32_t);
|
||||||
extern int32_t decQuadGetCoefficient(const decQuad *, uint8_t *);
|
extern int32_t decQuadGetCoefficient(const decQuad *, uint8_t *);
|
||||||
|
@ -182,7 +184,8 @@
|
||||||
|
|
||||||
/* decNumber conversions; these are implemented as macros so as not */
|
/* decNumber conversions; these are implemented as macros so as not */
|
||||||
/* to force a dependency on decimal128 and decNumber in decQuad. */
|
/* to force a dependency on decimal128 and decNumber in decQuad. */
|
||||||
|
/* decQuadFromNumber returns a decimal128 * to avoid warnings. */
|
||||||
#define decQuadToNumber(dq, dn) decimal128ToNumber((decimal128 *)(dq), dn)
|
#define decQuadToNumber(dq, dn) decimal128ToNumber((decimal128 *)(dq), dn)
|
||||||
#define decQuadFromNumber(dq, dn, set) (decQuad *)decimal128FromNumber((decimal128 *)(dq), dn, set)
|
#define decQuadFromNumber(dq, dn, set) decimal128FromNumber((decimal128 *)(dq), dn, set)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,22 +31,20 @@
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decSingle.c -- decSingle operations module */
|
/* decSingle.c -- decSingle operations module */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* This module comprises decSingle operations (including conversions) */
|
|
||||||
/* ------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
#include "decContext.h" /* public includes */
|
#include "decContext.h" /* public includes */
|
||||||
#include "decSingle.h" /* public includes */
|
#include "decSingle.h" /* public includes */
|
||||||
|
|
||||||
/* Constant mappings for shared code */
|
/* Constant mappings for shared code */
|
||||||
#define DECPMAX DECSINGLE_Pmax
|
#define DECPMAX DECSINGLE_Pmax
|
||||||
#define DECEMIN DECSINGLE_Emin
|
#define DECEMIN DECSINGLE_Emin
|
||||||
#define DECEMAX DECSINGLE_Emax
|
#define DECEMAX DECSINGLE_Emax
|
||||||
#define DECEMAXD DECSINGLE_EmaxD
|
#define DECEMAXD DECSINGLE_EmaxD
|
||||||
#define DECBYTES DECSINGLE_Bytes
|
#define DECBYTES DECSINGLE_Bytes
|
||||||
#define DECSTRING DECSINGLE_String
|
#define DECSTRING DECSINGLE_String
|
||||||
#define DECECONL DECSINGLE_EconL
|
#define DECECONL DECSINGLE_EconL
|
||||||
#define DECBIAS DECSINGLE_Bias
|
#define DECBIAS DECSINGLE_Bias
|
||||||
#define DECLETS DECSINGLE_Declets
|
#define DECLETS DECSINGLE_Declets
|
||||||
#define DECQTINY (-DECSINGLE_Bias)
|
#define DECQTINY (-DECSINGLE_Bias)
|
||||||
/* parameters of next-wider format */
|
/* parameters of next-wider format */
|
||||||
#define DECWBYTES DECDOUBLE_Bytes
|
#define DECWBYTES DECDOUBLE_Bytes
|
||||||
|
@ -55,29 +53,30 @@
|
||||||
#define DECWBIAS DECDOUBLE_Bias
|
#define DECWBIAS DECDOUBLE_Bias
|
||||||
|
|
||||||
/* Type and function mappings for shared code */
|
/* Type and function mappings for shared code */
|
||||||
#define decFloat decSingle /* Type name */
|
#define decFloat decSingle /* Type name */
|
||||||
#define decFloatWider decDouble /* Type name */
|
#define decFloatWider decDouble /* Type name */
|
||||||
|
|
||||||
/* Utility (binary results, extractors, etc.) */
|
/* Utility (binary results, extractors, etc.) */
|
||||||
#define decFloatFromBCD decSingleFromBCD
|
#define decFloatFromBCD decSingleFromBCD
|
||||||
#define decFloatFromPacked decSingleFromPacked
|
#define decFloatFromPacked decSingleFromPacked
|
||||||
#define decFloatFromString decSingleFromString
|
#define decFloatFromPackedChecked decSingleFromPackedChecked
|
||||||
#define decFloatFromWider decSingleFromWider
|
#define decFloatFromString decSingleFromString
|
||||||
#define decFloatGetCoefficient decSingleGetCoefficient
|
#define decFloatFromWider decSingleFromWider
|
||||||
#define decFloatGetExponent decSingleGetExponent
|
#define decFloatGetCoefficient decSingleGetCoefficient
|
||||||
#define decFloatSetCoefficient decSingleSetCoefficient
|
#define decFloatGetExponent decSingleGetExponent
|
||||||
#define decFloatSetExponent decSingleSetExponent
|
#define decFloatSetCoefficient decSingleSetCoefficient
|
||||||
#define decFloatShow decSingleShow
|
#define decFloatSetExponent decSingleSetExponent
|
||||||
#define decFloatToBCD decSingleToBCD
|
#define decFloatShow decSingleShow
|
||||||
#define decFloatToEngString decSingleToEngString
|
#define decFloatToBCD decSingleToBCD
|
||||||
#define decFloatToPacked decSingleToPacked
|
#define decFloatToEngString decSingleToEngString
|
||||||
#define decFloatToString decSingleToString
|
#define decFloatToPacked decSingleToPacked
|
||||||
#define decFloatToWider decSingleToWider
|
#define decFloatToString decSingleToString
|
||||||
#define decFloatZero decSingleZero
|
#define decFloatToWider decSingleToWider
|
||||||
|
#define decFloatZero decSingleZero
|
||||||
|
|
||||||
/* Non-computational */
|
/* Non-computational */
|
||||||
#define decFloatRadix decSingleRadix
|
#define decFloatRadix decSingleRadix
|
||||||
#define decFloatVersion decSingleVersion
|
#define decFloatVersion decSingleVersion
|
||||||
|
|
||||||
#include "decNumberLocal.h" /* local includes (need DECPMAX) */
|
#include "decNumberLocal.h" /* local includes (need DECPMAX) */
|
||||||
#include "decCommon.c" /* non-basic decFloat routines */
|
#include "decCommon.c" /* non-basic decFloat routines */
|
||||||
|
|
|
@ -31,24 +31,22 @@
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decSingle.h -- Decimal 32-bit format module header */
|
/* decSingle.h -- Decimal 32-bit format module header */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* Please see decFloats.h for an overview and documentation details. */
|
|
||||||
/* ------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
#if !defined(DECSINGLE)
|
#if !defined(DECSINGLE)
|
||||||
#define DECSINGLE
|
#define DECSINGLE
|
||||||
|
|
||||||
#define DECSINGLENAME "decSingle" /* Short name */
|
#define DECSINGLENAME "decSingle" /* Short name */
|
||||||
#define DECSINGLETITLE "Decimal 32-bit datum" /* Verbose name */
|
#define DECSINGLETITLE "Decimal 32-bit datum" /* Verbose name */
|
||||||
#define DECSINGLEAUTHOR "Mike Cowlishaw" /* Who to blame */
|
#define DECSINGLEAUTHOR "Mike Cowlishaw" /* Who to blame */
|
||||||
|
|
||||||
/* parameters for decSingles */
|
/* parameters for decSingles */
|
||||||
#define DECSINGLE_Bytes 4 /* length */
|
#define DECSINGLE_Bytes 4 /* length */
|
||||||
#define DECSINGLE_Pmax 7 /* maximum precision (digits) */
|
#define DECSINGLE_Pmax 7 /* maximum precision (digits) */
|
||||||
#define DECSINGLE_Emin -95 /* minimum adjusted exponent */
|
#define DECSINGLE_Emin -95 /* minimum adjusted exponent */
|
||||||
#define DECSINGLE_Emax 96 /* maximum adjusted exponent */
|
#define DECSINGLE_Emax 96 /* maximum adjusted exponent */
|
||||||
#define DECSINGLE_EmaxD 3 /* maximum exponent digits */
|
#define DECSINGLE_EmaxD 3 /* maximum exponent digits */
|
||||||
#define DECSINGLE_Bias 101 /* bias for the exponent */
|
#define DECSINGLE_Bias 101 /* bias for the exponent */
|
||||||
#define DECSINGLE_String 16 /* maximum string length, +1 */
|
#define DECSINGLE_String 16 /* maximum string length, +1 */
|
||||||
#define DECSINGLE_EconL 6 /* exponent continuation length */
|
#define DECSINGLE_EconL 6 /* exponent continuation length */
|
||||||
#define DECSINGLE_Declets 2 /* count of declets */
|
#define DECSINGLE_Declets 2 /* count of declets */
|
||||||
/* highest biased exponent (Elimit-1) */
|
/* highest biased exponent (Elimit-1) */
|
||||||
|
@ -59,11 +57,11 @@
|
||||||
#include "decQuad.h"
|
#include "decQuad.h"
|
||||||
#include "decDouble.h"
|
#include "decDouble.h"
|
||||||
|
|
||||||
/* The decSingle decimal 32-bit type, accessible by various types */
|
/* The decSingle decimal 32-bit type, accessible by all sizes */
|
||||||
typedef union {
|
typedef union {
|
||||||
uint8_t bytes[DECSINGLE_Bytes]; /* fields: 1, 5, 6, 20 bits */
|
uint8_t bytes[DECSINGLE_Bytes]; /* fields: 1, 5, 6, 20 bits */
|
||||||
uint16_t shorts[DECSINGLE_Bytes/2];
|
uint16_t shorts[DECSINGLE_Bytes/2];
|
||||||
uint32_t words[DECSINGLE_Bytes/4];
|
uint32_t words[DECSINGLE_Bytes/4];
|
||||||
} decSingle;
|
} decSingle;
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
|
@ -75,6 +73,7 @@
|
||||||
/* Utilities (binary argument(s) or result, extractors, etc.) */
|
/* Utilities (binary argument(s) or result, extractors, etc.) */
|
||||||
extern decSingle * decSingleFromBCD(decSingle *, int32_t, const uint8_t *, int32_t);
|
extern decSingle * decSingleFromBCD(decSingle *, int32_t, const uint8_t *, int32_t);
|
||||||
extern decSingle * decSingleFromPacked(decSingle *, int32_t, const uint8_t *);
|
extern decSingle * decSingleFromPacked(decSingle *, int32_t, const uint8_t *);
|
||||||
|
extern decSingle * decSingleFromPackedChecked(decSingle *, int32_t, const uint8_t *);
|
||||||
extern decSingle * decSingleFromString(decSingle *, const char *, decContext *);
|
extern decSingle * decSingleFromString(decSingle *, const char *, decContext *);
|
||||||
extern decSingle * decSingleFromWider(decSingle *, const decDouble *, decContext *);
|
extern decSingle * decSingleFromWider(decSingle *, const decDouble *, decContext *);
|
||||||
extern int32_t decSingleGetCoefficient(const decSingle *, uint8_t *);
|
extern int32_t decSingleGetCoefficient(const decSingle *, uint8_t *);
|
||||||
|
@ -97,7 +96,8 @@
|
||||||
|
|
||||||
/* decNumber conversions; these are implemented as macros so as not */
|
/* decNumber conversions; these are implemented as macros so as not */
|
||||||
/* to force a dependency on decimal32 and decNumber in decSingle. */
|
/* to force a dependency on decimal32 and decNumber in decSingle. */
|
||||||
|
/* decSingleFromNumber returns a decimal32 * to avoid warnings. */
|
||||||
#define decSingleToNumber(dq, dn) decimal32ToNumber((decimal32 *)(dq), dn)
|
#define decSingleToNumber(dq, dn) decimal32ToNumber((decimal32 *)(dq), dn)
|
||||||
#define decSingleFromNumber(dq, dn, set) (decSingle *)decimal32FromNumber((decimal32 *)(dq), dn, set)
|
#define decSingleFromNumber(dq, dn, set) decimal32FromNumber((decimal32 *)(dq), dn, set)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -42,11 +42,11 @@
|
||||||
#include <string.h> /* [for memset/memcpy] */
|
#include <string.h> /* [for memset/memcpy] */
|
||||||
#include <stdio.h> /* [for printf] */
|
#include <stdio.h> /* [for printf] */
|
||||||
|
|
||||||
#include "dconfig.h" /* GCC definitions */
|
#include "dconfig.h" /* GCC definitions */
|
||||||
#define DECNUMDIGITS 34 /* make decNumbers with space for 34 */
|
#define DECNUMDIGITS 34 /* make decNumbers with space for 34 */
|
||||||
#include "decNumber.h" /* base number library */
|
#include "decNumber.h" /* base number library */
|
||||||
#include "decNumberLocal.h" /* decNumber local types, etc. */
|
#include "decNumberLocal.h" /* decNumber local types, etc. */
|
||||||
#include "decimal128.h" /* our primary include */
|
#include "decimal128.h" /* our primary include */
|
||||||
|
|
||||||
/* Utility routines and tables [in decimal64.c] */
|
/* Utility routines and tables [in decimal64.c] */
|
||||||
extern const uInt COMBEXP[32], COMBMSD[32];
|
extern const uInt COMBEXP[32], COMBMSD[32];
|
||||||
|
@ -71,7 +71,7 @@ extern void decNumberShow(const decNumber *); /* .. */
|
||||||
/* */
|
/* */
|
||||||
/* ds is the target decimal128 */
|
/* ds is the target decimal128 */
|
||||||
/* dn is the source number (assumed valid) */
|
/* dn is the source number (assumed valid) */
|
||||||
/* set is the context, used only for reporting errors */
|
/* set is the context, used only for reporting errors */
|
||||||
/* */
|
/* */
|
||||||
/* The set argument is used only for status reporting and for the */
|
/* The set argument is used only for status reporting and for the */
|
||||||
/* rounding mode (used if the coefficient is more than DECIMAL128_Pmax*/
|
/* rounding mode (used if the coefficient is more than DECIMAL128_Pmax*/
|
||||||
|
@ -89,8 +89,8 @@ decimal128 * decimal128FromNumber(decimal128 *d128, const decNumber *dn,
|
||||||
Int ae; /* adjusted exponent */
|
Int ae; /* adjusted exponent */
|
||||||
decNumber dw; /* work */
|
decNumber dw; /* work */
|
||||||
decContext dc; /* .. */
|
decContext dc; /* .. */
|
||||||
uInt *pu; /* .. */
|
|
||||||
uInt comb, exp; /* .. */
|
uInt comb, exp; /* .. */
|
||||||
|
uInt uiwork; /* for macros */
|
||||||
uInt targar[4]={0,0,0,0}; /* target 128-bit */
|
uInt targar[4]={0,0,0,0}; /* target 128-bit */
|
||||||
#define targhi targar[3] /* name the word with the sign */
|
#define targhi targar[3] /* name the word with the sign */
|
||||||
#define targmh targar[2] /* name the words */
|
#define targmh targar[2] /* name the words */
|
||||||
|
@ -102,7 +102,7 @@ decimal128 * decimal128FromNumber(decimal128 *d128, const decNumber *dn,
|
||||||
/* constraints. This could push the number to Infinity or zero, */
|
/* constraints. This could push the number to Infinity or zero, */
|
||||||
/* so this check and rounding must be done before generating the */
|
/* so this check and rounding must be done before generating the */
|
||||||
/* decimal128] */
|
/* decimal128] */
|
||||||
ae=dn->exponent+dn->digits-1; /* [0 if special] */
|
ae=dn->exponent+dn->digits-1; /* [0 if special] */
|
||||||
if (dn->digits>DECIMAL128_Pmax /* too many digits */
|
if (dn->digits>DECIMAL128_Pmax /* too many digits */
|
||||||
|| ae>DECIMAL128_Emax /* likely overflow */
|
|| ae>DECIMAL128_Emax /* likely overflow */
|
||||||
|| ae<DECIMAL128_Emin) { /* likely underflow */
|
|| ae<DECIMAL128_Emin) { /* likely underflow */
|
||||||
|
@ -118,7 +118,7 @@ decimal128 * decimal128FromNumber(decimal128 *d128, const decNumber *dn,
|
||||||
if (dn->bits&DECSPECIAL) { /* a special value */
|
if (dn->bits&DECSPECIAL) { /* a special value */
|
||||||
if (dn->bits&DECINF) targhi=DECIMAL_Inf<<24;
|
if (dn->bits&DECINF) targhi=DECIMAL_Inf<<24;
|
||||||
else { /* sNaN or qNaN */
|
else { /* sNaN or qNaN */
|
||||||
if ((*dn->lsu!=0 || dn->digits>1) /* non-zero coefficient */
|
if ((*dn->lsu!=0 || dn->digits>1) /* non-zero coefficient */
|
||||||
&& (dn->digits<DECIMAL128_Pmax)) { /* coefficient fits */
|
&& (dn->digits<DECIMAL128_Pmax)) { /* coefficient fits */
|
||||||
decDigitsToDPD(dn, targar, 0);
|
decDigitsToDPD(dn, targar, 0);
|
||||||
}
|
}
|
||||||
|
@ -144,11 +144,11 @@ decimal128 * decimal128FromNumber(decimal128 *d128, const decNumber *dn,
|
||||||
comb=(exp>>9) & 0x18; /* msd=0, exp top 2 bits .. */
|
comb=(exp>>9) & 0x18; /* msd=0, exp top 2 bits .. */
|
||||||
}
|
}
|
||||||
else { /* non-zero finite number */
|
else { /* non-zero finite number */
|
||||||
uInt msd; /* work */
|
uInt msd; /* work */
|
||||||
Int pad=0; /* coefficient pad digits */
|
Int pad=0; /* coefficient pad digits */
|
||||||
|
|
||||||
/* the dn is known to fit, but it may need to be padded */
|
/* the dn is known to fit, but it may need to be padded */
|
||||||
exp=(uInt)(dn->exponent+DECIMAL128_Bias); /* bias exponent */
|
exp=(uInt)(dn->exponent+DECIMAL128_Bias); /* bias exponent */
|
||||||
if (exp>DECIMAL128_Ehigh) { /* fold-down case */
|
if (exp>DECIMAL128_Ehigh) { /* fold-down case */
|
||||||
pad=exp-DECIMAL128_Ehigh;
|
pad=exp-DECIMAL128_Ehigh;
|
||||||
exp=DECIMAL128_Ehigh; /* [to maximum] */
|
exp=DECIMAL128_Ehigh; /* [to maximum] */
|
||||||
|
@ -172,18 +172,19 @@ decimal128 * decimal128FromNumber(decimal128 *d128, const decNumber *dn,
|
||||||
if (dn->bits&DECNEG) targhi|=0x80000000; /* add sign bit */
|
if (dn->bits&DECNEG) targhi|=0x80000000; /* add sign bit */
|
||||||
|
|
||||||
/* now write to storage; this is endian */
|
/* now write to storage; this is endian */
|
||||||
pu=(uInt *)d128->bytes; /* overlay */
|
|
||||||
if (DECLITEND) {
|
if (DECLITEND) {
|
||||||
pu[0]=targlo; /* directly store the low int */
|
/* lo -> hi */
|
||||||
pu[1]=targml; /* then the mid-low */
|
UBFROMUI(d128->bytes, targlo);
|
||||||
pu[2]=targmh; /* then the mid-high */
|
UBFROMUI(d128->bytes+4, targml);
|
||||||
pu[3]=targhi; /* then the high int */
|
UBFROMUI(d128->bytes+8, targmh);
|
||||||
|
UBFROMUI(d128->bytes+12, targhi);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pu[0]=targhi; /* directly store the high int */
|
/* hi -> lo */
|
||||||
pu[1]=targmh; /* then the mid-high */
|
UBFROMUI(d128->bytes, targhi);
|
||||||
pu[2]=targml; /* then the mid-low */
|
UBFROMUI(d128->bytes+4, targmh);
|
||||||
pu[3]=targlo; /* then the low int */
|
UBFROMUI(d128->bytes+8, targml);
|
||||||
|
UBFROMUI(d128->bytes+12, targlo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status!=0) decContextSetStatus(set, status); /* pass on status */
|
if (status!=0) decContextSetStatus(set, status); /* pass on status */
|
||||||
|
@ -201,8 +202,8 @@ decNumber * decimal128ToNumber(const decimal128 *d128, decNumber *dn) {
|
||||||
uInt msd; /* coefficient MSD */
|
uInt msd; /* coefficient MSD */
|
||||||
uInt exp; /* exponent top two bits */
|
uInt exp; /* exponent top two bits */
|
||||||
uInt comb; /* combination field */
|
uInt comb; /* combination field */
|
||||||
const uInt *pu; /* work */
|
Int need; /* work */
|
||||||
Int need; /* .. */
|
uInt uiwork; /* for macros */
|
||||||
uInt sourar[4]; /* source 128-bit */
|
uInt sourar[4]; /* source 128-bit */
|
||||||
#define sourhi sourar[3] /* name the word with the sign */
|
#define sourhi sourar[3] /* name the word with the sign */
|
||||||
#define sourmh sourar[2] /* and the mid-high word */
|
#define sourmh sourar[2] /* and the mid-high word */
|
||||||
|
@ -210,18 +211,17 @@ decNumber * decimal128ToNumber(const decimal128 *d128, decNumber *dn) {
|
||||||
#define sourlo sourar[0] /* and the lowest word */
|
#define sourlo sourar[0] /* and the lowest word */
|
||||||
|
|
||||||
/* load source from storage; this is endian */
|
/* load source from storage; this is endian */
|
||||||
pu=(const uInt *)d128->bytes; /* overlay */
|
|
||||||
if (DECLITEND) {
|
if (DECLITEND) {
|
||||||
sourlo=pu[0]; /* directly load the low int */
|
sourlo=UBTOUI(d128->bytes ); /* directly load the low int */
|
||||||
sourml=pu[1]; /* then the mid-low */
|
sourml=UBTOUI(d128->bytes+4 ); /* then the mid-low */
|
||||||
sourmh=pu[2]; /* then the mid-high */
|
sourmh=UBTOUI(d128->bytes+8 ); /* then the mid-high */
|
||||||
sourhi=pu[3]; /* then the high int */
|
sourhi=UBTOUI(d128->bytes+12); /* then the high int */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sourhi=pu[0]; /* directly load the high int */
|
sourhi=UBTOUI(d128->bytes ); /* directly load the high int */
|
||||||
sourmh=pu[1]; /* then the mid-high */
|
sourmh=UBTOUI(d128->bytes+4 ); /* then the mid-high */
|
||||||
sourml=pu[2]; /* then the mid-low */
|
sourml=UBTOUI(d128->bytes+8 ); /* then the mid-low */
|
||||||
sourlo=pu[3]; /* then the low int */
|
sourlo=UBTOUI(d128->bytes+12); /* then the low int */
|
||||||
}
|
}
|
||||||
|
|
||||||
comb=(sourhi>>26)&0x1f; /* combination field */
|
comb=(sourhi>>26)&0x1f; /* combination field */
|
||||||
|
@ -232,7 +232,7 @@ decNumber * decimal128ToNumber(const decimal128 *d128, decNumber *dn) {
|
||||||
msd=COMBMSD[comb]; /* decode the combination field */
|
msd=COMBMSD[comb]; /* decode the combination field */
|
||||||
exp=COMBEXP[comb]; /* .. */
|
exp=COMBEXP[comb]; /* .. */
|
||||||
|
|
||||||
if (exp==3) { /* is a special */
|
if (exp==3) { /* is a special */
|
||||||
if (msd==0) {
|
if (msd==0) {
|
||||||
dn->bits|=DECINF;
|
dn->bits|=DECINF;
|
||||||
return dn; /* no coefficient needed */
|
return dn; /* no coefficient needed */
|
||||||
|
@ -265,7 +265,7 @@ decNumber * decimal128ToNumber(const decimal128 *d128, decNumber *dn) {
|
||||||
} /* decimal128ToNumber */
|
} /* decimal128ToNumber */
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* to-scientific-string -- conversion to numeric string */
|
/* to-scientific-string -- conversion to numeric string */
|
||||||
/* to-engineering-string -- conversion to numeric string */
|
/* to-engineering-string -- conversion to numeric string */
|
||||||
/* */
|
/* */
|
||||||
/* decimal128ToString(d128, string); */
|
/* decimal128ToString(d128, string); */
|
||||||
|
@ -279,7 +279,7 @@ decNumber * decimal128ToNumber(const decimal128 *d128, decNumber *dn) {
|
||||||
/* No error is possible, and no status can be set. */
|
/* No error is possible, and no status can be set. */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
char * decimal128ToEngString(const decimal128 *d128, char *string){
|
char * decimal128ToEngString(const decimal128 *d128, char *string){
|
||||||
decNumber dn; /* work */
|
decNumber dn; /* work */
|
||||||
decimal128ToNumber(d128, &dn);
|
decimal128ToNumber(d128, &dn);
|
||||||
decNumberToEngString(&dn, string);
|
decNumberToEngString(&dn, string);
|
||||||
return string;
|
return string;
|
||||||
|
@ -289,13 +289,13 @@ char * decimal128ToString(const decimal128 *d128, char *string){
|
||||||
uInt msd; /* coefficient MSD */
|
uInt msd; /* coefficient MSD */
|
||||||
Int exp; /* exponent top two bits or full */
|
Int exp; /* exponent top two bits or full */
|
||||||
uInt comb; /* combination field */
|
uInt comb; /* combination field */
|
||||||
char *cstart; /* coefficient start */
|
char *cstart; /* coefficient start */
|
||||||
char *c; /* output pointer in string */
|
char *c; /* output pointer in string */
|
||||||
const uInt *pu; /* work */
|
const uByte *u; /* work */
|
||||||
char *s, *t; /* .. (source, target) */
|
char *s, *t; /* .. (source, target) */
|
||||||
Int dpd; /* .. */
|
Int dpd; /* .. */
|
||||||
Int pre, e; /* .. */
|
Int pre, e; /* .. */
|
||||||
const uByte *u; /* .. */
|
uInt uiwork; /* for macros */
|
||||||
|
|
||||||
uInt sourar[4]; /* source 128-bit */
|
uInt sourar[4]; /* source 128-bit */
|
||||||
#define sourhi sourar[3] /* name the word with the sign */
|
#define sourhi sourar[3] /* name the word with the sign */
|
||||||
|
@ -304,18 +304,17 @@ char * decimal128ToString(const decimal128 *d128, char *string){
|
||||||
#define sourlo sourar[0] /* and the lowest word */
|
#define sourlo sourar[0] /* and the lowest word */
|
||||||
|
|
||||||
/* load source from storage; this is endian */
|
/* load source from storage; this is endian */
|
||||||
pu=(const uInt *)d128->bytes; /* overlay */
|
|
||||||
if (DECLITEND) {
|
if (DECLITEND) {
|
||||||
sourlo=pu[0]; /* directly load the low int */
|
sourlo=UBTOUI(d128->bytes ); /* directly load the low int */
|
||||||
sourml=pu[1]; /* then the mid-low */
|
sourml=UBTOUI(d128->bytes+4 ); /* then the mid-low */
|
||||||
sourmh=pu[2]; /* then the mid-high */
|
sourmh=UBTOUI(d128->bytes+8 ); /* then the mid-high */
|
||||||
sourhi=pu[3]; /* then the high int */
|
sourhi=UBTOUI(d128->bytes+12); /* then the high int */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sourhi=pu[0]; /* directly load the high int */
|
sourhi=UBTOUI(d128->bytes ); /* directly load the high int */
|
||||||
sourmh=pu[1]; /* then the mid-high */
|
sourmh=UBTOUI(d128->bytes+4 ); /* then the mid-high */
|
||||||
sourml=pu[2]; /* then the mid-low */
|
sourml=UBTOUI(d128->bytes+8 ); /* then the mid-low */
|
||||||
sourlo=pu[3]; /* then the low int */
|
sourlo=UBTOUI(d128->bytes+12); /* then the low int */
|
||||||
}
|
}
|
||||||
|
|
||||||
c=string; /* where result will go */
|
c=string; /* where result will go */
|
||||||
|
@ -327,7 +326,7 @@ char * decimal128ToString(const decimal128 *d128, char *string){
|
||||||
|
|
||||||
if (exp==3) {
|
if (exp==3) {
|
||||||
if (msd==0) { /* infinity */
|
if (msd==0) { /* infinity */
|
||||||
strcpy(c, "Inf");
|
strcpy(c, "Inf");
|
||||||
strcpy(c+3, "inity");
|
strcpy(c+3, "inity");
|
||||||
return string; /* easy */
|
return string; /* easy */
|
||||||
}
|
}
|
||||||
|
@ -353,12 +352,12 @@ char * decimal128ToString(const decimal128 *d128, char *string){
|
||||||
/* length. We use fixed-length memcpys because variable-length */
|
/* length. We use fixed-length memcpys because variable-length */
|
||||||
/* causes a subroutine call in GCC. (These are length 4 for speed */
|
/* causes a subroutine call in GCC. (These are length 4 for speed */
|
||||||
/* and are safe because the array has an extra terminator byte.) */
|
/* and are safe because the array has an extra terminator byte.) */
|
||||||
#define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; \
|
#define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; \
|
||||||
if (c!=cstart) {memcpy(c, u+1, 4); c+=3;} \
|
if (c!=cstart) {memcpy(c, u+1, 4); c+=3;} \
|
||||||
else if (*u) {memcpy(c, u+4-*u, 4); c+=*u;}
|
else if (*u) {memcpy(c, u+4-*u, 4); c+=*u;}
|
||||||
dpd=(sourhi>>4)&0x3ff; /* declet 1 */
|
dpd=(sourhi>>4)&0x3ff; /* declet 1 */
|
||||||
dpd2char;
|
dpd2char;
|
||||||
dpd=((sourhi&0xf)<<6) | (sourmh>>26); /* declet 2 */
|
dpd=((sourhi&0xf)<<6) | (sourmh>>26); /* declet 2 */
|
||||||
dpd2char;
|
dpd2char;
|
||||||
dpd=(sourmh>>16)&0x3ff; /* declet 3 */
|
dpd=(sourmh>>16)&0x3ff; /* declet 3 */
|
||||||
dpd2char;
|
dpd2char;
|
||||||
|
@ -381,7 +380,7 @@ char * decimal128ToString(const decimal128 *d128, char *string){
|
||||||
|
|
||||||
if (c==cstart) *c++='0'; /* all zeros -- make 0 */
|
if (c==cstart) *c++='0'; /* all zeros -- make 0 */
|
||||||
|
|
||||||
if (exp==0) { /* integer or NaN case -- easy */
|
if (exp==0) { /* integer or NaN case -- easy */
|
||||||
*c='\0'; /* terminate */
|
*c='\0'; /* terminate */
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
@ -409,8 +408,8 @@ char * decimal128ToString(const decimal128 *d128, char *string){
|
||||||
/* finally add the E-part, if needed; it will never be 0, and has */
|
/* finally add the E-part, if needed; it will never be 0, and has */
|
||||||
/* a maximum length of 4 digits */
|
/* a maximum length of 4 digits */
|
||||||
if (e!=0) {
|
if (e!=0) {
|
||||||
*c++='E'; /* starts with E */
|
*c++='E'; /* starts with E */
|
||||||
*c++='+'; /* assume positive */
|
*c++='+'; /* assume positive */
|
||||||
if (e<0) {
|
if (e<0) {
|
||||||
*(c-1)='-'; /* oops, need '-' */
|
*(c-1)='-'; /* oops, need '-' */
|
||||||
e=-e; /* uInt, please */
|
e=-e; /* uInt, please */
|
||||||
|
@ -449,13 +448,13 @@ char * decimal128ToString(const decimal128 *d128, char *string){
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* to-number -- conversion from numeric string */
|
/* to-number -- conversion from numeric string */
|
||||||
/* */
|
/* */
|
||||||
/* decimal128FromString(result, string, set); */
|
/* decimal128FromString(result, string, set); */
|
||||||
/* */
|
/* */
|
||||||
/* result is the decimal128 format number which gets the result of */
|
/* result is the decimal128 format number which gets the result of */
|
||||||
/* the conversion */
|
/* the conversion */
|
||||||
/* *string is the character string which should contain a valid */
|
/* *string is the character string which should contain a valid */
|
||||||
/* number (which may be a special value) */
|
/* number (which may be a special value) */
|
||||||
/* set is the context */
|
/* set is the context */
|
||||||
/* */
|
/* */
|
||||||
/* The context is supplied to this routine is used for error handling */
|
/* The context is supplied to this routine is used for error handling */
|
||||||
/* (setting of status and traps) and for the rounding mode, only. */
|
/* (setting of status and traps) and for the rounding mode, only. */
|
||||||
|
@ -464,7 +463,7 @@ char * decimal128ToString(const decimal128 *d128, char *string){
|
||||||
decimal128 * decimal128FromString(decimal128 *result, const char *string,
|
decimal128 * decimal128FromString(decimal128 *result, const char *string,
|
||||||
decContext *set) {
|
decContext *set) {
|
||||||
decContext dc; /* work */
|
decContext dc; /* work */
|
||||||
decNumber dn; /* .. */
|
decNumber dn; /* .. */
|
||||||
|
|
||||||
decContextDefault(&dc, DEC_INIT_DECIMAL128); /* no traps, please */
|
decContextDefault(&dc, DEC_INIT_DECIMAL128); /* no traps, please */
|
||||||
dc.round=set->round; /* use supplied rounding */
|
dc.round=set->round; /* use supplied rounding */
|
||||||
|
@ -483,8 +482,8 @@ decimal128 * decimal128FromString(decimal128 *result, const char *string,
|
||||||
/* returns 1 if the encoding of d128 is canonical, 0 otherwise */
|
/* returns 1 if the encoding of d128 is canonical, 0 otherwise */
|
||||||
/* No error is possible. */
|
/* No error is possible. */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
uint32_t decimal128IsCanonical(const decimal128 *d128) {
|
uInt decimal128IsCanonical(const decimal128 *d128) {
|
||||||
decNumber dn; /* work */
|
decNumber dn; /* work */
|
||||||
decimal128 canon; /* .. */
|
decimal128 canon; /* .. */
|
||||||
decContext dc; /* .. */
|
decContext dc; /* .. */
|
||||||
decContextDefault(&dc, DEC_INIT_DECIMAL128);
|
decContextDefault(&dc, DEC_INIT_DECIMAL128);
|
||||||
|
@ -501,7 +500,7 @@ uint32_t decimal128IsCanonical(const decimal128 *d128) {
|
||||||
/* No error is possible. */
|
/* No error is possible. */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
decimal128 * decimal128Canonical(decimal128 *result, const decimal128 *d128) {
|
decimal128 * decimal128Canonical(decimal128 *result, const decimal128 *d128) {
|
||||||
decNumber dn; /* work */
|
decNumber dn; /* work */
|
||||||
decContext dc; /* .. */
|
decContext dc; /* .. */
|
||||||
decContextDefault(&dc, DEC_INIT_DECIMAL128);
|
decContextDefault(&dc, DEC_INIT_DECIMAL128);
|
||||||
decimal128ToNumber(d128, &dn);
|
decimal128ToNumber(d128, &dn);
|
||||||
|
@ -532,13 +531,13 @@ decimal128 * decimal128Canonical(decimal128 *result, const decimal128 *d128) {
|
||||||
/* This assumes range has been checked and exponent previously 0; */
|
/* This assumes range has been checked and exponent previously 0; */
|
||||||
/* type of exponent must be unsigned */
|
/* type of exponent must be unsigned */
|
||||||
#define decimal128SetExpCon(d, e) { \
|
#define decimal128SetExpCon(d, e) { \
|
||||||
(d)->bytes[0]|=(uint8_t)((e)>>10); \
|
(d)->bytes[0]|=(uByte)((e)>>10); \
|
||||||
(d)->bytes[1] =(uint8_t)(((e)&0x3fc)>>2); \
|
(d)->bytes[1] =(uByte)(((e)&0x3fc)>>2); \
|
||||||
(d)->bytes[2]|=(uint8_t)(((e)&0x03)<<6);}
|
(d)->bytes[2]|=(uByte)(((e)&0x03)<<6);}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decimal128Show -- display a decimal128 in hexadecimal [debug aid] */
|
/* decimal128Show -- display a decimal128 in hexadecimal [debug aid] */
|
||||||
/* d128 -- the number to show */
|
/* d128 -- the number to show */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* Also shows sign/cob/expconfields extracted */
|
/* Also shows sign/cob/expconfields extracted */
|
||||||
void decimal128Show(const decimal128 *d128) {
|
void decimal128Show(const decimal128 *d128) {
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
02110-1301, USA. */
|
02110-1301, USA. */
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* Decimal 128-bit format module header */
|
/* Decimal 128-bit format module header */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
|
||||||
#if !defined(DECIMAL128)
|
#if !defined(DECIMAL128)
|
||||||
|
@ -46,7 +46,7 @@
|
||||||
#define DECIMAL128_Bias 6176 /* bias for the exponent */
|
#define DECIMAL128_Bias 6176 /* bias for the exponent */
|
||||||
#define DECIMAL128_String 43 /* maximum string length, +1 */
|
#define DECIMAL128_String 43 /* maximum string length, +1 */
|
||||||
#define DECIMAL128_EconL 12 /* exp. continuation length */
|
#define DECIMAL128_EconL 12 /* exp. continuation length */
|
||||||
/* highest biased exponent (Elimit-1) */
|
/* highest biased exponent (Elimit-1) */
|
||||||
#define DECIMAL128_Ehigh (DECIMAL128_Emax+DECIMAL128_Bias-DECIMAL128_Pmax+1)
|
#define DECIMAL128_Ehigh (DECIMAL128_Emax+DECIMAL128_Bias-DECIMAL128_Pmax+1)
|
||||||
|
|
||||||
/* check enough digits, if pre-defined */
|
/* check enough digits, if pre-defined */
|
||||||
|
@ -71,20 +71,20 @@
|
||||||
/* special values [top byte excluding sign bit; last two bits are */
|
/* special values [top byte excluding sign bit; last two bits are */
|
||||||
/* don't-care for Infinity on input, last bit don't-care for NaN] */
|
/* don't-care for Infinity on input, last bit don't-care for NaN] */
|
||||||
#if !defined(DECIMAL_NaN)
|
#if !defined(DECIMAL_NaN)
|
||||||
#define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */
|
#define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */
|
||||||
#define DECIMAL_sNaN 0x7e /* 0 11111 10 sNaN */
|
#define DECIMAL_sNaN 0x7e /* 0 11111 10 sNaN */
|
||||||
#define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */
|
#define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "decimal128Local.h"
|
#include "decimal128Local.h"
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
/* Routines */
|
/* Routines */
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
#include "decimal128Symbols.h"
|
#include "decimal128Symbols.h"
|
||||||
|
|
||||||
/* String conversions */
|
/* String conversions */
|
||||||
decimal128 * decimal128FromString(decimal128 *, const char *, decContext *);
|
decimal128 * decimal128FromString(decimal128 *, const char *, decContext *);
|
||||||
char * decimal128ToString(const decimal128 *, char *);
|
char * decimal128ToString(const decimal128 *, char *);
|
||||||
char * decimal128ToEngString(const decimal128 *, char *);
|
char * decimal128ToEngString(const decimal128 *, char *);
|
||||||
|
@ -94,7 +94,7 @@
|
||||||
decContext *);
|
decContext *);
|
||||||
decNumber * decimal128ToNumber(const decimal128 *, decNumber *);
|
decNumber * decimal128ToNumber(const decimal128 *, decNumber *);
|
||||||
|
|
||||||
/* Format-dependent utilities */
|
/* Format-dependent utilities */
|
||||||
uint32_t decimal128IsCanonical(const decimal128 *);
|
uint32_t decimal128IsCanonical(const decimal128 *);
|
||||||
decimal128 * decimal128Canonical(decimal128 *, const decimal128 *);
|
decimal128 * decimal128Canonical(decimal128 *, const decimal128 *);
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
02110-1301, USA. */
|
02110-1301, USA. */
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* Decimal 32-bit format module */
|
/* Decimal 32-bit format module */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* This module comprises the routines for decimal32 format numbers. */
|
/* This module comprises the routines for decimal32 format numbers. */
|
||||||
/* Conversions are supplied to and from decNumber and String. */
|
/* Conversions are supplied to and from decNumber and String. */
|
||||||
|
@ -42,8 +42,8 @@
|
||||||
#include <string.h> /* [for memset/memcpy] */
|
#include <string.h> /* [for memset/memcpy] */
|
||||||
#include <stdio.h> /* [for printf] */
|
#include <stdio.h> /* [for printf] */
|
||||||
|
|
||||||
#include "dconfig.h" /* GCC definitions */
|
#include "dconfig.h" /* GCC definitions */
|
||||||
#define DECNUMDIGITS 7 /* make decNumbers with space for 7 */
|
#define DECNUMDIGITS 7 /* make decNumbers with space for 7 */
|
||||||
#include "decNumber.h" /* base number library */
|
#include "decNumber.h" /* base number library */
|
||||||
#include "decNumberLocal.h" /* decNumber local types, etc. */
|
#include "decNumberLocal.h" /* decNumber local types, etc. */
|
||||||
#include "decimal32.h" /* our primary include */
|
#include "decimal32.h" /* our primary include */
|
||||||
|
@ -69,9 +69,9 @@ extern void decNumberShow(const decNumber *); /* .. */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decimal32FromNumber -- convert decNumber to decimal32 */
|
/* decimal32FromNumber -- convert decNumber to decimal32 */
|
||||||
/* */
|
/* */
|
||||||
/* ds is the target decimal32 */
|
/* ds is the target decimal32 */
|
||||||
/* dn is the source number (assumed valid) */
|
/* dn is the source number (assumed valid) */
|
||||||
/* set is the context, used only for reporting errors */
|
/* set is the context, used only for reporting errors */
|
||||||
/* */
|
/* */
|
||||||
/* The set argument is used only for status reporting and for the */
|
/* The set argument is used only for status reporting and for the */
|
||||||
/* rounding mode (used if the coefficient is more than DECIMAL32_Pmax */
|
/* rounding mode (used if the coefficient is more than DECIMAL32_Pmax */
|
||||||
|
@ -89,8 +89,8 @@ decimal32 * decimal32FromNumber(decimal32 *d32, const decNumber *dn,
|
||||||
Int ae; /* adjusted exponent */
|
Int ae; /* adjusted exponent */
|
||||||
decNumber dw; /* work */
|
decNumber dw; /* work */
|
||||||
decContext dc; /* .. */
|
decContext dc; /* .. */
|
||||||
uInt *pu; /* .. */
|
|
||||||
uInt comb, exp; /* .. */
|
uInt comb, exp; /* .. */
|
||||||
|
uInt uiwork; /* for macros */
|
||||||
uInt targ=0; /* target 32-bit */
|
uInt targ=0; /* target 32-bit */
|
||||||
|
|
||||||
/* If the number has too many digits, or the exponent could be */
|
/* If the number has too many digits, or the exponent could be */
|
||||||
|
@ -98,9 +98,9 @@ decimal32 * decimal32FromNumber(decimal32 *d32, const decNumber *dn,
|
||||||
/* constraints. This could push the number to Infinity or zero, */
|
/* constraints. This could push the number to Infinity or zero, */
|
||||||
/* so this check and rounding must be done before generating the */
|
/* so this check and rounding must be done before generating the */
|
||||||
/* decimal32] */
|
/* decimal32] */
|
||||||
ae=dn->exponent+dn->digits-1; /* [0 if special] */
|
ae=dn->exponent+dn->digits-1; /* [0 if special] */
|
||||||
if (dn->digits>DECIMAL32_Pmax /* too many digits */
|
if (dn->digits>DECIMAL32_Pmax /* too many digits */
|
||||||
|| ae>DECIMAL32_Emax /* likely overflow */
|
|| ae>DECIMAL32_Emax /* likely overflow */
|
||||||
|| ae<DECIMAL32_Emin) { /* likely underflow */
|
|| ae<DECIMAL32_Emin) { /* likely underflow */
|
||||||
decContextDefault(&dc, DEC_INIT_DECIMAL32); /* [no traps] */
|
decContextDefault(&dc, DEC_INIT_DECIMAL32); /* [no traps] */
|
||||||
dc.round=set->round; /* use supplied rounding */
|
dc.round=set->round; /* use supplied rounding */
|
||||||
|
@ -114,7 +114,7 @@ decimal32 * decimal32FromNumber(decimal32 *d32, const decNumber *dn,
|
||||||
if (dn->bits&DECSPECIAL) { /* a special value */
|
if (dn->bits&DECSPECIAL) { /* a special value */
|
||||||
if (dn->bits&DECINF) targ=DECIMAL_Inf<<24;
|
if (dn->bits&DECINF) targ=DECIMAL_Inf<<24;
|
||||||
else { /* sNaN or qNaN */
|
else { /* sNaN or qNaN */
|
||||||
if ((*dn->lsu!=0 || dn->digits>1) /* non-zero coefficient */
|
if ((*dn->lsu!=0 || dn->digits>1) /* non-zero coefficient */
|
||||||
&& (dn->digits<DECIMAL32_Pmax)) { /* coefficient fits */
|
&& (dn->digits<DECIMAL32_Pmax)) { /* coefficient fits */
|
||||||
decDigitsToDPD(dn, &targ, 0);
|
decDigitsToDPD(dn, &targ, 0);
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ decimal32 * decimal32FromNumber(decimal32 *d32, const decNumber *dn,
|
||||||
comb=(exp>>3) & 0x18; /* msd=0, exp top 2 bits .. */
|
comb=(exp>>3) & 0x18; /* msd=0, exp top 2 bits .. */
|
||||||
}
|
}
|
||||||
else { /* non-zero finite number */
|
else { /* non-zero finite number */
|
||||||
uInt msd; /* work */
|
uInt msd; /* work */
|
||||||
Int pad=0; /* coefficient pad digits */
|
Int pad=0; /* coefficient pad digits */
|
||||||
|
|
||||||
/* the dn is known to fit, but it may need to be padded */
|
/* the dn is known to fit, but it may need to be padded */
|
||||||
|
@ -175,8 +175,7 @@ decimal32 * decimal32FromNumber(decimal32 *d32, const decNumber *dn,
|
||||||
if (dn->bits&DECNEG) targ|=0x80000000; /* add sign bit */
|
if (dn->bits&DECNEG) targ|=0x80000000; /* add sign bit */
|
||||||
|
|
||||||
/* now write to storage; this is endian */
|
/* now write to storage; this is endian */
|
||||||
pu=(uInt *)d32->bytes; /* overlay */
|
UBFROMUI(d32->bytes, targ); /* directly store the int */
|
||||||
*pu=targ; /* directly store the int */
|
|
||||||
|
|
||||||
if (status!=0) decContextSetStatus(set, status); /* pass on status */
|
if (status!=0) decContextSetStatus(set, status); /* pass on status */
|
||||||
/* decimal32Show(d32); */
|
/* decimal32Show(d32); */
|
||||||
|
@ -194,13 +193,12 @@ decNumber * decimal32ToNumber(const decimal32 *d32, decNumber *dn) {
|
||||||
uInt exp; /* exponent top two bits */
|
uInt exp; /* exponent top two bits */
|
||||||
uInt comb; /* combination field */
|
uInt comb; /* combination field */
|
||||||
uInt sour; /* source 32-bit */
|
uInt sour; /* source 32-bit */
|
||||||
const uInt *pu; /* work */
|
uInt uiwork; /* for macros */
|
||||||
|
|
||||||
/* load source from storage; this is endian */
|
/* load source from storage; this is endian */
|
||||||
pu=(const uInt *)d32->bytes; /* overlay */
|
sour=UBTOUI(d32->bytes); /* directly load the int */
|
||||||
sour=*pu; /* directly load the int */
|
|
||||||
|
|
||||||
comb=(sour>>26)&0x1f; /* combination field */
|
comb=(sour>>26)&0x1f; /* combination field */
|
||||||
|
|
||||||
decNumberZero(dn); /* clean number */
|
decNumberZero(dn); /* clean number */
|
||||||
if (sour&0x80000000) dn->bits=DECNEG; /* set sign if negative */
|
if (sour&0x80000000) dn->bits=DECNEG; /* set sign if negative */
|
||||||
|
@ -208,7 +206,7 @@ decNumber * decimal32ToNumber(const decimal32 *d32, decNumber *dn) {
|
||||||
msd=COMBMSD[comb]; /* decode the combination field */
|
msd=COMBMSD[comb]; /* decode the combination field */
|
||||||
exp=COMBEXP[comb]; /* .. */
|
exp=COMBEXP[comb]; /* .. */
|
||||||
|
|
||||||
if (exp==3) { /* is a special */
|
if (exp==3) { /* is a special */
|
||||||
if (msd==0) {
|
if (msd==0) {
|
||||||
dn->bits|=DECINF;
|
dn->bits|=DECINF;
|
||||||
return dn; /* no coefficient needed */
|
return dn; /* no coefficient needed */
|
||||||
|
@ -229,7 +227,7 @@ decNumber * decimal32ToNumber(const decimal32 *d32, decNumber *dn) {
|
||||||
return dn;
|
return dn;
|
||||||
}
|
}
|
||||||
/* msd=0 */
|
/* msd=0 */
|
||||||
if (!sour) return dn; /* easy: coefficient is 0 */
|
if (!sour) return dn; /* easy: coefficient is 0 */
|
||||||
if (sour&0x000ffc00) /* need 2 declets? */
|
if (sour&0x000ffc00) /* need 2 declets? */
|
||||||
decDigitsFromDPD(dn, &sour, 2); /* process 2 declets */
|
decDigitsFromDPD(dn, &sour, 2); /* process 2 declets */
|
||||||
else
|
else
|
||||||
|
@ -238,11 +236,11 @@ decNumber * decimal32ToNumber(const decimal32 *d32, decNumber *dn) {
|
||||||
} /* decimal32ToNumber */
|
} /* decimal32ToNumber */
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* to-scientific-string -- conversion to numeric string */
|
/* to-scientific-string -- conversion to numeric string */
|
||||||
/* to-engineering-string -- conversion to numeric string */
|
/* to-engineering-string -- conversion to numeric string */
|
||||||
/* */
|
/* */
|
||||||
/* decimal32ToString(d32, string); */
|
/* decimal32ToString(d32, string); */
|
||||||
/* decimal32ToEngString(d32, string); */
|
/* decimal32ToEngString(d32, string); */
|
||||||
/* */
|
/* */
|
||||||
/* d32 is the decimal32 format number to convert */
|
/* d32 is the decimal32 format number to convert */
|
||||||
/* string is the string where the result will be laid out */
|
/* string is the string where the result will be laid out */
|
||||||
|
@ -252,7 +250,7 @@ decNumber * decimal32ToNumber(const decimal32 *d32, decNumber *dn) {
|
||||||
/* No error is possible, and no status can be set. */
|
/* No error is possible, and no status can be set. */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
char * decimal32ToEngString(const decimal32 *d32, char *string){
|
char * decimal32ToEngString(const decimal32 *d32, char *string){
|
||||||
decNumber dn; /* work */
|
decNumber dn; /* work */
|
||||||
decimal32ToNumber(d32, &dn);
|
decimal32ToNumber(d32, &dn);
|
||||||
decNumberToEngString(&dn, string);
|
decNumberToEngString(&dn, string);
|
||||||
return string;
|
return string;
|
||||||
|
@ -262,29 +260,28 @@ char * decimal32ToString(const decimal32 *d32, char *string){
|
||||||
uInt msd; /* coefficient MSD */
|
uInt msd; /* coefficient MSD */
|
||||||
Int exp; /* exponent top two bits or full */
|
Int exp; /* exponent top two bits or full */
|
||||||
uInt comb; /* combination field */
|
uInt comb; /* combination field */
|
||||||
char *cstart; /* coefficient start */
|
char *cstart; /* coefficient start */
|
||||||
char *c; /* output pointer in string */
|
char *c; /* output pointer in string */
|
||||||
const uInt *pu; /* work */
|
const uByte *u; /* work */
|
||||||
const uByte *u; /* .. */
|
|
||||||
char *s, *t; /* .. (source, target) */
|
char *s, *t; /* .. (source, target) */
|
||||||
Int dpd; /* .. */
|
Int dpd; /* .. */
|
||||||
Int pre, e; /* .. */
|
Int pre, e; /* .. */
|
||||||
|
uInt uiwork; /* for macros */
|
||||||
uInt sour; /* source 32-bit */
|
uInt sour; /* source 32-bit */
|
||||||
|
|
||||||
/* load source from storage; this is endian */
|
/* load source from storage; this is endian */
|
||||||
pu=(const uInt *)d32->bytes; /* overlay */
|
sour=UBTOUI(d32->bytes); /* directly load the int */
|
||||||
sour=*pu; /* directly load the int */
|
|
||||||
|
|
||||||
c=string; /* where result will go */
|
c=string; /* where result will go */
|
||||||
if (((Int)sour)<0) *c++='-'; /* handle sign */
|
if (((Int)sour)<0) *c++='-'; /* handle sign */
|
||||||
|
|
||||||
comb=(sour>>26)&0x1f; /* combination field */
|
comb=(sour>>26)&0x1f; /* combination field */
|
||||||
msd=COMBMSD[comb]; /* decode the combination field */
|
msd=COMBMSD[comb]; /* decode the combination field */
|
||||||
exp=COMBEXP[comb]; /* .. */
|
exp=COMBEXP[comb]; /* .. */
|
||||||
|
|
||||||
if (exp==3) {
|
if (exp==3) {
|
||||||
if (msd==0) { /* infinity */
|
if (msd==0) { /* infinity */
|
||||||
strcpy(c, "Inf");
|
strcpy(c, "Inf");
|
||||||
strcpy(c+3, "inity");
|
strcpy(c+3, "inity");
|
||||||
return string; /* easy */
|
return string; /* easy */
|
||||||
}
|
}
|
||||||
|
@ -309,18 +306,18 @@ char * decimal32ToString(const decimal32 *d32, char *string){
|
||||||
/* length. We use fixed-length memcpys because variable-length */
|
/* length. We use fixed-length memcpys because variable-length */
|
||||||
/* causes a subroutine call in GCC. (These are length 4 for speed */
|
/* causes a subroutine call in GCC. (These are length 4 for speed */
|
||||||
/* and are safe because the array has an extra terminator byte.) */
|
/* and are safe because the array has an extra terminator byte.) */
|
||||||
#define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; \
|
#define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; \
|
||||||
if (c!=cstart) {memcpy(c, u+1, 4); c+=3;} \
|
if (c!=cstart) {memcpy(c, u+1, 4); c+=3;} \
|
||||||
else if (*u) {memcpy(c, u+4-*u, 4); c+=*u;}
|
else if (*u) {memcpy(c, u+4-*u, 4); c+=*u;}
|
||||||
|
|
||||||
dpd=(sour>>10)&0x3ff; /* declet 1 */
|
dpd=(sour>>10)&0x3ff; /* declet 1 */
|
||||||
dpd2char;
|
dpd2char;
|
||||||
dpd=(sour)&0x3ff; /* declet 2 */
|
dpd=(sour)&0x3ff; /* declet 2 */
|
||||||
dpd2char;
|
dpd2char;
|
||||||
|
|
||||||
if (c==cstart) *c++='0'; /* all zeros -- make 0 */
|
if (c==cstart) *c++='0'; /* all zeros -- make 0 */
|
||||||
|
|
||||||
if (exp==0) { /* integer or NaN case -- easy */
|
if (exp==0) { /* integer or NaN case -- easy */
|
||||||
*c='\0'; /* terminate */
|
*c='\0'; /* terminate */
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
@ -348,13 +345,13 @@ char * decimal32ToString(const decimal32 *d32, char *string){
|
||||||
/* finally add the E-part, if needed; it will never be 0, and has */
|
/* finally add the E-part, if needed; it will never be 0, and has */
|
||||||
/* a maximum length of 3 digits (E-101 case) */
|
/* a maximum length of 3 digits (E-101 case) */
|
||||||
if (e!=0) {
|
if (e!=0) {
|
||||||
*c++='E'; /* starts with E */
|
*c++='E'; /* starts with E */
|
||||||
*c++='+'; /* assume positive */
|
*c++='+'; /* assume positive */
|
||||||
if (e<0) {
|
if (e<0) {
|
||||||
*(c-1)='-'; /* oops, need '-' */
|
*(c-1)='-'; /* oops, need '-' */
|
||||||
e=-e; /* uInt, please */
|
e=-e; /* uInt, please */
|
||||||
}
|
}
|
||||||
u=&BIN2CHAR[e*4]; /* -> length byte */
|
u=&BIN2CHAR[e*4]; /* -> length byte */
|
||||||
memcpy(c, u+4-*u, 4); /* copy fixed 4 characters [is safe] */
|
memcpy(c, u+4-*u, 4); /* copy fixed 4 characters [is safe] */
|
||||||
c+=*u; /* bump pointer appropriately */
|
c+=*u; /* bump pointer appropriately */
|
||||||
}
|
}
|
||||||
|
@ -384,7 +381,7 @@ char * decimal32ToString(const decimal32 *d32, char *string){
|
||||||
/* the conversion */
|
/* the conversion */
|
||||||
/* *string is the character string which should contain a valid */
|
/* *string is the character string which should contain a valid */
|
||||||
/* number (which may be a special value) */
|
/* number (which may be a special value) */
|
||||||
/* set is the context */
|
/* set is the context */
|
||||||
/* */
|
/* */
|
||||||
/* The context is supplied to this routine is used for error handling */
|
/* The context is supplied to this routine is used for error handling */
|
||||||
/* (setting of status and traps) and for the rounding mode, only. */
|
/* (setting of status and traps) and for the rounding mode, only. */
|
||||||
|
@ -393,7 +390,7 @@ char * decimal32ToString(const decimal32 *d32, char *string){
|
||||||
decimal32 * decimal32FromString(decimal32 *result, const char *string,
|
decimal32 * decimal32FromString(decimal32 *result, const char *string,
|
||||||
decContext *set) {
|
decContext *set) {
|
||||||
decContext dc; /* work */
|
decContext dc; /* work */
|
||||||
decNumber dn; /* .. */
|
decNumber dn; /* .. */
|
||||||
|
|
||||||
decContextDefault(&dc, DEC_INIT_DECIMAL32); /* no traps, please */
|
decContextDefault(&dc, DEC_INIT_DECIMAL32); /* no traps, please */
|
||||||
dc.round=set->round; /* use supplied rounding */
|
dc.round=set->round; /* use supplied rounding */
|
||||||
|
@ -409,11 +406,11 @@ decimal32 * decimal32FromString(decimal32 *result, const char *string,
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decimal32IsCanonical -- test whether encoding is canonical */
|
/* decimal32IsCanonical -- test whether encoding is canonical */
|
||||||
/* d32 is the source decimal32 */
|
/* d32 is the source decimal32 */
|
||||||
/* returns 1 if the encoding of d32 is canonical, 0 otherwise */
|
/* returns 1 if the encoding of d32 is canonical, 0 otherwise */
|
||||||
/* No error is possible. */
|
/* No error is possible. */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
uint32_t decimal32IsCanonical(const decimal32 *d32) {
|
uInt decimal32IsCanonical(const decimal32 *d32) {
|
||||||
decNumber dn; /* work */
|
decNumber dn; /* work */
|
||||||
decimal32 canon; /* .. */
|
decimal32 canon; /* .. */
|
||||||
decContext dc; /* .. */
|
decContext dc; /* .. */
|
||||||
decContextDefault(&dc, DEC_INIT_DECIMAL32);
|
decContextDefault(&dc, DEC_INIT_DECIMAL32);
|
||||||
|
@ -430,7 +427,7 @@ uint32_t decimal32IsCanonical(const decimal32 *d32) {
|
||||||
/* No error is possible. */
|
/* No error is possible. */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
decimal32 * decimal32Canonical(decimal32 *result, const decimal32 *d32) {
|
decimal32 * decimal32Canonical(decimal32 *result, const decimal32 *d32) {
|
||||||
decNumber dn; /* work */
|
decNumber dn; /* work */
|
||||||
decContext dc; /* .. */
|
decContext dc; /* .. */
|
||||||
decContextDefault(&dc, DEC_INIT_DECIMAL32);
|
decContextDefault(&dc, DEC_INIT_DECIMAL32);
|
||||||
decimal32ToNumber(d32, &dn);
|
decimal32ToNumber(d32, &dn);
|
||||||
|
@ -460,8 +457,8 @@ decimal32 * decimal32Canonical(decimal32 *result, const decimal32 *d32) {
|
||||||
/* This assumes range has been checked and exponent previously 0; */
|
/* This assumes range has been checked and exponent previously 0; */
|
||||||
/* type of exponent must be unsigned */
|
/* type of exponent must be unsigned */
|
||||||
#define decimal32SetExpCon(d, e) { \
|
#define decimal32SetExpCon(d, e) { \
|
||||||
(d)->bytes[0]|=(uint8_t)((e)>>4); \
|
(d)->bytes[0]|=(uByte)((e)>>4); \
|
||||||
(d)->bytes[1]|=(uint8_t)(((e)&0x0F)<<4);}
|
(d)->bytes[1]|=(uByte)(((e)&0x0F)<<4);}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decimal32Show -- display a decimal32 in hexadecimal [debug aid] */
|
/* decimal32Show -- display a decimal32 in hexadecimal [debug aid] */
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#if !defined(DECIMAL32)
|
#if !defined(DECIMAL32)
|
||||||
#define DECIMAL32
|
#define DECIMAL32
|
||||||
#define DEC32NAME "decimal32" /* Short name */
|
#define DEC32NAME "decimal32" /* Short name */
|
||||||
#define DEC32FULLNAME "Decimal 32-bit Number" /* Verbose name */
|
#define DEC32FULLNAME "Decimal 32-bit Number" /* Verbose name */
|
||||||
#define DEC32AUTHOR "Mike Cowlishaw" /* Who to blame */
|
#define DEC32AUTHOR "Mike Cowlishaw" /* Who to blame */
|
||||||
|
|
||||||
/* parameters for decimal32s */
|
/* parameters for decimal32s */
|
||||||
|
@ -46,7 +46,7 @@
|
||||||
#define DECIMAL32_Bias 101 /* bias for the exponent */
|
#define DECIMAL32_Bias 101 /* bias for the exponent */
|
||||||
#define DECIMAL32_String 15 /* maximum string length, +1 */
|
#define DECIMAL32_String 15 /* maximum string length, +1 */
|
||||||
#define DECIMAL32_EconL 6 /* exp. continuation length */
|
#define DECIMAL32_EconL 6 /* exp. continuation length */
|
||||||
/* highest biased exponent (Elimit-1) */
|
/* highest biased exponent (Elimit-1) */
|
||||||
#define DECIMAL32_Ehigh (DECIMAL32_Emax+DECIMAL32_Bias-DECIMAL32_Pmax+1)
|
#define DECIMAL32_Ehigh (DECIMAL32_Emax+DECIMAL32_Bias-DECIMAL32_Pmax+1)
|
||||||
|
|
||||||
/* check enough digits, if pre-defined */
|
/* check enough digits, if pre-defined */
|
||||||
|
@ -71,18 +71,18 @@
|
||||||
/* special values [top byte excluding sign bit; last two bits are */
|
/* special values [top byte excluding sign bit; last two bits are */
|
||||||
/* don't-care for Infinity on input, last bit don't-care for NaN] */
|
/* don't-care for Infinity on input, last bit don't-care for NaN] */
|
||||||
#if !defined(DECIMAL_NaN)
|
#if !defined(DECIMAL_NaN)
|
||||||
#define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */
|
#define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */
|
||||||
#define DECIMAL_sNaN 0x7e /* 0 11111 10 sNaN */
|
#define DECIMAL_sNaN 0x7e /* 0 11111 10 sNaN */
|
||||||
#define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */
|
#define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
/* Routines */
|
/* Routines */
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
#include "decimal32Symbols.h"
|
#include "decimal32Symbols.h"
|
||||||
|
|
||||||
/* String conversions */
|
/* String conversions */
|
||||||
decimal32 * decimal32FromString(decimal32 *, const char *, decContext *);
|
decimal32 * decimal32FromString(decimal32 *, const char *, decContext *);
|
||||||
char * decimal32ToString(const decimal32 *, char *);
|
char * decimal32ToString(const decimal32 *, char *);
|
||||||
char * decimal32ToEngString(const decimal32 *, char *);
|
char * decimal32ToEngString(const decimal32 *, char *);
|
||||||
|
@ -92,7 +92,7 @@
|
||||||
decContext *);
|
decContext *);
|
||||||
decNumber * decimal32ToNumber(const decimal32 *, decNumber *);
|
decNumber * decimal32ToNumber(const decimal32 *, decNumber *);
|
||||||
|
|
||||||
/* Format-dependent utilities */
|
/* Format-dependent utilities */
|
||||||
uint32_t decimal32IsCanonical(const decimal32 *);
|
uint32_t decimal32IsCanonical(const decimal32 *);
|
||||||
decimal32 * decimal32Canonical(decimal32 *, const decimal32 *);
|
decimal32 * decimal32Canonical(decimal32 *, const decimal32 *);
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
02110-1301, USA. */
|
02110-1301, USA. */
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* Decimal 64-bit format module */
|
/* Decimal 64-bit format module */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* This module comprises the routines for decimal64 format numbers. */
|
/* This module comprises the routines for decimal64 format numbers. */
|
||||||
/* Conversions are supplied to and from decNumber and String. */
|
/* Conversions are supplied to and from decNumber and String. */
|
||||||
|
@ -42,8 +42,8 @@
|
||||||
#include <string.h> /* [for memset/memcpy] */
|
#include <string.h> /* [for memset/memcpy] */
|
||||||
#include <stdio.h> /* [for printf] */
|
#include <stdio.h> /* [for printf] */
|
||||||
|
|
||||||
#include "dconfig.h" /* GCC definitions */
|
#include "dconfig.h" /* GCC definitions */
|
||||||
#define DECNUMDIGITS 16 /* make decNumbers with space for 16 */
|
#define DECNUMDIGITS 16 /* make decNumbers with space for 16 */
|
||||||
#include "decNumber.h" /* base number library */
|
#include "decNumber.h" /* base number library */
|
||||||
#include "decNumberLocal.h" /* decNumber local types, etc. */
|
#include "decNumberLocal.h" /* decNumber local types, etc. */
|
||||||
#include "decimal64.h" /* our primary include */
|
#include "decimal64.h" /* our primary include */
|
||||||
|
@ -75,9 +75,9 @@ extern void decNumberShow(const decNumber *); /* .. */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decimal64FromNumber -- convert decNumber to decimal64 */
|
/* decimal64FromNumber -- convert decNumber to decimal64 */
|
||||||
/* */
|
/* */
|
||||||
/* ds is the target decimal64 */
|
/* ds is the target decimal64 */
|
||||||
/* dn is the source number (assumed valid) */
|
/* dn is the source number (assumed valid) */
|
||||||
/* set is the context, used only for reporting errors */
|
/* set is the context, used only for reporting errors */
|
||||||
/* */
|
/* */
|
||||||
/* The set argument is used only for status reporting and for the */
|
/* The set argument is used only for status reporting and for the */
|
||||||
/* rounding mode (used if the coefficient is more than DECIMAL64_Pmax */
|
/* rounding mode (used if the coefficient is more than DECIMAL64_Pmax */
|
||||||
|
@ -95,8 +95,8 @@ decimal64 * decimal64FromNumber(decimal64 *d64, const decNumber *dn,
|
||||||
Int ae; /* adjusted exponent */
|
Int ae; /* adjusted exponent */
|
||||||
decNumber dw; /* work */
|
decNumber dw; /* work */
|
||||||
decContext dc; /* .. */
|
decContext dc; /* .. */
|
||||||
uInt *pu; /* .. */
|
|
||||||
uInt comb, exp; /* .. */
|
uInt comb, exp; /* .. */
|
||||||
|
uInt uiwork; /* for macros */
|
||||||
uInt targar[2]={0, 0}; /* target 64-bit */
|
uInt targar[2]={0, 0}; /* target 64-bit */
|
||||||
#define targhi targar[1] /* name the word with the sign */
|
#define targhi targar[1] /* name the word with the sign */
|
||||||
#define targlo targar[0] /* and the other */
|
#define targlo targar[0] /* and the other */
|
||||||
|
@ -106,9 +106,9 @@ decimal64 * decimal64FromNumber(decimal64 *d64, const decNumber *dn,
|
||||||
/* constraints. This could push the number to Infinity or zero, */
|
/* constraints. This could push the number to Infinity or zero, */
|
||||||
/* so this check and rounding must be done before generating the */
|
/* so this check and rounding must be done before generating the */
|
||||||
/* decimal64] */
|
/* decimal64] */
|
||||||
ae=dn->exponent+dn->digits-1; /* [0 if special] */
|
ae=dn->exponent+dn->digits-1; /* [0 if special] */
|
||||||
if (dn->digits>DECIMAL64_Pmax /* too many digits */
|
if (dn->digits>DECIMAL64_Pmax /* too many digits */
|
||||||
|| ae>DECIMAL64_Emax /* likely overflow */
|
|| ae>DECIMAL64_Emax /* likely overflow */
|
||||||
|| ae<DECIMAL64_Emin) { /* likely underflow */
|
|| ae<DECIMAL64_Emin) { /* likely underflow */
|
||||||
decContextDefault(&dc, DEC_INIT_DECIMAL64); /* [no traps] */
|
decContextDefault(&dc, DEC_INIT_DECIMAL64); /* [no traps] */
|
||||||
dc.round=set->round; /* use supplied rounding */
|
dc.round=set->round; /* use supplied rounding */
|
||||||
|
@ -122,7 +122,7 @@ decimal64 * decimal64FromNumber(decimal64 *d64, const decNumber *dn,
|
||||||
if (dn->bits&DECSPECIAL) { /* a special value */
|
if (dn->bits&DECSPECIAL) { /* a special value */
|
||||||
if (dn->bits&DECINF) targhi=DECIMAL_Inf<<24;
|
if (dn->bits&DECINF) targhi=DECIMAL_Inf<<24;
|
||||||
else { /* sNaN or qNaN */
|
else { /* sNaN or qNaN */
|
||||||
if ((*dn->lsu!=0 || dn->digits>1) /* non-zero coefficient */
|
if ((*dn->lsu!=0 || dn->digits>1) /* non-zero coefficient */
|
||||||
&& (dn->digits<DECIMAL64_Pmax)) { /* coefficient fits */
|
&& (dn->digits<DECIMAL64_Pmax)) { /* coefficient fits */
|
||||||
decDigitsToDPD(dn, targar, 0);
|
decDigitsToDPD(dn, targar, 0);
|
||||||
}
|
}
|
||||||
|
@ -148,7 +148,7 @@ decimal64 * decimal64FromNumber(decimal64 *d64, const decNumber *dn,
|
||||||
comb=(exp>>5) & 0x18; /* msd=0, exp top 2 bits .. */
|
comb=(exp>>5) & 0x18; /* msd=0, exp top 2 bits .. */
|
||||||
}
|
}
|
||||||
else { /* non-zero finite number */
|
else { /* non-zero finite number */
|
||||||
uInt msd; /* work */
|
uInt msd; /* work */
|
||||||
Int pad=0; /* coefficient pad digits */
|
Int pad=0; /* coefficient pad digits */
|
||||||
|
|
||||||
/* the dn is known to fit, but it may need to be padded */
|
/* the dn is known to fit, but it may need to be padded */
|
||||||
|
@ -193,14 +193,15 @@ decimal64 * decimal64FromNumber(decimal64 *d64, const decNumber *dn,
|
||||||
if (dn->bits&DECNEG) targhi|=0x80000000; /* add sign bit */
|
if (dn->bits&DECNEG) targhi|=0x80000000; /* add sign bit */
|
||||||
|
|
||||||
/* now write to storage; this is now always endian */
|
/* now write to storage; this is now always endian */
|
||||||
pu=(uInt *)d64->bytes; /* overlay */
|
|
||||||
if (DECLITEND) {
|
if (DECLITEND) {
|
||||||
pu[0]=targar[0]; /* directly store the low int */
|
/* lo int then hi */
|
||||||
pu[1]=targar[1]; /* then the high int */
|
UBFROMUI(d64->bytes, targar[0]);
|
||||||
|
UBFROMUI(d64->bytes+4, targar[1]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pu[0]=targar[1]; /* directly store the high int */
|
/* hi int then lo */
|
||||||
pu[1]=targar[0]; /* then the low int */
|
UBFROMUI(d64->bytes, targar[1]);
|
||||||
|
UBFROMUI(d64->bytes+4, targar[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status!=0) decContextSetStatus(set, status); /* pass on status */
|
if (status!=0) decContextSetStatus(set, status); /* pass on status */
|
||||||
|
@ -218,21 +219,20 @@ decNumber * decimal64ToNumber(const decimal64 *d64, decNumber *dn) {
|
||||||
uInt msd; /* coefficient MSD */
|
uInt msd; /* coefficient MSD */
|
||||||
uInt exp; /* exponent top two bits */
|
uInt exp; /* exponent top two bits */
|
||||||
uInt comb; /* combination field */
|
uInt comb; /* combination field */
|
||||||
const uInt *pu; /* work */
|
Int need; /* work */
|
||||||
Int need; /* .. */
|
uInt uiwork; /* for macros */
|
||||||
uInt sourar[2]; /* source 64-bit */
|
uInt sourar[2]; /* source 64-bit */
|
||||||
#define sourhi sourar[1] /* name the word with the sign */
|
#define sourhi sourar[1] /* name the word with the sign */
|
||||||
#define sourlo sourar[0] /* and the lower word */
|
#define sourlo sourar[0] /* and the lower word */
|
||||||
|
|
||||||
/* load source from storage; this is endian */
|
/* load source from storage; this is endian */
|
||||||
pu=(const uInt *)d64->bytes; /* overlay */
|
|
||||||
if (DECLITEND) {
|
if (DECLITEND) {
|
||||||
sourlo=pu[0]; /* directly load the low int */
|
sourlo=UBTOUI(d64->bytes ); /* directly load the low int */
|
||||||
sourhi=pu[1]; /* then the high int */
|
sourhi=UBTOUI(d64->bytes+4); /* then the high int */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sourhi=pu[0]; /* directly load the high int */
|
sourhi=UBTOUI(d64->bytes ); /* directly load the high int */
|
||||||
sourlo=pu[1]; /* then the low int */
|
sourlo=UBTOUI(d64->bytes+4); /* then the low int */
|
||||||
}
|
}
|
||||||
|
|
||||||
comb=(sourhi>>26)&0x1f; /* combination field */
|
comb=(sourhi>>26)&0x1f; /* combination field */
|
||||||
|
@ -243,7 +243,7 @@ decNumber * decimal64ToNumber(const decimal64 *d64, decNumber *dn) {
|
||||||
msd=COMBMSD[comb]; /* decode the combination field */
|
msd=COMBMSD[comb]; /* decode the combination field */
|
||||||
exp=COMBEXP[comb]; /* .. */
|
exp=COMBEXP[comb]; /* .. */
|
||||||
|
|
||||||
if (exp==3) { /* is a special */
|
if (exp==3) { /* is a special */
|
||||||
if (msd==0) {
|
if (msd==0) {
|
||||||
dn->bits|=DECINF;
|
dn->bits|=DECINF;
|
||||||
return dn; /* no coefficient needed */
|
return dn; /* no coefficient needed */
|
||||||
|
@ -281,11 +281,11 @@ decNumber * decimal64ToNumber(const decimal64 *d64, decNumber *dn) {
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* to-scientific-string -- conversion to numeric string */
|
/* to-scientific-string -- conversion to numeric string */
|
||||||
/* to-engineering-string -- conversion to numeric string */
|
/* to-engineering-string -- conversion to numeric string */
|
||||||
/* */
|
/* */
|
||||||
/* decimal64ToString(d64, string); */
|
/* decimal64ToString(d64, string); */
|
||||||
/* decimal64ToEngString(d64, string); */
|
/* decimal64ToEngString(d64, string); */
|
||||||
/* */
|
/* */
|
||||||
/* d64 is the decimal64 format number to convert */
|
/* d64 is the decimal64 format number to convert */
|
||||||
/* string is the string where the result will be laid out */
|
/* string is the string where the result will be laid out */
|
||||||
|
@ -295,7 +295,7 @@ decNumber * decimal64ToNumber(const decimal64 *d64, decNumber *dn) {
|
||||||
/* No error is possible, and no status can be set. */
|
/* No error is possible, and no status can be set. */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
char * decimal64ToEngString(const decimal64 *d64, char *string){
|
char * decimal64ToEngString(const decimal64 *d64, char *string){
|
||||||
decNumber dn; /* work */
|
decNumber dn; /* work */
|
||||||
decimal64ToNumber(d64, &dn);
|
decimal64ToNumber(d64, &dn);
|
||||||
decNumberToEngString(&dn, string);
|
decNumberToEngString(&dn, string);
|
||||||
return string;
|
return string;
|
||||||
|
@ -305,27 +305,26 @@ char * decimal64ToString(const decimal64 *d64, char *string){
|
||||||
uInt msd; /* coefficient MSD */
|
uInt msd; /* coefficient MSD */
|
||||||
Int exp; /* exponent top two bits or full */
|
Int exp; /* exponent top two bits or full */
|
||||||
uInt comb; /* combination field */
|
uInt comb; /* combination field */
|
||||||
char *cstart; /* coefficient start */
|
char *cstart; /* coefficient start */
|
||||||
char *c; /* output pointer in string */
|
char *c; /* output pointer in string */
|
||||||
const uInt *pu; /* work */
|
const uByte *u; /* work */
|
||||||
char *s, *t; /* .. (source, target) */
|
char *s, *t; /* .. (source, target) */
|
||||||
Int dpd; /* .. */
|
Int dpd; /* .. */
|
||||||
Int pre, e; /* .. */
|
Int pre, e; /* .. */
|
||||||
const uByte *u; /* .. */
|
uInt uiwork; /* for macros */
|
||||||
|
|
||||||
uInt sourar[2]; /* source 64-bit */
|
uInt sourar[2]; /* source 64-bit */
|
||||||
#define sourhi sourar[1] /* name the word with the sign */
|
#define sourhi sourar[1] /* name the word with the sign */
|
||||||
#define sourlo sourar[0] /* and the lower word */
|
#define sourlo sourar[0] /* and the lower word */
|
||||||
|
|
||||||
/* load source from storage; this is endian */
|
/* load source from storage; this is endian */
|
||||||
pu=(const uInt *)d64->bytes; /* overlay */
|
|
||||||
if (DECLITEND) {
|
if (DECLITEND) {
|
||||||
sourlo=pu[0]; /* directly load the low int */
|
sourlo=UBTOUI(d64->bytes ); /* directly load the low int */
|
||||||
sourhi=pu[1]; /* then the high int */
|
sourhi=UBTOUI(d64->bytes+4); /* then the high int */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sourhi=pu[0]; /* directly load the high int */
|
sourhi=UBTOUI(d64->bytes ); /* directly load the high int */
|
||||||
sourlo=pu[1]; /* then the low int */
|
sourlo=UBTOUI(d64->bytes+4); /* then the low int */
|
||||||
}
|
}
|
||||||
|
|
||||||
c=string; /* where result will go */
|
c=string; /* where result will go */
|
||||||
|
@ -337,7 +336,7 @@ char * decimal64ToString(const decimal64 *d64, char *string){
|
||||||
|
|
||||||
if (exp==3) {
|
if (exp==3) {
|
||||||
if (msd==0) { /* infinity */
|
if (msd==0) { /* infinity */
|
||||||
strcpy(c, "Inf");
|
strcpy(c, "Inf");
|
||||||
strcpy(c+3, "inity");
|
strcpy(c+3, "inity");
|
||||||
return string; /* easy */
|
return string; /* easy */
|
||||||
}
|
}
|
||||||
|
@ -362,7 +361,7 @@ char * decimal64ToString(const decimal64 *d64, char *string){
|
||||||
/* length. We use fixed-length memcpys because variable-length */
|
/* length. We use fixed-length memcpys because variable-length */
|
||||||
/* causes a subroutine call in GCC. (These are length 4 for speed */
|
/* causes a subroutine call in GCC. (These are length 4 for speed */
|
||||||
/* and are safe because the array has an extra terminator byte.) */
|
/* and are safe because the array has an extra terminator byte.) */
|
||||||
#define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; \
|
#define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; \
|
||||||
if (c!=cstart) {memcpy(c, u+1, 4); c+=3;} \
|
if (c!=cstart) {memcpy(c, u+1, 4); c+=3;} \
|
||||||
else if (*u) {memcpy(c, u+4-*u, 4); c+=*u;}
|
else if (*u) {memcpy(c, u+4-*u, 4); c+=*u;}
|
||||||
|
|
||||||
|
@ -379,7 +378,7 @@ char * decimal64ToString(const decimal64 *d64, char *string){
|
||||||
|
|
||||||
if (c==cstart) *c++='0'; /* all zeros -- make 0 */
|
if (c==cstart) *c++='0'; /* all zeros -- make 0 */
|
||||||
|
|
||||||
if (exp==0) { /* integer or NaN case -- easy */
|
if (exp==0) { /* integer or NaN case -- easy */
|
||||||
*c='\0'; /* terminate */
|
*c='\0'; /* terminate */
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
@ -407,13 +406,13 @@ char * decimal64ToString(const decimal64 *d64, char *string){
|
||||||
/* finally add the E-part, if needed; it will never be 0, and has */
|
/* finally add the E-part, if needed; it will never be 0, and has */
|
||||||
/* a maximum length of 3 digits */
|
/* a maximum length of 3 digits */
|
||||||
if (e!=0) {
|
if (e!=0) {
|
||||||
*c++='E'; /* starts with E */
|
*c++='E'; /* starts with E */
|
||||||
*c++='+'; /* assume positive */
|
*c++='+'; /* assume positive */
|
||||||
if (e<0) {
|
if (e<0) {
|
||||||
*(c-1)='-'; /* oops, need '-' */
|
*(c-1)='-'; /* oops, need '-' */
|
||||||
e=-e; /* uInt, please */
|
e=-e; /* uInt, please */
|
||||||
}
|
}
|
||||||
u=&BIN2CHAR[e*4]; /* -> length byte */
|
u=&BIN2CHAR[e*4]; /* -> length byte */
|
||||||
memcpy(c, u+4-*u, 4); /* copy fixed 4 characters [is safe] */
|
memcpy(c, u+4-*u, 4); /* copy fixed 4 characters [is safe] */
|
||||||
c+=*u; /* bump pointer appropriately */
|
c+=*u; /* bump pointer appropriately */
|
||||||
}
|
}
|
||||||
|
@ -443,7 +442,7 @@ char * decimal64ToString(const decimal64 *d64, char *string){
|
||||||
/* the conversion */
|
/* the conversion */
|
||||||
/* *string is the character string which should contain a valid */
|
/* *string is the character string which should contain a valid */
|
||||||
/* number (which may be a special value) */
|
/* number (which may be a special value) */
|
||||||
/* set is the context */
|
/* set is the context */
|
||||||
/* */
|
/* */
|
||||||
/* The context is supplied to this routine is used for error handling */
|
/* The context is supplied to this routine is used for error handling */
|
||||||
/* (setting of status and traps) and for the rounding mode, only. */
|
/* (setting of status and traps) and for the rounding mode, only. */
|
||||||
|
@ -452,7 +451,7 @@ char * decimal64ToString(const decimal64 *d64, char *string){
|
||||||
decimal64 * decimal64FromString(decimal64 *result, const char *string,
|
decimal64 * decimal64FromString(decimal64 *result, const char *string,
|
||||||
decContext *set) {
|
decContext *set) {
|
||||||
decContext dc; /* work */
|
decContext dc; /* work */
|
||||||
decNumber dn; /* .. */
|
decNumber dn; /* .. */
|
||||||
|
|
||||||
decContextDefault(&dc, DEC_INIT_DECIMAL64); /* no traps, please */
|
decContextDefault(&dc, DEC_INIT_DECIMAL64); /* no traps, please */
|
||||||
dc.round=set->round; /* use supplied rounding */
|
dc.round=set->round; /* use supplied rounding */
|
||||||
|
@ -469,11 +468,11 @@ decimal64 * decimal64FromString(decimal64 *result, const char *string,
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decimal64IsCanonical -- test whether encoding is canonical */
|
/* decimal64IsCanonical -- test whether encoding is canonical */
|
||||||
/* d64 is the source decimal64 */
|
/* d64 is the source decimal64 */
|
||||||
/* returns 1 if the encoding of d64 is canonical, 0 otherwise */
|
/* returns 1 if the encoding of d64 is canonical, 0 otherwise */
|
||||||
/* No error is possible. */
|
/* No error is possible. */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
uint32_t decimal64IsCanonical(const decimal64 *d64) {
|
uInt decimal64IsCanonical(const decimal64 *d64) {
|
||||||
decNumber dn; /* work */
|
decNumber dn; /* work */
|
||||||
decimal64 canon; /* .. */
|
decimal64 canon; /* .. */
|
||||||
decContext dc; /* .. */
|
decContext dc; /* .. */
|
||||||
decContextDefault(&dc, DEC_INIT_DECIMAL64);
|
decContextDefault(&dc, DEC_INIT_DECIMAL64);
|
||||||
|
@ -490,7 +489,7 @@ uint32_t decimal64IsCanonical(const decimal64 *d64) {
|
||||||
/* No error is possible. */
|
/* No error is possible. */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
decimal64 * decimal64Canonical(decimal64 *result, const decimal64 *d64) {
|
decimal64 * decimal64Canonical(decimal64 *result, const decimal64 *d64) {
|
||||||
decNumber dn; /* work */
|
decNumber dn; /* work */
|
||||||
decContext dc; /* .. */
|
decContext dc; /* .. */
|
||||||
decContextDefault(&dc, DEC_INIT_DECIMAL64);
|
decContextDefault(&dc, DEC_INIT_DECIMAL64);
|
||||||
decimal64ToNumber(d64, &dn);
|
decimal64ToNumber(d64, &dn);
|
||||||
|
@ -520,8 +519,8 @@ decimal64 * decimal64Canonical(decimal64 *result, const decimal64 *d64) {
|
||||||
/* This assumes range has been checked and exponent previously 0; */
|
/* This assumes range has been checked and exponent previously 0; */
|
||||||
/* type of exponent must be unsigned */
|
/* type of exponent must be unsigned */
|
||||||
#define decimal64SetExpCon(d, e) { \
|
#define decimal64SetExpCon(d, e) { \
|
||||||
(d)->bytes[0]|=(uint8_t)((e)>>6); \
|
(d)->bytes[0]|=(uByte)((e)>>6); \
|
||||||
(d)->bytes[1]|=(uint8_t)(((e)&0x3F)<<2);}
|
(d)->bytes[1]|=(uByte)(((e)&0x3F)<<2);}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decimal64Show -- display a decimal64 in hexadecimal [debug aid] */
|
/* decimal64Show -- display a decimal64 in hexadecimal [debug aid] */
|
||||||
|
@ -591,12 +590,12 @@ const uInt COMBMSD[32]={0, 1, 2, 3, 4, 5, 6, 7,
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* decDigitsToDPD -- pack coefficient into DPD form */
|
/* decDigitsToDPD -- pack coefficient into DPD form */
|
||||||
/* */
|
/* */
|
||||||
/* dn is the source number (assumed valid, max DECMAX754 digits) */
|
/* dn is the source number (assumed valid, max DECMAX754 digits) */
|
||||||
/* targ is 1, 2, or 4-element uInt array, which the caller must */
|
/* targ is 1, 2, or 4-element uInt array, which the caller must */
|
||||||
/* have cleared to zeros */
|
/* have cleared to zeros */
|
||||||
/* shift is the number of 0 digits to add on the right (normally 0) */
|
/* shift is the number of 0 digits to add on the right (normally 0) */
|
||||||
/* */
|
/* */
|
||||||
/* The coefficient must be known small enough to fit. The full */
|
/* The coefficient must be known small enough to fit. The full */
|
||||||
/* coefficient is copied, including the leading 'odd' digit. This */
|
/* coefficient is copied, including the leading 'odd' digit. This */
|
||||||
/* digit is retrieved and packed into the combination field by the */
|
/* digit is retrieved and packed into the combination field by the */
|
||||||
/* caller. */
|
/* caller. */
|
||||||
|
@ -625,7 +624,7 @@ void decDigitsToDPD(const decNumber *dn, uInt *targ, Int shift) {
|
||||||
uInt dpd; /* densely packed decimal value */
|
uInt dpd; /* densely packed decimal value */
|
||||||
uInt bin; /* binary value 0-999 */
|
uInt bin; /* binary value 0-999 */
|
||||||
uInt *uout=targ; /* -> current output uInt */
|
uInt *uout=targ; /* -> current output uInt */
|
||||||
uInt uoff=0; /* -> current output offset [from right] */
|
uInt uoff=0; /* -> current output offset [from right] */
|
||||||
const Unit *inu=dn->lsu; /* -> current input unit */
|
const Unit *inu=dn->lsu; /* -> current input unit */
|
||||||
Unit uar[DECMAXUNITS]; /* working copy of units, iff shifted */
|
Unit uar[DECMAXUNITS]; /* working copy of units, iff shifted */
|
||||||
#if DECDPUN!=3 /* not fast path */
|
#if DECDPUN!=3 /* not fast path */
|
||||||
|
@ -636,7 +635,7 @@ void decDigitsToDPD(const decNumber *dn, uInt *targ, Int shift) {
|
||||||
/* shift the units array to the left by pad digits and copy */
|
/* shift the units array to the left by pad digits and copy */
|
||||||
/* [this code is a special case of decShiftToMost, which could */
|
/* [this code is a special case of decShiftToMost, which could */
|
||||||
/* be used instead if exposed and the array were copied first] */
|
/* be used instead if exposed and the array were copied first] */
|
||||||
const Unit *source; /* .. */
|
const Unit *source; /* .. */
|
||||||
Unit *target, *first; /* .. */
|
Unit *target, *first; /* .. */
|
||||||
uInt next=0; /* work */
|
uInt next=0; /* work */
|
||||||
|
|
||||||
|
@ -681,12 +680,12 @@ void decDigitsToDPD(const decNumber *dn, uInt *targ, Int shift) {
|
||||||
|
|
||||||
for(n=0; digits>0; n++) { /* each output bunch */
|
for(n=0; digits>0; n++) { /* each output bunch */
|
||||||
#if DECDPUN==3 /* fast path, 3-at-a-time */
|
#if DECDPUN==3 /* fast path, 3-at-a-time */
|
||||||
bin=*inu; /* 3 digits ready for convert */
|
bin=*inu; /* 3 digits ready for convert */
|
||||||
digits-=3; /* [may go negative] */
|
digits-=3; /* [may go negative] */
|
||||||
inu++; /* may need another */
|
inu++; /* may need another */
|
||||||
|
|
||||||
#else /* must collect digit-by-digit */
|
#else /* must collect digit-by-digit */
|
||||||
Unit dig; /* current digit */
|
Unit dig; /* current digit */
|
||||||
Int j; /* digit-in-declet count */
|
Int j; /* digit-in-declet count */
|
||||||
for (j=0; j<3; j++) {
|
for (j=0; j<3; j++) {
|
||||||
#if DECDPUN<=4
|
#if DECDPUN<=4
|
||||||
|
@ -698,7 +697,7 @@ void decDigitsToDPD(const decNumber *dn, uInt *targ, Int shift) {
|
||||||
in=in/10;
|
in=in/10;
|
||||||
#endif
|
#endif
|
||||||
if (j==0) bin=dig;
|
if (j==0) bin=dig;
|
||||||
else if (j==1) bin+=X10(dig);
|
else if (j==1) bin+=X10(dig);
|
||||||
else /* j==2 */ bin+=X100(dig);
|
else /* j==2 */ bin+=X100(dig);
|
||||||
digits--;
|
digits--;
|
||||||
if (digits==0) break; /* [also protects *inu below] */
|
if (digits==0) break; /* [also protects *inu below] */
|
||||||
|
@ -750,12 +749,12 @@ void decDigitsFromDPD(decNumber *dn, const uInt *sour, Int declets) {
|
||||||
Int n; /* counter */
|
Int n; /* counter */
|
||||||
Unit *uout=dn->lsu; /* -> current output unit */
|
Unit *uout=dn->lsu; /* -> current output unit */
|
||||||
Unit *last=uout; /* will be unit containing msd */
|
Unit *last=uout; /* will be unit containing msd */
|
||||||
const uInt *uin=sour; /* -> current input uInt */
|
const uInt *uin=sour; /* -> current input uInt */
|
||||||
uInt uoff=0; /* -> current input offset [from right] */
|
uInt uoff=0; /* -> current input offset [from right] */
|
||||||
|
|
||||||
#if DECDPUN!=3
|
#if DECDPUN!=3
|
||||||
uInt bcd; /* BCD result */
|
uInt bcd; /* BCD result */
|
||||||
uInt nibble; /* work */
|
uInt nibble; /* work */
|
||||||
Unit out=0; /* accumulator */
|
Unit out=0; /* accumulator */
|
||||||
Int cut=0; /* power of ten in current unit */
|
Int cut=0; /* power of ten in current unit */
|
||||||
#endif
|
#endif
|
||||||
|
@ -772,7 +771,7 @@ void decDigitsFromDPD(decNumber *dn, const uInt *sour, Int declets) {
|
||||||
uoff-=32;
|
uoff-=32;
|
||||||
dpd|=*uin<<(10-uoff); /* get waiting bits */
|
dpd|=*uin<<(10-uoff); /* get waiting bits */
|
||||||
}
|
}
|
||||||
dpd&=0x3ff; /* clear uninteresting bits */
|
dpd&=0x3ff; /* clear uninteresting bits */
|
||||||
|
|
||||||
#if DECDPUN==3
|
#if DECDPUN==3
|
||||||
if (dpd==0) *uout=0;
|
if (dpd==0) *uout=0;
|
||||||
|
@ -822,9 +821,9 @@ void decDigitsFromDPD(decNumber *dn, const uInt *sour, Int declets) {
|
||||||
cut++;
|
cut++;
|
||||||
if (cut==DECDPUN) {*uout=out; if (out) {last=uout; out=0;} uout++; cut=0;}
|
if (cut==DECDPUN) {*uout=out; if (out) {last=uout; out=0;} uout++; cut=0;}
|
||||||
} /* n */
|
} /* n */
|
||||||
if (cut!=0) { /* some more left over */
|
if (cut!=0) { /* some more left over */
|
||||||
*uout=out; /* write out final unit */
|
*uout=out; /* write out final unit */
|
||||||
if (out) last=uout; /* and note if non-zero */
|
if (out) last=uout; /* and note if non-zero */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -834,14 +833,14 @@ void decDigitsFromDPD(decNumber *dn, const uInt *sour, Int declets) {
|
||||||
dn->digits=(last-dn->lsu)*DECDPUN+1; /* floor of digits, plus */
|
dn->digits=(last-dn->lsu)*DECDPUN+1; /* floor of digits, plus */
|
||||||
/* must be at least 1 digit */
|
/* must be at least 1 digit */
|
||||||
#if DECDPUN>1
|
#if DECDPUN>1
|
||||||
if (*last<10) return; /* common odd digit or 0 */
|
if (*last<10) return; /* common odd digit or 0 */
|
||||||
dn->digits++; /* must be 2 at least */
|
dn->digits++; /* must be 2 at least */
|
||||||
#if DECDPUN>2
|
#if DECDPUN>2
|
||||||
if (*last<100) return; /* 10-99 */
|
if (*last<100) return; /* 10-99 */
|
||||||
dn->digits++; /* must be 3 at least */
|
dn->digits++; /* must be 3 at least */
|
||||||
#if DECDPUN>3
|
#if DECDPUN>3
|
||||||
if (*last<1000) return; /* 100-999 */
|
if (*last<1000) return; /* 100-999 */
|
||||||
dn->digits++; /* must be 4 at least */
|
dn->digits++; /* must be 4 at least */
|
||||||
#if DECDPUN>4
|
#if DECDPUN>4
|
||||||
for (pow=&DECPOWERS[4]; *last>=*pow; pow++) dn->digits++;
|
for (pow=&DECPOWERS[4]; *last>=*pow; pow++) dn->digits++;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#if !defined(DECIMAL64)
|
#if !defined(DECIMAL64)
|
||||||
#define DECIMAL64
|
#define DECIMAL64
|
||||||
#define DEC64NAME "decimal64" /* Short name */
|
#define DEC64NAME "decimal64" /* Short name */
|
||||||
#define DEC64FULLNAME "Decimal 64-bit Number" /* Verbose name */
|
#define DEC64FULLNAME "Decimal 64-bit Number" /* Verbose name */
|
||||||
#define DEC64AUTHOR "Mike Cowlishaw" /* Who to blame */
|
#define DEC64AUTHOR "Mike Cowlishaw" /* Who to blame */
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
#define DECIMAL64_Bias 398 /* bias for the exponent */
|
#define DECIMAL64_Bias 398 /* bias for the exponent */
|
||||||
#define DECIMAL64_String 24 /* maximum string length, +1 */
|
#define DECIMAL64_String 24 /* maximum string length, +1 */
|
||||||
#define DECIMAL64_EconL 8 /* exp. continuation length */
|
#define DECIMAL64_EconL 8 /* exp. continuation length */
|
||||||
/* highest biased exponent (Elimit-1) */
|
/* highest biased exponent (Elimit-1) */
|
||||||
#define DECIMAL64_Ehigh (DECIMAL64_Emax+DECIMAL64_Bias-DECIMAL64_Pmax+1)
|
#define DECIMAL64_Ehigh (DECIMAL64_Emax+DECIMAL64_Bias-DECIMAL64_Pmax+1)
|
||||||
|
|
||||||
/* check enough digits, if pre-defined */
|
/* check enough digits, if pre-defined */
|
||||||
|
@ -73,18 +73,18 @@
|
||||||
/* special values [top byte excluding sign bit; last two bits are */
|
/* special values [top byte excluding sign bit; last two bits are */
|
||||||
/* don't-care for Infinity on input, last bit don't-care for NaN] */
|
/* don't-care for Infinity on input, last bit don't-care for NaN] */
|
||||||
#if !defined(DECIMAL_NaN)
|
#if !defined(DECIMAL_NaN)
|
||||||
#define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */
|
#define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */
|
||||||
#define DECIMAL_sNaN 0x7e /* 0 11111 10 sNaN */
|
#define DECIMAL_sNaN 0x7e /* 0 11111 10 sNaN */
|
||||||
#define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */
|
#define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
/* Routines */
|
/* Routines */
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
#include "decimal64Symbols.h"
|
#include "decimal64Symbols.h"
|
||||||
|
|
||||||
/* String conversions */
|
/* String conversions */
|
||||||
decimal64 * decimal64FromString(decimal64 *, const char *, decContext *);
|
decimal64 * decimal64FromString(decimal64 *, const char *, decContext *);
|
||||||
char * decimal64ToString(const decimal64 *, char *);
|
char * decimal64ToString(const decimal64 *, char *);
|
||||||
char * decimal64ToEngString(const decimal64 *, char *);
|
char * decimal64ToEngString(const decimal64 *, char *);
|
||||||
|
@ -94,7 +94,7 @@
|
||||||
decContext *);
|
decContext *);
|
||||||
decNumber * decimal64ToNumber(const decimal64 *, decNumber *);
|
decNumber * decimal64ToNumber(const decimal64 *, decNumber *);
|
||||||
|
|
||||||
/* Format-dependent utilities */
|
/* Format-dependent utilities */
|
||||||
uint32_t decimal64IsCanonical(const decimal64 *);
|
uint32_t decimal64IsCanonical(const decimal64 *);
|
||||||
decimal64 * decimal64Canonical(decimal64 *, const decimal64 *);
|
decimal64 * decimal64Canonical(decimal64 *, const decimal64 *);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue