merge from gcc

This commit is contained in:
DJ Delorie 2009-03-30 00:01:29 +00:00
parent 4104b747d5
commit f2be950300
23 changed files with 1611 additions and 1971 deletions

View File

@ -1,12 +1,3 @@
2009-03-29 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>
* 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

View File

@ -38,13 +38,15 @@
#include <string.h> /* for strcmp */
#include <stdio.h> /* for printf if DECCHECK */
#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. */
#if DECCHECK
/* compile-time endian tester [assumes sizeof(Int)>1] */
static const Int mfcone=1; /* constant 1 */
static const Flag *mfctop=(const Flag *)&mfcone; /* -> top byte */
static const Flag *mfctop=(Flag *)&mfcone; /* -> top byte */
#define LITEND *mfctop /* named flag; 1=little-endian */
#endif
/* ------------------------------------------------------------------ */
/* round-for-reround digits */
@ -62,7 +64,7 @@ const uInt DECPOWERS[10]={1, 10, 100, 1000, 10000, 100000, 1000000,
/* */
/* context is the context structure to be queried */
/* mask indicates the bits to be cleared (the status bit that */
/* corresponds to each 1 bit in the mask is cleared) */
/* corresponds to each 1 bit in the mask is cleared) */
/* returns context */
/* */
/* No error is possible. */
@ -78,9 +80,9 @@ decContext *decContextClearStatus(decContext *context, uInt mask) {
/* context is the structure to be initialized */
/* kind selects the required set of default values, one of: */
/* DEC_INIT_BASE -- select ANSI X3-274 defaults */
/* DEC_INIT_DECIMAL32 -- select IEEE 754 defaults, 32-bit */
/* DEC_INIT_DECIMAL64 -- select IEEE 754 defaults, 64-bit */
/* DEC_INIT_DECIMAL128 -- select IEEE 754 defaults, 128-bit */
/* DEC_INIT_DECIMAL32 -- select IEEE 754r defaults, 32-bit */
/* DEC_INIT_DECIMAL64 -- select IEEE 754r defaults, 64-bit */
/* DEC_INIT_DECIMAL128 -- select IEEE 754r defaults, 128-bit */
/* For any other value a valid context is returned, but with */
/* Invalid_operation set in the status field. */
/* returns a context structure with the appropriate initial values. */
@ -103,11 +105,11 @@ decContext * decContextDefault(decContext *context, Int kind) {
break;
case DEC_INIT_DECIMAL32:
context->digits=7; /* digits */
context->emax=96; /* Emax */
context->emax=96; /* Emax */
context->emin=-95; /* Emin */
context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
context->traps=0; /* no traps set */
context->clamp=1; /* clamp exponents */
context->traps=0; /* no traps set */
context->clamp=1; /* clamp exponents */
#if DECSUBSET
context->extended=1; /* set */
#endif
@ -117,8 +119,8 @@ decContext * decContextDefault(decContext *context, Int kind) {
context->emax=384; /* Emax */
context->emin=-383; /* Emin */
context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
context->traps=0; /* no traps set */
context->clamp=1; /* clamp exponents */
context->traps=0; /* no traps set */
context->clamp=1; /* clamp exponents */
#if DECSUBSET
context->extended=1; /* set */
#endif
@ -128,8 +130,8 @@ decContext * decContextDefault(decContext *context, Int kind) {
context->emax=6144; /* Emax */
context->emin=-6143; /* Emin */
context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
context->traps=0; /* no traps set */
context->clamp=1; /* clamp exponents */
context->traps=0; /* no traps set */
context->clamp=1; /* clamp exponents */
#if DECSUBSET
context->extended=1; /* set */
#endif
@ -140,6 +142,15 @@ decContext * decContextDefault(decContext *context, Int kind) {
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 */
/* ------------------------------------------------------------------ */
@ -155,7 +166,7 @@ enum rounding decContextGetRounding(decContext *context) {
} /* decContextGetRounding */
/* ------------------------------------------------------------------ */
/* decContextGetStatus -- return current status */
/* decContextGetStatus -- return current status */
/* */
/* context is the context structure to be queried */
/* returns status */
@ -170,8 +181,8 @@ uInt decContextGetStatus(decContext *context) {
/* decContextRestoreStatus -- restore bits in current status */
/* */
/* context is the context structure to be updated */
/* newstatus is the source for the bits to be restored */
/* mask indicates the bits to be restored (the status bit that */
/* newstatus is the source for the bits to be restored */
/* mask indicates the bits to be restored (the status bit that */
/* corresponds to each 1 bit in the mask is set to the value of */
/* the correspnding bit in newstatus) */
/* returns context */
@ -241,7 +252,7 @@ decContext * decContextSetStatus(decContext *context, uInt status) {
/* */
/* returns the context structure, unless the string is equal to */
/* DEC_Condition_MU or is not recognized. In these cases NULL is */
/* returned. */
/* returned. */
/* ------------------------------------------------------------------ */
decContext * decContextSetStatusFromString(decContext *context,
const char *string) {
@ -292,7 +303,7 @@ decContext * decContextSetStatusFromString(decContext *context,
/* */
/* returns the context structure, unless the string is equal to */
/* DEC_Condition_MU or is not recognized. In these cases NULL is */
/* returned. */
/* returned. */
/* ------------------------------------------------------------------ */
decContext * decContextSetStatusFromStringQuiet(decContext *context,
const char *string) {
@ -345,11 +356,11 @@ decContext * decContextSetStatusQuiet(decContext *context, uInt status) {
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 */
/* */
/* 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. */
/* ------------------------------------------------------------------ */
const char *decContextStatusToString(const decContext *context) {
@ -374,40 +385,10 @@ const char *decContextStatusToString(const decContext *context) {
#if DECSUBSET
if (status==DEC_Lost_digits ) return DEC_Condition_LD;
#endif
if (status==0 ) return DEC_Condition_ZE;
if (status==0 ) return DEC_Condition_ZE;
return DEC_Condition_MU; /* Multiple errors */
} /* 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 */
/* */

View File

@ -34,7 +34,7 @@
/* */
/* 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 */
/* */
/* The following variables are implied for fixed size formats (i.e., */
@ -54,42 +54,36 @@
#define DECCONTEXT
#define DECCNAME "decContext" /* Short name */
#define DECCFULLNAME "Decimal Context Descriptor" /* Verbose name */
#define DECCAUTHOR "Mike Cowlishaw" /* Who to blame */
#define DECCAUTHOR "Mike Cowlishaw" /* Who to blame */
#if !defined(int32_t)
#include <stdint.h> /* C99 standard integers */
#endif
#include "gstdint.h" /* C99 standard integers */
#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 */
#if !defined(DECEXTFLAG)
#define DECEXTFLAG 1 /* 1=enable extended flags */
#endif
/* Conditional code flag -- set this to 0 for best performance */
#if !defined(DECSUBSET)
#define DECSUBSET 0 /* 1=enable subset arithmetic */
#endif
/* Context for operations, with associated constants */
enum rounding {
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_EVEN, /* 0.5 rounds to nearest even */
DEC_ROUND_HALF_DOWN, /* 0.5 rounds down */
DEC_ROUND_DOWN, /* round towards 0 (truncate) */
DEC_ROUND_FLOOR, /* round towards -infinity */
DEC_ROUND_05UP, /* round for reround */
DEC_ROUND_05UP, /* round for reround */
DEC_ROUND_MAX /* enum must be less than this */
};
#define DEC_ROUND_DEFAULT DEC_ROUND_HALF_EVEN;
typedef struct {
int32_t digits; /* working precision */
int32_t emax; /* maximum positive exponent */
int32_t emin; /* minimum negative exponent */
int32_t digits; /* working precision */
int32_t emax; /* maximum positive exponent */
int32_t emin; /* minimum negative exponent */
enum rounding round; /* rounding mode */
uint32_t traps; /* trap-enabler flags */
uint32_t status; /* status flags */
@ -108,9 +102,9 @@
#define DEC_MIN_EMIN -999999999
#define DEC_MAX_MATH 999999 /* max emax, etc., for math funcs. */
/* Classifications for decimal numbers, aligned with 754 (note that */
/* 'normal' and 'subnormal' are meaningful only with a decContext */
/* or a fixed size format). */
/* Classifications for decimal numbers, aligned with 754r (note */
/* that 'normal' and 'subnormal' are meaningful only with a */
/* decContext or a fixed size format). */
enum decClass {
DEC_CLASS_SNAN,
DEC_CLASS_QNAN,
@ -145,15 +139,15 @@
#define DEC_Division_impossible 0x00000004
#define DEC_Division_undefined 0x00000008
#define DEC_Insufficient_storage 0x00000010 /* [when malloc fails] */
#define DEC_Inexact 0x00000020
#define DEC_Invalid_context 0x00000040
#define DEC_Inexact 0x00000020
#define DEC_Invalid_context 0x00000040
#define DEC_Invalid_operation 0x00000080
#if DECSUBSET
#define DEC_Lost_digits 0x00000100
#endif
#define DEC_Overflow 0x00000200
#define DEC_Clamped 0x00000400
#define DEC_Rounded 0x00000800
#define DEC_Clamped 0x00000400
#define DEC_Rounded 0x00000800
#define DEC_Subnormal 0x00001000
#define DEC_Underflow 0x00002000
#else
@ -163,43 +157,43 @@
#define DEC_Division_impossible 0x00000010
#define DEC_Division_undefined 0x00000010
#define DEC_Insufficient_storage 0x00000010 /* [when malloc fails] */
#define DEC_Inexact 0x00000001
#define DEC_Invalid_context 0x00000010
#define DEC_Inexact 0x00000001
#define DEC_Invalid_context 0x00000010
#define DEC_Invalid_operation 0x00000010
#if DECSUBSET
#define DEC_Lost_digits 0x00000000
#endif
#define DEC_Overflow 0x00000008
#define DEC_Clamped 0x00000000
#define DEC_Rounded 0x00000000
#define DEC_Clamped 0x00000000
#define DEC_Rounded 0x00000000
#define DEC_Subnormal 0x00000000
#define DEC_Underflow 0x00000004
#endif
/* IEEE 754 groupings for the flags */
/* IEEE 854 groupings for the flags */
/* [DEC_Clamped, DEC_Lost_digits, DEC_Rounded, and DEC_Subnormal */
/* are not in IEEE 754] */
#define DEC_IEEE_754_Division_by_zero (DEC_Division_by_zero)
/* are not in IEEE 854] */
#define DEC_IEEE_854_Division_by_zero (DEC_Division_by_zero)
#if DECSUBSET
#define DEC_IEEE_754_Inexact (DEC_Inexact | DEC_Lost_digits)
#define DEC_IEEE_854_Inexact (DEC_Inexact | DEC_Lost_digits)
#else
#define DEC_IEEE_754_Inexact (DEC_Inexact)
#define DEC_IEEE_854_Inexact (DEC_Inexact)
#endif
#define DEC_IEEE_754_Invalid_operation (DEC_Conversion_syntax | \
#define DEC_IEEE_854_Invalid_operation (DEC_Conversion_syntax | \
DEC_Division_impossible | \
DEC_Division_undefined | \
DEC_Insufficient_storage | \
DEC_Invalid_context | \
DEC_Invalid_context | \
DEC_Invalid_operation)
#define DEC_IEEE_754_Overflow (DEC_Overflow)
#define DEC_IEEE_754_Underflow (DEC_Underflow)
#define DEC_IEEE_854_Overflow (DEC_Overflow)
#define DEC_IEEE_854_Underflow (DEC_Underflow)
/* flags which are normally errors (result is qNaN, infinite, or 0) */
#define DEC_Errors (DEC_IEEE_754_Division_by_zero | \
DEC_IEEE_754_Invalid_operation | \
DEC_IEEE_754_Overflow | DEC_IEEE_754_Underflow)
#define DEC_Errors (DEC_IEEE_854_Division_by_zero | \
DEC_IEEE_854_Invalid_operation | \
DEC_IEEE_854_Overflow | DEC_IEEE_854_Underflow)
/* flags which cause a result to become qNaN */
#define DEC_NaNs DEC_IEEE_754_Invalid_operation
#define DEC_NaNs DEC_IEEE_854_Invalid_operation
/* flags which are normally for information only (finite results) */
#if DECSUBSET
@ -209,13 +203,6 @@
#define DEC_Information (DEC_Clamped | DEC_Rounded | DEC_Inexact)
#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 */
#define DEC_Condition_CS "Conversion syntax"
#define DEC_Condition_DZ "Division by zero"
@ -239,7 +226,7 @@
/* including terminator */
/* Initialization descriptors, used by decContextDefault */
#define DEC_INIT_BASE 0
#define DEC_INIT_BASE 0
#define DEC_INIT_DECIMAL32 32
#define DEC_INIT_DECIMAL64 64
#define DEC_INIT_DECIMAL128 128
@ -264,7 +251,6 @@
extern decContext * decContextSetStatusFromStringQuiet(decContext *, const char *);
extern decContext * decContextSetStatusQuiet(decContext *, uint32_t);
extern const char * decContextStatusToString(const decContext *);
extern int32_t decContextTestEndian(uint8_t);
extern uint32_t decContextTestSavedStatus(uint32_t, uint32_t);
extern uint32_t decContextTestStatus(decContext *, uint32_t);
extern decContext * decContextZeroStatus(decContext *);

View File

@ -30,9 +30,10 @@
/* ------------------------------------------------------------------------ */
/* Binary Coded Decimal and Densely Packed Decimal conversion lookup tables */
/* [Automatically generated -- do not edit. 2008.06.21] */
/* [Automatically generated -- do not edit. 2007.05.05] */
/* ------------------------------------------------------------------------ */
/* 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"
@ -42,9 +43,9 @@
/* uint16_t BIN2DPD[1000]; -- Bin -> DPD (999 => 2457) */
/* uint8_t BIN2CHAR[4001]; -- Bin -> CHAR (999 => '\3' '9' '9' '9') */
/* 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) */
/* 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) */
/* uint8_t DPD2BCD8[4096]; -- DPD -> bytes (x3FF => 9 9 9 3) */
/* */
@ -52,10 +53,10 @@
/* in the table entry. BIN2CHAR entries are a single byte length (0 for */
/* value 0) followed by three digit characters; a trailing terminator is */
/* included to allow 4-char moves always. BIN2BCD8 and DPD2BCD8 entries */
/* are similar with the three BCD8 digits followed by a one-byte length */
/* are similar with the three BCD8 digits followed by a one-byte length */
/* (again, length=0 for value 0). */
/* */
/* To use a table, its name, prefixed with DEC_, must be defined with a */
/* To use a table, its name, prefixed with DEC_, must be defined with a */
/* value of 1 before this header file is included. For example: */
/* #define DEC_BCD2DPD 1 */
/* This mechanism allows software to only include tables that are needed. */
@ -512,7 +513,7 @@ const uint16_t DPD2BIN[1024]={ 0, 1, 2, 3, 4, 5, 6, 7,
#if defined(DEC_DPD2BINK) && DEC_DPD2BINK==1 && !defined(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,
10000, 11000, 12000, 13000, 14000, 15000, 16000, 17000, 18000, 19000,
90000, 91000, 810000, 811000, 890000, 891000, 20000, 21000, 22000, 23000,
@ -620,24 +621,24 @@ const uint32_t DPD2BINK[1024]={ 0, 1000, 2000, 3000, 4000, 5000,
#if defined(DEC_DPD2BINM) && DEC_DPD2BINM==1 && !defined(DECDPD2BINM)
#define DECDPD2BINM
const uint32_t DPD2BINM[1024]={0, 1000000, 2000000, 3000000, 4000000,
5000000, 6000000, 7000000, 8000000, 9000000, 80000000, 81000000,
800000000, 801000000, 880000000, 881000000, 10000000, 11000000, 12000000,
13000000, 14000000, 15000000, 16000000, 17000000, 18000000, 19000000,
const uint32_t DPD2BINM[1024]={0, 1000000, 2000000, 3000000, 4000000,
5000000, 6000000, 7000000, 8000000, 9000000, 80000000, 81000000,
800000000, 801000000, 880000000, 881000000, 10000000, 11000000, 12000000,
13000000, 14000000, 15000000, 16000000, 17000000, 18000000, 19000000,
90000000, 91000000, 810000000, 811000000, 890000000, 891000000, 20000000,
21000000, 22000000, 23000000, 24000000, 25000000, 26000000, 27000000,
21000000, 22000000, 23000000, 24000000, 25000000, 26000000, 27000000,
28000000, 29000000, 82000000, 83000000, 820000000, 821000000, 808000000,
809000000, 30000000, 31000000, 32000000, 33000000, 34000000, 35000000,
36000000, 37000000, 38000000, 39000000, 92000000, 93000000, 830000000,
831000000, 818000000, 819000000, 40000000, 41000000, 42000000, 43000000,
44000000, 45000000, 46000000, 47000000, 48000000, 49000000, 84000000,
85000000, 840000000, 841000000, 88000000, 89000000, 50000000, 51000000,
52000000, 53000000, 54000000, 55000000, 56000000, 57000000, 58000000,
59000000, 94000000, 95000000, 850000000, 851000000, 98000000, 99000000,
60000000, 61000000, 62000000, 63000000, 64000000, 65000000, 66000000,
809000000, 30000000, 31000000, 32000000, 33000000, 34000000, 35000000,
36000000, 37000000, 38000000, 39000000, 92000000, 93000000, 830000000,
831000000, 818000000, 819000000, 40000000, 41000000, 42000000, 43000000,
44000000, 45000000, 46000000, 47000000, 48000000, 49000000, 84000000,
85000000, 840000000, 841000000, 88000000, 89000000, 50000000, 51000000,
52000000, 53000000, 54000000, 55000000, 56000000, 57000000, 58000000,
59000000, 94000000, 95000000, 850000000, 851000000, 98000000, 99000000,
60000000, 61000000, 62000000, 63000000, 64000000, 65000000, 66000000,
67000000, 68000000, 69000000, 86000000, 87000000, 860000000, 861000000,
888000000, 889000000, 70000000, 71000000, 72000000, 73000000, 74000000,
75000000, 76000000, 77000000, 78000000, 79000000, 96000000, 97000000,
888000000, 889000000, 70000000, 71000000, 72000000, 73000000, 74000000,
75000000, 76000000, 77000000, 78000000, 79000000, 96000000, 97000000,
870000000, 871000000, 898000000, 899000000, 100000000, 101000000, 102000000,
103000000, 104000000, 105000000, 106000000, 107000000, 108000000, 109000000,
180000000, 181000000, 900000000, 901000000, 980000000, 981000000, 110000000,

View File

@ -34,19 +34,19 @@
/* This module comprises decDouble operations (including conversions) */
/* ------------------------------------------------------------------ */
#include "decContext.h" /* public includes */
#include "decContext.h" /* public includes */
#include "decDouble.h" /* .. */
/* Constant mappings for shared code */
#define DECPMAX DECDOUBLE_Pmax
#define DECEMIN DECDOUBLE_Emin
#define DECEMAX DECDOUBLE_Emax
#define DECPMAX DECDOUBLE_Pmax
#define DECEMIN DECDOUBLE_Emin
#define DECEMAX DECDOUBLE_Emax
#define DECEMAXD DECDOUBLE_EmaxD
#define DECBYTES DECDOUBLE_Bytes
#define DECSTRING DECDOUBLE_String
#define DECECONL DECDOUBLE_EconL
#define DECBIAS DECDOUBLE_Bias
#define DECLETS DECDOUBLE_Declets
#define DECBIAS DECDOUBLE_Bias
#define DECLETS DECDOUBLE_Declets
#define DECQTINY (-DECDOUBLE_Bias)
/* parameters of next-wider format */
#define DECWBYTES DECQUAD_Bytes
@ -55,98 +55,100 @@
#define DECWBIAS DECQUAD_Bias
/* Type and function mappings for shared code */
#define decFloat decDouble /* Type name */
#define decFloatWider decQuad /* Type name */
#define decFloat decDouble /* Type name */
#define decFloatWider decQuad /* Type name */
/* Utilities and conversions (binary results, extractors, etc.) */
#define decFloatFromBCD decDoubleFromBCD
#define decFloatFromInt32 decDoubleFromInt32
#define decFloatFromPacked decDoubleFromPacked
#define decFloatFromPackedChecked decDoubleFromPackedChecked
#define decFloatFromString decDoubleFromString
#define decFloatFromUInt32 decDoubleFromUInt32
#define decFloatFromWider decDoubleFromWider
#define decFloatGetCoefficient decDoubleGetCoefficient
#define decFloatGetExponent decDoubleGetExponent
#define decFloatSetCoefficient decDoubleSetCoefficient
#define decFloatSetExponent decDoubleSetExponent
#define decFloatShow decDoubleShow
#define decFloatToBCD decDoubleToBCD
#define decFloatToEngString decDoubleToEngString
#define decFloatToInt32 decDoubleToInt32
#define decFloatToInt32Exact decDoubleToInt32Exact
#define decFloatToPacked decDoubleToPacked
#define decFloatToString decDoubleToString
#define decFloatToUInt32 decDoubleToUInt32
#define decFloatToUInt32Exact decDoubleToUInt32Exact
#define decFloatToWider decDoubleToWider
#define decFloatZero decDoubleZero
#define decFloatFromBCD decDoubleFromBCD
#define decFloatFromInt32 decDoubleFromInt32
#define decFloatFromPacked decDoubleFromPacked
#define decFloatFromString decDoubleFromString
#define decFloatFromUInt32 decDoubleFromUInt32
#define decFloatFromWider decDoubleFromWider
#define decFloatGetCoefficient decDoubleGetCoefficient
#define decFloatGetExponent decDoubleGetExponent
#define decFloatSetCoefficient decDoubleSetCoefficient
#define decFloatSetExponent decDoubleSetExponent
#define decFloatShow decDoubleShow
#define decFloatToBCD decDoubleToBCD
#define decFloatToEngString decDoubleToEngString
#define decFloatToInt32 decDoubleToInt32
#define decFloatToInt32Exact decDoubleToInt32Exact
#define decFloatToPacked decDoubleToPacked
#define decFloatToString decDoubleToString
#define decFloatToUInt32 decDoubleToUInt32
#define decFloatToUInt32Exact decDoubleToUInt32Exact
#define decFloatToWider decDoubleToWider
#define decFloatZero decDoubleZero
/* Computational (result is a decFloat) */
#define decFloatAbs decDoubleAbs
#define decFloatAdd decDoubleAdd
#define decFloatAnd decDoubleAnd
#define decFloatDivide decDoubleDivide
#define decFloatDivideInteger decDoubleDivideInteger
#define decFloatFMA decDoubleFMA
#define decFloatInvert decDoubleInvert
#define decFloatLogB decDoubleLogB
#define decFloatMax decDoubleMax
#define decFloatMaxMag decDoubleMaxMag
#define decFloatMin decDoubleMin
#define decFloatMinMag decDoubleMinMag
#define decFloatMinus decDoubleMinus
#define decFloatMultiply decDoubleMultiply
#define decFloatNextMinus decDoubleNextMinus
#define decFloatNextPlus decDoubleNextPlus
#define decFloatNextToward decDoubleNextToward
#define decFloatOr decDoubleOr
#define decFloatPlus decDoublePlus
#define decFloatQuantize decDoubleQuantize
#define decFloatReduce decDoubleReduce
#define decFloatRemainder decDoubleRemainder
#define decFloatRemainderNear decDoubleRemainderNear
#define decFloatRotate decDoubleRotate
#define decFloatScaleB decDoubleScaleB
#define decFloatShift decDoubleShift
#define decFloatSubtract decDoubleSubtract
#define decFloatToIntegralValue decDoubleToIntegralValue
#define decFloatToIntegralExact decDoubleToIntegralExact
#define decFloatXor decDoubleXor
#define decFloatAbs decDoubleAbs
#define decFloatAdd decDoubleAdd
#define decFloatAnd decDoubleAnd
#define decFloatDivide decDoubleDivide
#define decFloatDivideInteger decDoubleDivideInteger
#define decFloatFMA decDoubleFMA
#define decFloatInvert decDoubleInvert
#define decFloatLogB decDoubleLogB
#define decFloatMax decDoubleMax
#define decFloatMaxMag decDoubleMaxMag
#define decFloatMin decDoubleMin
#define decFloatMinMag decDoubleMinMag
#define decFloatMinus decDoubleMinus
#define decFloatMultiply decDoubleMultiply
#define decFloatNextMinus decDoubleNextMinus
#define decFloatNextPlus decDoubleNextPlus
#define decFloatNextToward decDoubleNextToward
#define decFloatOr decDoubleOr
#define decFloatPlus decDoublePlus
#define decFloatQuantize decDoubleQuantize
#define decFloatReduce decDoubleReduce
#define decFloatRemainder decDoubleRemainder
#define decFloatRemainderNear decDoubleRemainderNear
#define decFloatRotate decDoubleRotate
#define decFloatScaleB decDoubleScaleB
#define decFloatShift decDoubleShift
#define decFloatSubtract decDoubleSubtract
#define decFloatToIntegralValue decDoubleToIntegralValue
#define decFloatToIntegralExact decDoubleToIntegralExact
#define decFloatXor decDoubleXor
/* Comparisons */
#define decFloatCompare decDoubleCompare
#define decFloatCompareSignal decDoubleCompareSignal
#define decFloatCompareTotal decDoubleCompareTotal
#define decFloatCompareTotalMag decDoubleCompareTotalMag
#define decFloatCompare decDoubleCompare
#define decFloatCompareSignal decDoubleCompareSignal
#define decFloatCompareTotal decDoubleCompareTotal
#define decFloatCompareTotalMag decDoubleCompareTotalMag
/* Copies */
#define decFloatCanonical decDoubleCanonical
#define decFloatCopy decDoubleCopy
#define decFloatCopyAbs decDoubleCopyAbs
#define decFloatCopyNegate decDoubleCopyNegate
#define decFloatCopySign decDoubleCopySign
#define decFloatCanonical decDoubleCanonical
#define decFloatCopy decDoubleCopy
#define decFloatCopyAbs decDoubleCopyAbs
#define decFloatCopyNegate decDoubleCopyNegate
#define decFloatCopySign decDoubleCopySign
/* Non-computational */
#define decFloatClass decDoubleClass
#define decFloatClassString decDoubleClassString
#define decFloatDigits decDoubleDigits
#define decFloatIsCanonical decDoubleIsCanonical
#define decFloatIsFinite decDoubleIsFinite
#define decFloatIsInfinite decDoubleIsInfinite
#define decFloatIsInteger decDoubleIsInteger
#define decFloatIsNaN decDoubleIsNaN
#define decFloatIsNormal decDoubleIsNormal
#define decFloatIsSignaling decDoubleIsSignaling
#define decFloatIsSignalling decDoubleIsSignalling
#define decFloatIsSigned decDoubleIsSigned
#define decFloatIsSubnormal decDoubleIsSubnormal
#define decFloatIsZero decDoubleIsZero
#define decFloatRadix decDoubleRadix
#define decFloatSameQuantum decDoubleSameQuantum
#define decFloatVersion decDoubleVersion
#define decFloatClass decDoubleClass
#define decFloatClassString decDoubleClassString
#define decFloatDigits decDoubleDigits
#define decFloatIsCanonical decDoubleIsCanonical
#define decFloatIsFinite decDoubleIsFinite
#define decFloatIsInfinite decDoubleIsInfinite
#define decFloatIsInteger decDoubleIsInteger
#define decFloatIsNaN decDoubleIsNaN
#define decFloatIsNormal decDoubleIsNormal
#define decFloatIsSignaling decDoubleIsSignaling
#define decFloatIsSignalling decDoubleIsSignalling
#define decFloatIsSigned decDoubleIsSigned
#define decFloatIsSubnormal decDoubleIsSubnormal
#define decFloatIsZero decDoubleIsZero
#define decFloatRadix decDoubleRadix
#define decFloatSameQuantum decDoubleSameQuantum
#define decFloatVersion decDoubleVersion
#include "decNumberLocal.h" /* local includes (need DECPMAX) */
#include "decCommon.c" /* non-arithmetic decFloat routines */
#include "decBasic.c" /* basic formats routines */
/* Below here will move to shared file as completed */

View File

@ -31,22 +31,24 @@
/* ------------------------------------------------------------------ */
/* decDouble.h -- Decimal 64-bit format module header */
/* ------------------------------------------------------------------ */
/* Please see decFloats.h for an overview and documentation details. */
/* ------------------------------------------------------------------ */
#if !defined(DECDOUBLE)
#define DECDOUBLE
#define DECDOUBLENAME "decimalDouble" /* Short name */
#define DECDOUBLENAME "decimalDouble" /* Short name */
#define DECDOUBLETITLE "Decimal 64-bit datum" /* Verbose name */
#define DECDOUBLEAUTHOR "Mike Cowlishaw" /* Who to blame */
/* parameters for decDoubles */
#define DECDOUBLE_Bytes 8 /* length */
#define DECDOUBLE_Pmax 16 /* maximum precision (digits) */
#define DECDOUBLE_Emin -383 /* minimum adjusted exponent */
#define DECDOUBLE_Emax 384 /* maximum adjusted exponent */
#define DECDOUBLE_Emin -383 /* minimum adjusted exponent */
#define DECDOUBLE_Emax 384 /* maximum adjusted exponent */
#define DECDOUBLE_EmaxD 3 /* maximum exponent digits */
#define DECDOUBLE_Bias 398 /* bias for the exponent */
#define DECDOUBLE_String 25 /* maximum string length, +1 */
#define DECDOUBLE_Bias 398 /* bias for the exponent */
#define DECDOUBLE_String 25 /* maximum string length, +1 */
#define DECDOUBLE_EconL 8 /* exponent continuation length */
#define DECDOUBLE_Declets 5 /* count of declets */
/* highest biased exponent (Elimit-1) */
@ -56,14 +58,11 @@
#include "decContext.h"
#include "decQuad.h"
/* The decDouble decimal 64-bit type, accessible by all sizes */
/* The decDouble decimal 64-bit type, accessible by various types */
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];
uint32_t words[DECDOUBLE_Bytes/4];
#if DECUSE64
uint64_t longs[DECDOUBLE_Bytes/8];
#endif
uint32_t words[DECDOUBLE_Bytes/4];
} decDouble;
/* ---------------------------------------------------------------- */
@ -76,7 +75,6 @@
extern decDouble * decDoubleFromBCD(decDouble *, int32_t, const uint8_t *, int32_t);
extern decDouble * decDoubleFromInt32(decDouble *, int32_t);
extern decDouble * decDoubleFromPacked(decDouble *, int32_t, const uint8_t *);
extern decDouble * decDoubleFromPackedChecked(decDouble *, int32_t, const uint8_t *);
extern decDouble * decDoubleFromString(decDouble *, const char *, decContext *);
extern decDouble * decDoubleFromUInt32(decDouble *, uint32_t);
extern decDouble * decDoubleFromWider(decDouble *, const decQuad *, decContext *);
@ -162,8 +160,7 @@
/* decNumber conversions; these are implemented as macros so as not */
/* 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 decDoubleFromNumber(dq, dn, set) decimal64FromNumber((decimal64 *)(dq), dn, set)
#define decDoubleFromNumber(dq, dn, set) (decDouble *)decimal64FromNumber((decimal64 *)(dq), dn, set)
#endif

File diff suppressed because it is too large Load Diff

View File

@ -46,7 +46,7 @@
#define DECNEG 0x80 /* Sign; 1=negative, 0=positive or zero */
#define DECINF 0x40 /* 1=Infinity */
#define DECNAN 0x20 /* 1=NaN */
#define DECSNAN 0x10 /* 1=sNaN */
#define DECSNAN 0x10 /* 1=sNaN */
/* The remaining bits are reserved; they must be 0 */
#define DECSPECIAL (DECINF|DECNAN|DECSNAN) /* any special value */
@ -124,7 +124,7 @@
uint8_t * decNumberGetBCD(const decNumber *, uint8_t *);
decNumber * decNumberSetBCD(decNumber *, const uint8_t *, uint32_t);
/* Operators and elementary functions */
/* Operators and elementary functions */
decNumber * decNumberAbs(decNumber *, const decNumber *, decContext *);
decNumber * decNumberAdd(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberAnd(decNumber *, const decNumber *, const decNumber *, decContext *);
@ -185,7 +185,7 @@
/* Macros for testing decNumber *dn */
#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 decNumberIsNaN(dn) (((dn)->bits&(DECNAN|DECSNAN))!=0)
#define decNumberIsNegative(dn) (((dn)->bits&DECNEG)!=0)

View File

@ -31,48 +31,42 @@
/* ------------------------------------------------------------------ */
/* 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, */
/* 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. */
/* ------------------------------------------------------------------ */
#if !defined(DECNUMBERLOC)
#define DECNUMBERLOC
#define DECVERSION "decNumber 3.61" /* Package Version [16 max.] */
#define DECVERSION "decNumber 3.53" /* Package Version [16 max.] */
#define DECNLAUTHOR "Mike Cowlishaw" /* Who to blame */
#include <stdlib.h> /* for abs */
#include <string.h> /* for memset, strcpy */
#include "dconfig.h" /* for WORDS_BIGENDIAN */
/* Conditional code flag -- set this to match hardware platform */
#if !defined(DECLITEND)
#define DECLITEND 1 /* 1=little-endian, 0=big-endian */
/* 1=little-endian, 0=big-endian */
#if WORDS_BIGENDIAN
#define DECLITEND 0
#else
#define DECLITEND 1
#endif
/* Conditional code flag -- set this to 1 for best performance */
#if !defined(DECUSE64)
#define DECUSE64 1 /* 1=use int64s, 0=int32 & smaller only */
#endif
/* Conditional check flags -- set these to 0 for best performance */
#if !defined(DECCHECK)
#define DECCHECK 0 /* 1 to enable robust checking */
#endif
#if !defined(DECALLOC)
#define DECALLOC 0 /* 1 to enable memory accounting */
#endif
#if !defined(DECTRACE)
#define DECTRACE 0 /* 1 to trace certain internals, etc. */
#endif
/* Tuning parameter for decNumber (arbitrary precision) module */
#if !defined(DECBUFFER)
#define DECBUFFER 36 /* Size basis for local buffers. This */
/* should be a common maximum precision */
/* rounded up to a multiple of 4; must */
/* be zero or positive. */
#endif
/* ---------------------------------------------------------------- */
/* Definitions for all modules (general-purpose) */
@ -82,33 +76,33 @@
/* not use int or long directly. */
#define Flag uint8_t
#define Byte int8_t
#define uByte uint8_t
#define Short int16_t
#define uByte uint8_t
#define Short int16_t
#define uShort uint16_t
#define Int int32_t
#define uInt uint32_t
#define Unit decNumberUnit
#if DECUSE64
#define Long int64_t
#define uLong uint64_t
#define uLong uint64_t
#endif
/* Development-use definitions */
typedef long int LI; /* for printf arguments only */
#define DECNOINT 0 /* 1 to check no internal use of 'int' */
/* or stdint types */
#if DECNOINT
/* if these interfere with your C includes, do not set DECNOINT */
#define int ? /* enable to ensure that plain C 'int' */
#define long ?? /* .. or 'long' types are not used */
#define int ? /* enable to ensure that plain C 'int' */
#define long ?? /* .. or 'long' types are not used */
#endif
/* Shared lookup tables */
extern const uByte DECSTICKYTAB[10]; /* re-round digits if sticky */
extern const uInt DECPOWERS[10]; /* powers of ten table */
/* The following are included from decDPD.h */
extern const uShort DPD2BIN[1024]; /* DPD -> 0-999 */
extern const uShort BIN2DPD[1000]; /* 0-999 -> DPD */
#include "decDPDSymbols.h"
extern const uShort DPD2BIN[1024]; /* DPD -> 0-999 */
extern const uShort BIN2DPD[1000]; /* 0-999 -> DPD */
extern const uInt DPD2BINK[1024]; /* DPD -> 0-999000 */
extern const uInt DPD2BINM[1024]; /* DPD -> 0-999000000 */
extern const uByte DPD2BCD8[4096]; /* DPD -> ddd + len */
@ -117,42 +111,32 @@
/* 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; */
/* 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; */
/* it seems to optimize better than some others tried */
/* it seems to optimize better than some others tried */
#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; \
v0=v & 0xffff; v1=v>>16; \
w0=u0*v0; \
t=u1*v0 + (w0>>16); \
t=u1*v0 + (w0>>16); \
w1=t & 0xffff; w2=t>>16; \
w1=u0*v1 + w1; \
(w)=u1*v1 + w2 + (w1>>16);}
/* ROUNDUP -- round an integer up to a multiple of 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 */
#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; these */
/* require locally declared variables, but do not violate strict */
/* aliasing or alignment (as did the UINTAT simple cast to uInt). */
/* Variables needed are uswork, uiwork, etc. [so do not use at same */
/* level in an expression, e.g., UBTOUI(x)==UBTOUI(y) may fail]. */
/* 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)
/* References to multi-byte sequences under different sizes */
/* Refer to a uInt from four bytes starting at a char* or uByte*, */
/* etc. */
#define UINTAT(b) (*((uInt *)(b)))
#define USHORTAT(b) (*((uShort *)(b)))
#define UBYTEAT(b) (*((uByte *)(b)))
/* X10 and X100 -- multiply integer i by 10 or 100 */
/* [shifts are usually faster than multiply; could be conditional] */
@ -165,7 +149,7 @@
/* Useful constants */
#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')
@ -188,7 +172,7 @@
#error Minimum exponent mismatch
#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 */
#if DECDPUN==1
#define DECDPUNMAX 9
@ -269,7 +253,7 @@
/* D2N -- return the number of decNumber structs that would be */
/* needed to contain that number of digits (and the initial */
/* decNumber struct) safely. Note that one Unit is included in the */
/* initial structure. Used for allocating space that is aligned on */
/* initial structure. Used for allocating space that is aligned on */
/* a decNumber struct boundary. */
#define D2N(d) \
((((SD2U(d)-1)*sizeof(Unit))+sizeof(decNumber)*2-1)/sizeof(decNumber))
@ -277,7 +261,7 @@
/* TODIGIT -- macro to remove the leading digit from the unsigned */
/* integer u at column cut (counting from the right, LSD=0) and */
/* place it as an ASCII character into the character pointed to by */
/* c. Note that cut must be <= 9, and the maximum value for u is */
/* c. Note that cut must be <= 9, and the maximum value for u is */
/* 2,000,000,000 (as is needed for negative exponents of */
/* subnormals). The unsigned integer pow is used as a temporary */
/* variable. */
@ -290,7 +274,7 @@
pow/=2; \
if ((u)>=pow) {(u)-=pow; *(c)+=4;} \
pow/=2; \
} \
} \
if ((u)>=pow) {(u)-=pow; *(c)+=2;} \
pow/=2; \
if ((u)>=pow) {(u)-=pow; *(c)+=1;} \
@ -305,9 +289,9 @@
/* number, whose coefficient is a string of bcd8 uBytes */
typedef struct {
uByte *msd; /* -> most significant digit */
uByte *lsd; /* -> least ditto */
uByte *lsd; /* -> least ditto */
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 */
} bcdnum;
@ -324,12 +308,12 @@
#define DECWORDS (DECBYTES/4)
#define DECWWORDS (DECWBYTES/4)
#if DECLITEND
#define DFBYTE(df, off) ((df)->bytes[DECBYTES-1-(off)])
#define DFWORD(df, off) ((df)->words[DECWORDS-1-(off)])
#define DFWORD(df, off) ((df)->words[DECWORDS-1-(off)])
#define DFBYTE(df, off) ((df)->bytes[DECBYTES-1-(off)])
#define DFWWORD(dfw, off) ((dfw)->words[DECWWORDS-1-(off)])
#else
#define DFBYTE(df, off) ((df)->bytes[off])
#define DFWORD(df, off) ((df)->words[off])
#define DFWORD(df, off) ((df)->words[off])
#define DFBYTE(df, off) ((df)->bytes[off])
#define DFWWORD(dfw, off) ((dfw)->words[off])
#endif
@ -342,6 +326,7 @@
#define DFISSNAN(df) ((DFWORD(df, 0)&0x7e000000)==0x7e000000)
/* Shared lookup tables */
#include "decCommonSymbols.h"
extern const uInt DECCOMBMSD[64]; /* Combination field -> MSD */
extern const uInt DECCOMBFROM[48]; /* exp+msd -> Combination */
@ -353,7 +338,7 @@
/* Format-dependent macros and constants */
#if defined(DECPMAX)
/* Useful constants */
/* Useful constants */
#define DECPMAX9 (ROUNDUP(DECPMAX, 9)/9) /* 'Pmax' in 10**9s */
/* Top words for a zero */
#define SINGLEZERO 0x22500000
@ -365,10 +350,10 @@
/* DFISZERO -- test for (any) zero */
/* DFISCCZERO -- test for coefficient continuation being zero */
/* DFISCC01 -- test for coefficient contains only 0s and 1s */
/* DFISINT -- test for finite and exponent q=0 */
/* DFISINT -- test for finite and exponent q=0 */
/* DFISUINT01 -- test for sign=0, finite, exponent q=0, and */
/* MSD=0 or 1 */
/* ZEROWORD is also defined here. */
/* ZEROWORD is also defined here. */
/* In DFISZERO the first test checks the least-significant word */
/* (most likely to be non-zero); the penultimate tests MSD and */
/* DPDs in the signword, and the final test excludes specials and */
@ -422,36 +407,26 @@
|| ((dpd)&(((uInt)0x6e)<<(k)))!=(((uInt)0x6e)<<(k)))
/* declet is at offset k (a multiple of 2) in a pair of uInts: */
/* [the top 2 bits will always be in the more-significant uInt] */
#define CANONDPDTWO(hi, lo, k) (((hi)&(0x300>>(32-(k))))==0 \
#define CANONDPDTWO(hi, lo, k) (((hi)&(0x300>>(32-(k))))==0 \
|| ((hi)&(0x6e>>(32-(k))))!=(0x6e>>(32-(k))) \
|| ((lo)&(((uInt)0x6e)<<(k)))!=(((uInt)0x6e)<<(k)))
/* Macro to test whether a full-length (length DECPMAX) BCD8 */
/* coefficient, starting at uByte u, is all zeros */
/* Test just the LSWord first, then the remainder as a sequence */
/* of tests in order to avoid same-level use of UBTOUI */
/* coefficient is zero */
/* test just the LSWord first, then the remainder */
#if DECPMAX==7
#define ISCOEFFZERO(u) ( \
UBTOUI((u)+DECPMAX-4)==0 \
&& UBTOUS((u)+DECPMAX-6)==0 \
&& *(u)==0)
#define ISCOEFFZERO(u) (UINTAT((u)+DECPMAX-4)==0 \
&& UINTAT((u)+DECPMAX-7)==0)
#elif DECPMAX==16
#define ISCOEFFZERO(u) ( \
UBTOUI((u)+DECPMAX-4)==0 \
&& UBTOUI((u)+DECPMAX-8)==0 \
&& UBTOUI((u)+DECPMAX-12)==0 \
&& UBTOUI(u)==0)
#define ISCOEFFZERO(u) (UINTAT((u)+DECPMAX-4)==0 \
&& (UINTAT((u)+DECPMAX-8)+UINTAT((u)+DECPMAX-12) \
+UINTAT((u)+DECPMAX-16))==0)
#elif DECPMAX==34
#define ISCOEFFZERO(u) ( \
UBTOUI((u)+DECPMAX-4)==0 \
&& UBTOUI((u)+DECPMAX-8)==0 \
&& UBTOUI((u)+DECPMAX-12)==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)
#define ISCOEFFZERO(u) (UINTAT((u)+DECPMAX-4)==0 \
&& (UINTAT((u)+DECPMAX-8) +UINTAT((u)+DECPMAX-12) \
+UINTAT((u)+DECPMAX-16)+UINTAT((u)+DECPMAX-20) \
+UINTAT((u)+DECPMAX-24)+UINTAT((u)+DECPMAX-28) \
+UINTAT((u)+DECPMAX-32)+USHORTAT((u)+DECPMAX-34))==0)
#endif
/* Macros and masks for the exponent continuation field and MSD */
@ -473,24 +448,29 @@
#define ECONNANMASK ((0x01ffffff>>(32-6-DECECONL))<<(32-6-DECECONL))
/* Macros to decode the coefficient in a finite decFloat *df into */
/* a BCD string (uByte *bcdin) of length DECPMAX uBytes. */
/* a BCD string (uByte *bcdin) of length DECPMAX uBytes */
/* In-line sequence to convert least significant 10 bits of uInt */
/* dpd to three BCD8 digits starting at uByte u. Note that an */
/* extra byte is written to the right of the three digits because */
/* four bytes are moved at a time for speed; the alternative */
/* macro moves exactly three bytes (usually slower). */
#define dpd2bcd8(u, dpd) memcpy(u, &DPD2BCD8[((dpd)&0x3ff)*4], 4)
#define dpd2bcd83(u, dpd) memcpy(u, &DPD2BCD8[((dpd)&0x3ff)*4], 3)
/* In-line sequence to convert 10 bits at right end of uInt dpd */
/* to three BCD8 digits starting at uByte u. Note that an extra */
/* byte is written to the right of the three digits because this */
/* moves four at a time for speed; the alternative macro moves */
/* exactly three bytes */
#define dpd2bcd8(u, dpd) { \
UINTAT(u)=UINTAT(&DPD2BCD8[((dpd)&0x3ff)*4]);}
#define dpd2bcd83(u, dpd) { \
*(u)=DPD2BCD8[((dpd)&0x3ff)*4]; \
*(u+1)=DPD2BCD8[((dpd)&0x3ff)*4+1]; \
*(u+2)=DPD2BCD8[((dpd)&0x3ff)*4+2];}
/* Decode the declets. After extracting each one, it is decoded */
/* to BCD8 using a table lookup (also used for variable-length */
/* decode). Each DPD decode is 3 bytes BCD8 plus a one-byte */
/* length which is not used, here). Fixed-length 4-byte moves */
/* decode). Each DPD decode is 3 bytes BCD8 plus a one-byte */
/* length which is not used, here). Fixed-length 4-byte moves */
/* are fast, however, almost everywhere, and so are used except */
/* for the final three bytes (to avoid overrun). The code below */
/* is 36 instructions for Doubles and about 70 for Quads, even */
/* on IA32. */
/* on IA32. */
/* Two macros are defined for each format: */
/* GETCOEFF extracts the coefficient of the current format */
@ -498,7 +478,7 @@
/* The latter is a copy of the next-wider GETCOEFF using DFWWORD. */
#if DECPMAX==7
#define GETCOEFF(df, bcd) { \
#define GETCOEFF(df, bcd) { \
uInt sourhi=DFWORD(df, 0); \
*(bcd)=(uByte)DECCOMBMSD[sourhi>>26]; \
dpd2bcd8(bcd+1, sourhi>>10); \
@ -514,7 +494,7 @@
dpd2bcd83(bcd+13, sourlo);}
#elif DECPMAX==16
#define GETCOEFF(df, bcd) { \
#define GETCOEFF(df, bcd) { \
uInt sourhi=DFWORD(df, 0); \
uInt sourlo=DFWORD(df, 1); \
*(bcd)=(uByte)DECCOMBMSD[sourhi>>26]; \
@ -542,7 +522,7 @@
dpd2bcd83(bcd+31, sourlo);}
#elif DECPMAX==34
#define GETCOEFF(df, bcd) { \
#define GETCOEFF(df, bcd) { \
uInt sourhi=DFWORD(df, 0); \
uInt sourmh=DFWORD(df, 1); \
uInt sourml=DFWORD(df, 2); \
@ -560,12 +540,12 @@
dpd2bcd8(bcd+28, sourlo>>10); \
dpd2bcd83(bcd+31, sourlo);}
#define GETWCOEFF(df, bcd) {??} /* [should never be used] */
#define GETWCOEFF(df, bcd) {??} /* [should never be used] */
#endif
/* Macros to decode the coefficient in a finite decFloat *df into */
/* a base-billion uInt array, with the least-significant */
/* 0-999999999 'digit' at offset 0. */
/* 0-999999999 'digit' at offset 0. */
/* Decode the declets. After extracting each one, it is decoded */
/* to binary using a table lookup. Three tables are used; one */
@ -617,8 +597,8 @@
#endif
/* Macros to decode the coefficient in a finite decFloat *df into */
/* a base-thousand uInt array (of size DECLETS+1, to allow for */
/* the MSD), with the least-significant 0-999 'digit' at offset 0.*/
/* a base-thousand uInt array, with the least-significant 0-999 */
/* 'digit' at offset 0. */
/* Decode the declets. After extracting each one, it is decoded */
/* to binary using a table lookup. */
@ -660,72 +640,9 @@
(buf)[9]=DPD2BIN[((sourhi<<6) | (sourmh>>26))&0x3ff]; \
(buf)[10]=DPD2BIN[(sourhi>>4)&0x3ff]; \
(buf)[11]=DECCOMBMSD[sourhi>>26];}
#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) */
#if DECPMAX==7
#define DFSETNMAX(df) \

View File

@ -31,12 +31,12 @@
/* ------------------------------------------------------------------ */
/* 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 */
/* turn supports: */
/* conversions to and from string */
/* arithmetic routines */
/* utilities. */
/* utilities. */
/* Conversions from decNumber to and from densely packed decimal */
/* formats are provided by the decimal32 through decimal128 modules. */
/* ------------------------------------------------------------------ */
@ -51,8 +51,8 @@
/* */
/* bcd is the BCD bytes */
/* length is the length of the BCD array */
/* scale is the scale result */
/* dn is the decNumber */
/* scale is the scale result */
/* dn is the decNumber */
/* returns bcd, or NULL if error */
/* */
/* The number is converted to a BCD packed decimal byte array, */
@ -67,7 +67,7 @@
/* as necessary. */
/* */
/* If there is an error (that is, the decNumber has too many digits */
/* to fit in length bytes, or it is a NaN or Infinity), NULL is */
/* to fit in length bytes, or it is a NaN or Infinity), NULL is */
/* returned and the bcd and scale results are unchanged. Otherwise */
/* bcd is returned. */
/* ------------------------------------------------------------------ */
@ -86,9 +86,9 @@ uByte * decPackedFromNumber(uByte *bcd, Int length, Int *scale,
if (dn->digits>length*2-1 /* too long .. */
||(dn->bits & DECSPECIAL)) return NULL; /* .. or special -- hopeless */
if (dn->bits&DECNEG) obyte=DECPMINUS; /* set the sign .. */
else obyte=DECPPLUS;
*scale=-dn->exponent; /* .. and scale */
if (dn->bits&DECNEG) obyte=DECPMINUS; /* set the sign .. */
else obyte=DECPPLUS;
*scale=-dn->exponent; /* .. and scale */
/* loop from lowest (rightmost) byte */
out=bcd+length-1; /* -> final byte */
@ -141,7 +141,7 @@ uByte * decPackedFromNumber(uByte *bcd, Int length, Int *scale,
/* bcd is the BCD bytes */
/* length is the length of the BCD array */
/* scale is the scale associated with the BCD integer */
/* dn is the decNumber [with space for length*2 digits] */
/* dn is the decNumber [with space for length*2 digits] */
/* returns dn, or NULL if error */
/* */
/* The BCD packed decimal byte array, together with an associated */
@ -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 sign nibble was found, or a sign nibble was found before the */
/* final nibble. In these error cases, NULL is returned and the */
/* decNumber will be 0. */
/* decNumber will be 0. */
/* ------------------------------------------------------------------ */
decNumber * decPackedToNumber(const uByte *bcd, Int length,
const Int *scale, decNumber *dn) {
@ -165,7 +165,7 @@ decNumber * decPackedToNumber(const uByte *bcd, Int length,
const uByte *first; /* -> first non-zero byte */
uInt nib; /* work nibble */
Unit *up=dn->lsu; /* output pointer */
Int digits; /* digits count */
Int digits; /* digits count */
Int cut=0; /* phase of output */
decNumberZero(dn); /* default result */
@ -182,7 +182,7 @@ decNumber * decPackedToNumber(const uByte *bcd, Int length,
/* leave as 1] */
/* 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 ((dn->digits-*scale-1)<-DECNUMMAXE) { /* underflow */
decNumberZero(dn);

View File

@ -36,7 +36,7 @@
#define DECPACKED
#define DECPNAME "decPacked" /* Short 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 */
@ -47,12 +47,12 @@
/* Sign nibble constants */
#if !defined(DECPPLUSALT)
#define DECPPLUSALT 0x0A /* alternate plus nibble */
#define DECPMINUSALT 0x0B /* alternate minus nibble */
#define DECPPLUS 0x0C /* preferred plus nibble */
#define DECPMINUS 0x0D /* preferred minus nibble */
#define DECPPLUSALT2 0x0E /* alternate plus nibble */
#define DECPUNSIGNED 0x0F /* alternate plus nibble (unsigned) */
#define DECPPLUSALT 0x0A /* alternate plus nibble */
#define DECPMINUSALT 0x0B /* alternate minus nibble */
#define DECPPLUS 0x0C /* preferred plus nibble */
#define DECPMINUS 0x0D /* preferred minus nibble */
#define DECPPLUSALT2 0x0E /* alternate plus nibble */
#define DECPUNSIGNED 0x0F /* alternate plus nibble (unsigned) */
#endif
/* ---------------------------------------------------------------- */

View File

@ -34,111 +34,111 @@
/* This module comprises decQuad operations (including conversions) */
/* ------------------------------------------------------------------ */
#include "decContext.h" /* public includes */
#include "decContext.h" /* public includes */
#include "decQuad.h" /* .. */
/* Constant mappings for shared code */
#define DECPMAX DECQUAD_Pmax
#define DECEMIN DECQUAD_Emin
#define DECEMAX DECQUAD_Emax
#define DECPMAX DECQUAD_Pmax
#define DECEMIN DECQUAD_Emin
#define DECEMAX DECQUAD_Emax
#define DECEMAXD DECQUAD_EmaxD
#define DECBYTES DECQUAD_Bytes
#define DECSTRING DECQUAD_String
#define DECECONL DECQUAD_EconL
#define DECBIAS DECQUAD_Bias
#define DECLETS DECQUAD_Declets
#define DECBIAS DECQUAD_Bias
#define DECLETS DECQUAD_Declets
#define DECQTINY (-DECQUAD_Bias)
/* Type and function mappings for shared code */
#define decFloat decQuad /* Type name */
#define decFloat decQuad /* Type name */
/* Utilities and conversions (binary results, extractors, etc.) */
#define decFloatFromBCD decQuadFromBCD
#define decFloatFromInt32 decQuadFromInt32
#define decFloatFromPacked decQuadFromPacked
#define decFloatFromPackedChecked decQuadFromPackedChecked
#define decFloatFromString decQuadFromString
#define decFloatFromUInt32 decQuadFromUInt32
#define decFloatFromWider decQuadFromWider
#define decFloatGetCoefficient decQuadGetCoefficient
#define decFloatGetExponent decQuadGetExponent
#define decFloatSetCoefficient decQuadSetCoefficient
#define decFloatSetExponent decQuadSetExponent
#define decFloatShow decQuadShow
#define decFloatToBCD decQuadToBCD
#define decFloatToEngString decQuadToEngString
#define decFloatToInt32 decQuadToInt32
#define decFloatToInt32Exact decQuadToInt32Exact
#define decFloatToPacked decQuadToPacked
#define decFloatToString decQuadToString
#define decFloatToUInt32 decQuadToUInt32
#define decFloatToUInt32Exact decQuadToUInt32Exact
#define decFloatToWider decQuadToWider
#define decFloatZero decQuadZero
#define decFloatFromBCD decQuadFromBCD
#define decFloatFromInt32 decQuadFromInt32
#define decFloatFromPacked decQuadFromPacked
#define decFloatFromString decQuadFromString
#define decFloatFromUInt32 decQuadFromUInt32
#define decFloatFromWider decQuadFromWider
#define decFloatGetCoefficient decQuadGetCoefficient
#define decFloatGetExponent decQuadGetExponent
#define decFloatSetCoefficient decQuadSetCoefficient
#define decFloatSetExponent decQuadSetExponent
#define decFloatShow decQuadShow
#define decFloatToBCD decQuadToBCD
#define decFloatToEngString decQuadToEngString
#define decFloatToInt32 decQuadToInt32
#define decFloatToInt32Exact decQuadToInt32Exact
#define decFloatToPacked decQuadToPacked
#define decFloatToString decQuadToString
#define decFloatToUInt32 decQuadToUInt32
#define decFloatToUInt32Exact decQuadToUInt32Exact
#define decFloatToWider decQuadToWider
#define decFloatZero decQuadZero
/* Computational (result is a decFloat) */
#define decFloatAbs decQuadAbs
#define decFloatAdd decQuadAdd
#define decFloatAnd decQuadAnd
#define decFloatDivide decQuadDivide
#define decFloatDivideInteger decQuadDivideInteger
#define decFloatFMA decQuadFMA
#define decFloatInvert decQuadInvert
#define decFloatLogB decQuadLogB
#define decFloatMax decQuadMax
#define decFloatMaxMag decQuadMaxMag
#define decFloatMin decQuadMin
#define decFloatMinMag decQuadMinMag
#define decFloatMinus decQuadMinus
#define decFloatMultiply decQuadMultiply
#define decFloatNextMinus decQuadNextMinus
#define decFloatNextPlus decQuadNextPlus
#define decFloatNextToward decQuadNextToward
#define decFloatOr decQuadOr
#define decFloatPlus decQuadPlus
#define decFloatQuantize decQuadQuantize
#define decFloatReduce decQuadReduce
#define decFloatRemainder decQuadRemainder
#define decFloatRemainderNear decQuadRemainderNear
#define decFloatRotate decQuadRotate
#define decFloatScaleB decQuadScaleB
#define decFloatShift decQuadShift
#define decFloatSubtract decQuadSubtract
#define decFloatToIntegralValue decQuadToIntegralValue
#define decFloatToIntegralExact decQuadToIntegralExact
#define decFloatXor decQuadXor
#define decFloatAbs decQuadAbs
#define decFloatAdd decQuadAdd
#define decFloatAnd decQuadAnd
#define decFloatDivide decQuadDivide
#define decFloatDivideInteger decQuadDivideInteger
#define decFloatFMA decQuadFMA
#define decFloatInvert decQuadInvert
#define decFloatLogB decQuadLogB
#define decFloatMax decQuadMax
#define decFloatMaxMag decQuadMaxMag
#define decFloatMin decQuadMin
#define decFloatMinMag decQuadMinMag
#define decFloatMinus decQuadMinus
#define decFloatMultiply decQuadMultiply
#define decFloatNextMinus decQuadNextMinus
#define decFloatNextPlus decQuadNextPlus
#define decFloatNextToward decQuadNextToward
#define decFloatOr decQuadOr
#define decFloatPlus decQuadPlus
#define decFloatQuantize decQuadQuantize
#define decFloatReduce decQuadReduce
#define decFloatRemainder decQuadRemainder
#define decFloatRemainderNear decQuadRemainderNear
#define decFloatRotate decQuadRotate
#define decFloatScaleB decQuadScaleB
#define decFloatShift decQuadShift
#define decFloatSubtract decQuadSubtract
#define decFloatToIntegralValue decQuadToIntegralValue
#define decFloatToIntegralExact decQuadToIntegralExact
#define decFloatXor decQuadXor
/* Comparisons */
#define decFloatCompare decQuadCompare
#define decFloatCompareSignal decQuadCompareSignal
#define decFloatCompareTotal decQuadCompareTotal
#define decFloatCompareTotalMag decQuadCompareTotalMag
#define decFloatCompare decQuadCompare
#define decFloatCompareSignal decQuadCompareSignal
#define decFloatCompareTotal decQuadCompareTotal
#define decFloatCompareTotalMag decQuadCompareTotalMag
/* Copies */
#define decFloatCanonical decQuadCanonical
#define decFloatCopy decQuadCopy
#define decFloatCopyAbs decQuadCopyAbs
#define decFloatCopyNegate decQuadCopyNegate
#define decFloatCopySign decQuadCopySign
#define decFloatCanonical decQuadCanonical
#define decFloatCopy decQuadCopy
#define decFloatCopyAbs decQuadCopyAbs
#define decFloatCopyNegate decQuadCopyNegate
#define decFloatCopySign decQuadCopySign
/* Non-computational */
#define decFloatClass decQuadClass
#define decFloatClassString decQuadClassString
#define decFloatDigits decQuadDigits
#define decFloatIsCanonical decQuadIsCanonical
#define decFloatIsFinite decQuadIsFinite
#define decFloatIsInfinite decQuadIsInfinite
#define decFloatIsInteger decQuadIsInteger
#define decFloatIsNaN decQuadIsNaN
#define decFloatIsNormal decQuadIsNormal
#define decFloatIsSignaling decQuadIsSignaling
#define decFloatIsSignalling decQuadIsSignalling
#define decFloatIsSigned decQuadIsSigned
#define decFloatIsSubnormal decQuadIsSubnormal
#define decFloatIsZero decQuadIsZero
#define decFloatRadix decQuadRadix
#define decFloatSameQuantum decQuadSameQuantum
#define decFloatVersion decQuadVersion
#define decFloatClass decQuadClass
#define decFloatClassString decQuadClassString
#define decFloatDigits decQuadDigits
#define decFloatIsCanonical decQuadIsCanonical
#define decFloatIsFinite decQuadIsFinite
#define decFloatIsInfinite decQuadIsInfinite
#define decFloatIsInteger decQuadIsInteger
#define decFloatIsNaN decQuadIsNaN
#define decFloatIsNormal decQuadIsNormal
#define decFloatIsSignaling decQuadIsSignaling
#define decFloatIsSignalling decQuadIsSignalling
#define decFloatIsSigned decQuadIsSigned
#define decFloatIsSubnormal decQuadIsSubnormal
#define decFloatIsZero decQuadIsZero
#define decFloatRadix decQuadRadix
#define decFloatSameQuantum decQuadSameQuantum
#define decFloatVersion decQuadVersion
#include "decNumberLocal.h" /* local includes (need DECPMAX) */
#include "decCommon.c" /* non-arithmetic decFloat routines */

View File

@ -31,25 +31,27 @@
/* ------------------------------------------------------------------ */
/* decQuad.h -- Decimal 128-bit format module header */
/* ------------------------------------------------------------------ */
/* Please see decFloats.h for an overview and documentation details. */
/* ------------------------------------------------------------------ */
/* This include file is always included by decSingle and decDouble, */
/* and therefore also holds useful constants used by all three. */
/* and therefore also holds useful constants used by all three. */
#if !defined(DECQUAD)
#define DECQUAD
#define DECQUADNAME "decimalQuad" /* Short name */
#define DECQUADTITLE "Decimal 128-bit datum" /* Verbose name */
#define DECQUADAUTHOR "Mike Cowlishaw" /* Who to blame */
#define DECQUADAUTHOR "Mike Cowlishaw" /* Who to blame */
/* parameters for decQuads */
#define DECQUAD_Bytes 16 /* length */
#define DECQUAD_Bytes 16 /* length */
#define DECQUAD_Pmax 34 /* maximum precision (digits) */
#define DECQUAD_Emin -6143 /* minimum adjusted exponent */
#define DECQUAD_Emax 6144 /* maximum adjusted exponent */
#define DECQUAD_EmaxD 4 /* maximum exponent digits */
#define DECQUAD_Emin -6143 /* minimum adjusted exponent */
#define DECQUAD_Emax 6144 /* maximum adjusted exponent */
#define DECQUAD_EmaxD 4 /* maximum exponent digits */
#define DECQUAD_Bias 6176 /* bias for the exponent */
#define DECQUAD_String 43 /* maximum string length, +1 */
#define DECQUAD_EconL 12 /* exponent continuation length */
#define DECQUAD_String 43 /* maximum string length, +1 */
#define DECQUAD_EconL 12 /* exponent continuation length */
#define DECQUAD_Declets 11 /* count of declets */
/* highest biased exponent (Elimit-1) */
#define DECQUAD_Ehigh (DECQUAD_Emax + DECQUAD_Bias - (DECQUAD_Pmax-1))
@ -57,14 +59,11 @@
/* Required include */
#include "decContext.h"
/* The decQuad decimal 128-bit type, accessible by all sizes */
/* The decQuad decimal 128-bit type, accessible by various types */
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];
uint32_t words[DECQUAD_Bytes/4];
#if DECUSE64
uint64_t longs[DECQUAD_Bytes/8];
#endif
uint32_t words[DECQUAD_Bytes/4];
} decQuad;
/* ---------------------------------------------------------------- */
@ -73,21 +72,21 @@
/* sign and special values [top 32-bits; last two bits are don't-care
for Infinity on input, last bit don't-care for NaNs] */
#define DECFLOAT_Sign 0x80000000 /* 1 00000 00 Sign */
#define DECFLOAT_Sign 0x80000000 /* 1 00000 00 Sign */
#define DECFLOAT_NaN 0x7c000000 /* 0 11111 00 NaN generic */
#define DECFLOAT_qNaN 0x7c000000 /* 0 11111 00 qNaN */
#define DECFLOAT_sNaN 0x7e000000 /* 0 11111 10 sNaN */
#define DECFLOAT_qNaN 0x7c000000 /* 0 11111 00 qNaN */
#define DECFLOAT_sNaN 0x7e000000 /* 0 11111 10 sNaN */
#define DECFLOAT_Inf 0x78000000 /* 0 11110 00 Infinity */
#define DECFLOAT_MinSp 0x78000000 /* minimum special value */
/* [specials are all >=MinSp] */
/* Sign nibble constants */
#if !defined(DECPPLUSALT)
#define DECPPLUSALT 0x0A /* alternate plus nibble */
#define DECPMINUSALT 0x0B /* alternate minus nibble */
#define DECPPLUS 0x0C /* preferred plus nibble */
#define DECPMINUS 0x0D /* preferred minus nibble */
#define DECPPLUSALT2 0x0E /* alternate plus nibble */
#define DECPUNSIGNED 0x0F /* alternate plus nibble (unsigned) */
#define DECPPLUSALT 0x0A /* alternate plus nibble */
#define DECPMINUSALT 0x0B /* alternate minus nibble */
#define DECPPLUS 0x0C /* preferred plus nibble */
#define DECPMINUS 0x0D /* preferred minus nibble */
#define DECPPLUSALT2 0x0E /* alternate plus nibble */
#define DECPUNSIGNED 0x0F /* alternate plus nibble (unsigned) */
#endif
/* ---------------------------------------------------------------- */
@ -100,7 +99,6 @@
extern decQuad * decQuadFromBCD(decQuad *, int32_t, const uint8_t *, int32_t);
extern decQuad * decQuadFromInt32(decQuad *, int32_t);
extern decQuad * decQuadFromPacked(decQuad *, int32_t, const uint8_t *);
extern decQuad * decQuadFromPackedChecked(decQuad *, int32_t, const uint8_t *);
extern decQuad * decQuadFromString(decQuad *, const char *, decContext *);
extern decQuad * decQuadFromUInt32(decQuad *, uint32_t);
extern int32_t decQuadGetCoefficient(const decQuad *, uint8_t *);
@ -184,8 +182,7 @@
/* decNumber conversions; these are implemented as macros so as not */
/* 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 decQuadFromNumber(dq, dn, set) decimal128FromNumber((decimal128 *)(dq), dn, set)
#define decQuadFromNumber(dq, dn, set) (decQuad *)decimal128FromNumber((decimal128 *)(dq), dn, set)
#endif

View File

@ -31,20 +31,22 @@
/* ------------------------------------------------------------------ */
/* 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 */
/* Constant mappings for shared code */
#define DECPMAX DECSINGLE_Pmax
#define DECEMIN DECSINGLE_Emin
#define DECEMAX DECSINGLE_Emax
#define DECPMAX DECSINGLE_Pmax
#define DECEMIN DECSINGLE_Emin
#define DECEMAX DECSINGLE_Emax
#define DECEMAXD DECSINGLE_EmaxD
#define DECBYTES DECSINGLE_Bytes
#define DECSTRING DECSINGLE_String
#define DECECONL DECSINGLE_EconL
#define DECBIAS DECSINGLE_Bias
#define DECLETS DECSINGLE_Declets
#define DECBIAS DECSINGLE_Bias
#define DECLETS DECSINGLE_Declets
#define DECQTINY (-DECSINGLE_Bias)
/* parameters of next-wider format */
#define DECWBYTES DECDOUBLE_Bytes
@ -53,30 +55,29 @@
#define DECWBIAS DECDOUBLE_Bias
/* Type and function mappings for shared code */
#define decFloat decSingle /* Type name */
#define decFloatWider decDouble /* Type name */
#define decFloat decSingle /* Type name */
#define decFloatWider decDouble /* Type name */
/* Utility (binary results, extractors, etc.) */
#define decFloatFromBCD decSingleFromBCD
#define decFloatFromPacked decSingleFromPacked
#define decFloatFromPackedChecked decSingleFromPackedChecked
#define decFloatFromString decSingleFromString
#define decFloatFromWider decSingleFromWider
#define decFloatGetCoefficient decSingleGetCoefficient
#define decFloatGetExponent decSingleGetExponent
#define decFloatSetCoefficient decSingleSetCoefficient
#define decFloatSetExponent decSingleSetExponent
#define decFloatShow decSingleShow
#define decFloatToBCD decSingleToBCD
#define decFloatToEngString decSingleToEngString
#define decFloatToPacked decSingleToPacked
#define decFloatToString decSingleToString
#define decFloatToWider decSingleToWider
#define decFloatZero decSingleZero
#define decFloatFromBCD decSingleFromBCD
#define decFloatFromPacked decSingleFromPacked
#define decFloatFromString decSingleFromString
#define decFloatFromWider decSingleFromWider
#define decFloatGetCoefficient decSingleGetCoefficient
#define decFloatGetExponent decSingleGetExponent
#define decFloatSetCoefficient decSingleSetCoefficient
#define decFloatSetExponent decSingleSetExponent
#define decFloatShow decSingleShow
#define decFloatToBCD decSingleToBCD
#define decFloatToEngString decSingleToEngString
#define decFloatToPacked decSingleToPacked
#define decFloatToString decSingleToString
#define decFloatToWider decSingleToWider
#define decFloatZero decSingleZero
/* Non-computational */
#define decFloatRadix decSingleRadix
#define decFloatVersion decSingleVersion
#define decFloatRadix decSingleRadix
#define decFloatVersion decSingleVersion
#include "decNumberLocal.h" /* local includes (need DECPMAX) */
#include "decCommon.c" /* non-basic decFloat routines */

View File

@ -31,22 +31,24 @@
/* ------------------------------------------------------------------ */
/* decSingle.h -- Decimal 32-bit format module header */
/* ------------------------------------------------------------------ */
/* Please see decFloats.h for an overview and documentation details. */
/* ------------------------------------------------------------------ */
#if !defined(DECSINGLE)
#define DECSINGLE
#define DECSINGLENAME "decSingle" /* Short name */
#define DECSINGLENAME "decSingle" /* Short name */
#define DECSINGLETITLE "Decimal 32-bit datum" /* Verbose name */
#define DECSINGLEAUTHOR "Mike Cowlishaw" /* Who to blame */
/* parameters for decSingles */
#define DECSINGLE_Bytes 4 /* length */
#define DECSINGLE_Pmax 7 /* maximum precision (digits) */
#define DECSINGLE_Emin -95 /* minimum adjusted exponent */
#define DECSINGLE_Emax 96 /* maximum adjusted exponent */
#define DECSINGLE_Emin -95 /* minimum adjusted exponent */
#define DECSINGLE_Emax 96 /* maximum adjusted exponent */
#define DECSINGLE_EmaxD 3 /* maximum exponent digits */
#define DECSINGLE_Bias 101 /* bias for the exponent */
#define DECSINGLE_String 16 /* maximum string length, +1 */
#define DECSINGLE_String 16 /* maximum string length, +1 */
#define DECSINGLE_EconL 6 /* exponent continuation length */
#define DECSINGLE_Declets 2 /* count of declets */
/* highest biased exponent (Elimit-1) */
@ -57,11 +59,11 @@
#include "decQuad.h"
#include "decDouble.h"
/* The decSingle decimal 32-bit type, accessible by all sizes */
/* The decSingle decimal 32-bit type, accessible by various types */
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];
uint32_t words[DECSINGLE_Bytes/4];
uint32_t words[DECSINGLE_Bytes/4];
} decSingle;
/* ---------------------------------------------------------------- */
@ -73,7 +75,6 @@
/* Utilities (binary argument(s) or result, extractors, etc.) */
extern decSingle * decSingleFromBCD(decSingle *, int32_t, const uint8_t *, int32_t);
extern decSingle * decSingleFromPacked(decSingle *, int32_t, const uint8_t *);
extern decSingle * decSingleFromPackedChecked(decSingle *, int32_t, const uint8_t *);
extern decSingle * decSingleFromString(decSingle *, const char *, decContext *);
extern decSingle * decSingleFromWider(decSingle *, const decDouble *, decContext *);
extern int32_t decSingleGetCoefficient(const decSingle *, uint8_t *);
@ -96,8 +97,7 @@
/* decNumber conversions; these are implemented as macros so as not */
/* 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 decSingleFromNumber(dq, dn, set) decimal32FromNumber((decimal32 *)(dq), dn, set)
#define decSingleFromNumber(dq, dn, set) (decSingle *)decimal32FromNumber((decimal32 *)(dq), dn, set)
#endif

View File

@ -42,11 +42,11 @@
#include <string.h> /* [for memset/memcpy] */
#include <stdio.h> /* [for printf] */
#include "dconfig.h" /* GCC definitions */
#define DECNUMDIGITS 34 /* make decNumbers with space for 34 */
#include "dconfig.h" /* GCC definitions */
#define DECNUMDIGITS 34 /* make decNumbers with space for 34 */
#include "decNumber.h" /* base number library */
#include "decNumberLocal.h" /* decNumber local types, etc. */
#include "decimal128.h" /* our primary include */
#include "decimal128.h" /* our primary include */
/* Utility routines and tables [in decimal64.c] */
extern const uInt COMBEXP[32], COMBMSD[32];
@ -71,7 +71,7 @@ extern void decNumberShow(const decNumber *); /* .. */
/* */
/* ds is the target decimal128 */
/* 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 */
/* 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 */
decNumber dw; /* work */
decContext dc; /* .. */
uInt *pu; /* .. */
uInt comb, exp; /* .. */
uInt uiwork; /* for macros */
uInt targar[4]={0,0,0,0}; /* target 128-bit */
#define targhi targar[3] /* name the word with the sign */
#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, */
/* so this check and rounding must be done before generating the */
/* 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 */
|| ae>DECIMAL128_Emax /* likely overflow */
|| 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&DECINF) targhi=DECIMAL_Inf<<24;
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 */
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 .. */
}
else { /* non-zero finite number */
uInt msd; /* work */
uInt msd; /* work */
Int pad=0; /* coefficient pad digits */
/* 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 */
pad=exp-DECIMAL128_Ehigh;
exp=DECIMAL128_Ehigh; /* [to maximum] */
@ -172,19 +172,18 @@ decimal128 * decimal128FromNumber(decimal128 *d128, const decNumber *dn,
if (dn->bits&DECNEG) targhi|=0x80000000; /* add sign bit */
/* now write to storage; this is endian */
pu=(uInt *)d128->bytes; /* overlay */
if (DECLITEND) {
/* lo -> hi */
UBFROMUI(d128->bytes, targlo);
UBFROMUI(d128->bytes+4, targml);
UBFROMUI(d128->bytes+8, targmh);
UBFROMUI(d128->bytes+12, targhi);
pu[0]=targlo; /* directly store the low int */
pu[1]=targml; /* then the mid-low */
pu[2]=targmh; /* then the mid-high */
pu[3]=targhi; /* then the high int */
}
else {
/* hi -> lo */
UBFROMUI(d128->bytes, targhi);
UBFROMUI(d128->bytes+4, targmh);
UBFROMUI(d128->bytes+8, targml);
UBFROMUI(d128->bytes+12, targlo);
pu[0]=targhi; /* directly store the high int */
pu[1]=targmh; /* then the mid-high */
pu[2]=targml; /* then the mid-low */
pu[3]=targlo; /* then the low int */
}
if (status!=0) decContextSetStatus(set, status); /* pass on status */
@ -202,8 +201,8 @@ decNumber * decimal128ToNumber(const decimal128 *d128, decNumber *dn) {
uInt msd; /* coefficient MSD */
uInt exp; /* exponent top two bits */
uInt comb; /* combination field */
Int need; /* work */
uInt uiwork; /* for macros */
const uInt *pu; /* work */
Int need; /* .. */
uInt sourar[4]; /* source 128-bit */
#define sourhi sourar[3] /* name the word with the sign */
#define sourmh sourar[2] /* and the mid-high word */
@ -211,17 +210,18 @@ decNumber * decimal128ToNumber(const decimal128 *d128, decNumber *dn) {
#define sourlo sourar[0] /* and the lowest word */
/* load source from storage; this is endian */
pu=(const uInt *)d128->bytes; /* overlay */
if (DECLITEND) {
sourlo=UBTOUI(d128->bytes ); /* directly load the low int */
sourml=UBTOUI(d128->bytes+4 ); /* then the mid-low */
sourmh=UBTOUI(d128->bytes+8 ); /* then the mid-high */
sourhi=UBTOUI(d128->bytes+12); /* then the high int */
sourlo=pu[0]; /* directly load the low int */
sourml=pu[1]; /* then the mid-low */
sourmh=pu[2]; /* then the mid-high */
sourhi=pu[3]; /* then the high int */
}
else {
sourhi=UBTOUI(d128->bytes ); /* directly load the high int */
sourmh=UBTOUI(d128->bytes+4 ); /* then the mid-high */
sourml=UBTOUI(d128->bytes+8 ); /* then the mid-low */
sourlo=UBTOUI(d128->bytes+12); /* then the low int */
sourhi=pu[0]; /* directly load the high int */
sourmh=pu[1]; /* then the mid-high */
sourml=pu[2]; /* then the mid-low */
sourlo=pu[3]; /* then the low int */
}
comb=(sourhi>>26)&0x1f; /* combination field */
@ -232,7 +232,7 @@ decNumber * decimal128ToNumber(const decimal128 *d128, decNumber *dn) {
msd=COMBMSD[comb]; /* decode the combination field */
exp=COMBEXP[comb]; /* .. */
if (exp==3) { /* is a special */
if (exp==3) { /* is a special */
if (msd==0) {
dn->bits|=DECINF;
return dn; /* no coefficient needed */
@ -265,7 +265,7 @@ decNumber * decimal128ToNumber(const decimal128 *d128, decNumber *dn) {
} /* decimal128ToNumber */
/* ------------------------------------------------------------------ */
/* to-scientific-string -- conversion to numeric string */
/* to-scientific-string -- conversion to numeric string */
/* to-engineering-string -- conversion to numeric 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. */
/* ------------------------------------------------------------------ */
char * decimal128ToEngString(const decimal128 *d128, char *string){
decNumber dn; /* work */
decNumber dn; /* work */
decimal128ToNumber(d128, &dn);
decNumberToEngString(&dn, string);
return string;
@ -289,13 +289,13 @@ char * decimal128ToString(const decimal128 *d128, char *string){
uInt msd; /* coefficient MSD */
Int exp; /* exponent top two bits or full */
uInt comb; /* combination field */
char *cstart; /* coefficient start */
char *cstart; /* coefficient start */
char *c; /* output pointer in string */
const uByte *u; /* work */
const uInt *pu; /* work */
char *s, *t; /* .. (source, target) */
Int dpd; /* .. */
Int pre, e; /* .. */
uInt uiwork; /* for macros */
const uByte *u; /* .. */
uInt sourar[4]; /* source 128-bit */
#define sourhi sourar[3] /* name the word with the sign */
@ -304,17 +304,18 @@ char * decimal128ToString(const decimal128 *d128, char *string){
#define sourlo sourar[0] /* and the lowest word */
/* load source from storage; this is endian */
pu=(const uInt *)d128->bytes; /* overlay */
if (DECLITEND) {
sourlo=UBTOUI(d128->bytes ); /* directly load the low int */
sourml=UBTOUI(d128->bytes+4 ); /* then the mid-low */
sourmh=UBTOUI(d128->bytes+8 ); /* then the mid-high */
sourhi=UBTOUI(d128->bytes+12); /* then the high int */
sourlo=pu[0]; /* directly load the low int */
sourml=pu[1]; /* then the mid-low */
sourmh=pu[2]; /* then the mid-high */
sourhi=pu[3]; /* then the high int */
}
else {
sourhi=UBTOUI(d128->bytes ); /* directly load the high int */
sourmh=UBTOUI(d128->bytes+4 ); /* then the mid-high */
sourml=UBTOUI(d128->bytes+8 ); /* then the mid-low */
sourlo=UBTOUI(d128->bytes+12); /* then the low int */
sourhi=pu[0]; /* directly load the high int */
sourmh=pu[1]; /* then the mid-high */
sourml=pu[2]; /* then the mid-low */
sourlo=pu[3]; /* then the low int */
}
c=string; /* where result will go */
@ -326,7 +327,7 @@ char * decimal128ToString(const decimal128 *d128, char *string){
if (exp==3) {
if (msd==0) { /* infinity */
strcpy(c, "Inf");
strcpy(c, "Inf");
strcpy(c+3, "inity");
return string; /* easy */
}
@ -352,12 +353,12 @@ char * decimal128ToString(const decimal128 *d128, char *string){
/* length. We use fixed-length memcpys because variable-length */
/* causes a subroutine call in GCC. (These are length 4 for speed */
/* and are safe because the array has an extra terminator byte.) */
#define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; \
#define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; \
if (c!=cstart) {memcpy(c, u+1, 4); c+=3;} \
else if (*u) {memcpy(c, u+4-*u, 4); c+=*u;}
dpd=(sourhi>>4)&0x3ff; /* declet 1 */
dpd2char;
dpd=((sourhi&0xf)<<6) | (sourmh>>26); /* declet 2 */
dpd=((sourhi&0xf)<<6) | (sourmh>>26); /* declet 2 */
dpd2char;
dpd=(sourmh>>16)&0x3ff; /* declet 3 */
dpd2char;
@ -380,7 +381,7 @@ char * decimal128ToString(const decimal128 *d128, char *string){
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 */
return string;
}
@ -408,8 +409,8 @@ char * decimal128ToString(const decimal128 *d128, char *string){
/* finally add the E-part, if needed; it will never be 0, and has */
/* a maximum length of 4 digits */
if (e!=0) {
*c++='E'; /* starts with E */
*c++='+'; /* assume positive */
*c++='E'; /* starts with E */
*c++='+'; /* assume positive */
if (e<0) {
*(c-1)='-'; /* oops, need '-' */
e=-e; /* uInt, please */
@ -448,13 +449,13 @@ char * decimal128ToString(const decimal128 *d128, char *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 */
/* the conversion */
/* *string is the character string which should contain a valid */
/* 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 */
/* (setting of status and traps) and for the rounding mode, only. */
@ -463,7 +464,7 @@ char * decimal128ToString(const decimal128 *d128, char *string){
decimal128 * decimal128FromString(decimal128 *result, const char *string,
decContext *set) {
decContext dc; /* work */
decNumber dn; /* .. */
decNumber dn; /* .. */
decContextDefault(&dc, DEC_INIT_DECIMAL128); /* no traps, please */
dc.round=set->round; /* use supplied rounding */
@ -482,8 +483,8 @@ decimal128 * decimal128FromString(decimal128 *result, const char *string,
/* returns 1 if the encoding of d128 is canonical, 0 otherwise */
/* No error is possible. */
/* ------------------------------------------------------------------ */
uInt decimal128IsCanonical(const decimal128 *d128) {
decNumber dn; /* work */
uint32_t decimal128IsCanonical(const decimal128 *d128) {
decNumber dn; /* work */
decimal128 canon; /* .. */
decContext dc; /* .. */
decContextDefault(&dc, DEC_INIT_DECIMAL128);
@ -500,7 +501,7 @@ uInt decimal128IsCanonical(const decimal128 *d128) {
/* No error is possible. */
/* ------------------------------------------------------------------ */
decimal128 * decimal128Canonical(decimal128 *result, const decimal128 *d128) {
decNumber dn; /* work */
decNumber dn; /* work */
decContext dc; /* .. */
decContextDefault(&dc, DEC_INIT_DECIMAL128);
decimal128ToNumber(d128, &dn);
@ -531,13 +532,13 @@ decimal128 * decimal128Canonical(decimal128 *result, const decimal128 *d128) {
/* This assumes range has been checked and exponent previously 0; */
/* type of exponent must be unsigned */
#define decimal128SetExpCon(d, e) { \
(d)->bytes[0]|=(uByte)((e)>>10); \
(d)->bytes[1] =(uByte)(((e)&0x3fc)>>2); \
(d)->bytes[2]|=(uByte)(((e)&0x03)<<6);}
(d)->bytes[0]|=(uint8_t)((e)>>10); \
(d)->bytes[1] =(uint8_t)(((e)&0x3fc)>>2); \
(d)->bytes[2]|=(uint8_t)(((e)&0x03)<<6);}
/* ------------------------------------------------------------------ */
/* decimal128Show -- display a decimal128 in hexadecimal [debug aid] */
/* d128 -- the number to show */
/* d128 -- the number to show */
/* ------------------------------------------------------------------ */
/* Also shows sign/cob/expconfields extracted */
void decimal128Show(const decimal128 *d128) {

View File

@ -29,7 +29,7 @@
02110-1301, USA. */
/* ------------------------------------------------------------------ */
/* Decimal 128-bit format module header */
/* Decimal 128-bit format module header */
/* ------------------------------------------------------------------ */
#if !defined(DECIMAL128)
@ -46,7 +46,7 @@
#define DECIMAL128_Bias 6176 /* bias for the exponent */
#define DECIMAL128_String 43 /* maximum string length, +1 */
#define DECIMAL128_EconL 12 /* exp. continuation length */
/* highest biased exponent (Elimit-1) */
/* highest biased exponent (Elimit-1) */
#define DECIMAL128_Ehigh (DECIMAL128_Emax+DECIMAL128_Bias-DECIMAL128_Pmax+1)
/* check enough digits, if pre-defined */
@ -71,20 +71,20 @@
/* special values [top byte excluding sign bit; last two bits are */
/* don't-care for Infinity on input, last bit don't-care for NaN] */
#if !defined(DECIMAL_NaN)
#define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */
#define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */
#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
#include "decimal128Local.h"
#include "decimal128Local.h"
/* ---------------------------------------------------------------- */
/* Routines */
/* ---------------------------------------------------------------- */
#include "decimal128Symbols.h"
#include "decimal128Symbols.h"
/* String conversions */
/* String conversions */
decimal128 * decimal128FromString(decimal128 *, const char *, decContext *);
char * decimal128ToString(const decimal128 *, char *);
char * decimal128ToEngString(const decimal128 *, char *);
@ -94,7 +94,7 @@
decContext *);
decNumber * decimal128ToNumber(const decimal128 *, decNumber *);
/* Format-dependent utilities */
/* Format-dependent utilities */
uint32_t decimal128IsCanonical(const decimal128 *);
decimal128 * decimal128Canonical(decimal128 *, const decimal128 *);

View File

@ -29,7 +29,7 @@
02110-1301, USA. */
/* ------------------------------------------------------------------ */
/* Decimal 32-bit format module */
/* Decimal 32-bit format module */
/* ------------------------------------------------------------------ */
/* This module comprises the routines for decimal32 format numbers. */
/* Conversions are supplied to and from decNumber and String. */
@ -42,8 +42,8 @@
#include <string.h> /* [for memset/memcpy] */
#include <stdio.h> /* [for printf] */
#include "dconfig.h" /* GCC definitions */
#define DECNUMDIGITS 7 /* make decNumbers with space for 7 */
#include "dconfig.h" /* GCC definitions */
#define DECNUMDIGITS 7 /* make decNumbers with space for 7 */
#include "decNumber.h" /* base number library */
#include "decNumberLocal.h" /* decNumber local types, etc. */
#include "decimal32.h" /* our primary include */
@ -69,9 +69,9 @@ extern void decNumberShow(const decNumber *); /* .. */
/* ------------------------------------------------------------------ */
/* decimal32FromNumber -- convert decNumber to decimal32 */
/* */
/* ds is the target decimal32 */
/* ds is the target decimal32 */
/* 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 */
/* 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 */
decNumber dw; /* work */
decContext dc; /* .. */
uInt *pu; /* .. */
uInt comb, exp; /* .. */
uInt uiwork; /* for macros */
uInt targ=0; /* target 32-bit */
/* 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, */
/* so this check and rounding must be done before generating the */
/* decimal32] */
ae=dn->exponent+dn->digits-1; /* [0 if special] */
if (dn->digits>DECIMAL32_Pmax /* too many digits */
|| ae>DECIMAL32_Emax /* likely overflow */
ae=dn->exponent+dn->digits-1; /* [0 if special] */
if (dn->digits>DECIMAL32_Pmax /* too many digits */
|| ae>DECIMAL32_Emax /* likely overflow */
|| ae<DECIMAL32_Emin) { /* likely underflow */
decContextDefault(&dc, DEC_INIT_DECIMAL32); /* [no traps] */
dc.round=set->round; /* use supplied rounding */
@ -114,7 +114,7 @@ decimal32 * decimal32FromNumber(decimal32 *d32, const decNumber *dn,
if (dn->bits&DECSPECIAL) { /* a special value */
if (dn->bits&DECINF) targ=DECIMAL_Inf<<24;
else { /* sNaN or qNaN */
if ((*dn->lsu!=0 || dn->digits>1) /* non-zero coefficient */
if ((*dn->lsu!=0 || dn->digits>1) /* non-zero coefficient */
&& (dn->digits<DECIMAL32_Pmax)) { /* coefficient fits */
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 .. */
}
else { /* non-zero finite number */
uInt msd; /* work */
uInt msd; /* work */
Int pad=0; /* coefficient pad digits */
/* the dn is known to fit, but it may need to be padded */
@ -175,7 +175,8 @@ decimal32 * decimal32FromNumber(decimal32 *d32, const decNumber *dn,
if (dn->bits&DECNEG) targ|=0x80000000; /* add sign bit */
/* now write to storage; this is endian */
UBFROMUI(d32->bytes, targ); /* directly store the int */
pu=(uInt *)d32->bytes; /* overlay */
*pu=targ; /* directly store the int */
if (status!=0) decContextSetStatus(set, status); /* pass on status */
/* decimal32Show(d32); */
@ -193,12 +194,13 @@ decNumber * decimal32ToNumber(const decimal32 *d32, decNumber *dn) {
uInt exp; /* exponent top two bits */
uInt comb; /* combination field */
uInt sour; /* source 32-bit */
uInt uiwork; /* for macros */
const uInt *pu; /* work */
/* load source from storage; this is endian */
sour=UBTOUI(d32->bytes); /* directly load the int */
pu=(const uInt *)d32->bytes; /* overlay */
sour=*pu; /* directly load the int */
comb=(sour>>26)&0x1f; /* combination field */
comb=(sour>>26)&0x1f; /* combination field */
decNumberZero(dn); /* clean number */
if (sour&0x80000000) dn->bits=DECNEG; /* set sign if negative */
@ -206,7 +208,7 @@ decNumber * decimal32ToNumber(const decimal32 *d32, decNumber *dn) {
msd=COMBMSD[comb]; /* decode the combination field */
exp=COMBEXP[comb]; /* .. */
if (exp==3) { /* is a special */
if (exp==3) { /* is a special */
if (msd==0) {
dn->bits|=DECINF;
return dn; /* no coefficient needed */
@ -227,7 +229,7 @@ decNumber * decimal32ToNumber(const decimal32 *d32, decNumber *dn) {
return dn;
}
/* msd=0 */
if (!sour) return dn; /* easy: coefficient is 0 */
if (!sour) return dn; /* easy: coefficient is 0 */
if (sour&0x000ffc00) /* need 2 declets? */
decDigitsFromDPD(dn, &sour, 2); /* process 2 declets */
else
@ -236,11 +238,11 @@ decNumber * decimal32ToNumber(const decimal32 *d32, decNumber *dn) {
} /* decimal32ToNumber */
/* ------------------------------------------------------------------ */
/* to-scientific-string -- conversion to numeric string */
/* to-scientific-string -- conversion to numeric string */
/* to-engineering-string -- conversion to numeric string */
/* */
/* decimal32ToString(d32, string); */
/* decimal32ToEngString(d32, string); */
/* decimal32ToEngString(d32, string); */
/* */
/* d32 is the decimal32 format number to convert */
/* string is the string where the result will be laid out */
@ -250,7 +252,7 @@ decNumber * decimal32ToNumber(const decimal32 *d32, decNumber *dn) {
/* No error is possible, and no status can be set. */
/* ------------------------------------------------------------------ */
char * decimal32ToEngString(const decimal32 *d32, char *string){
decNumber dn; /* work */
decNumber dn; /* work */
decimal32ToNumber(d32, &dn);
decNumberToEngString(&dn, string);
return string;
@ -260,28 +262,29 @@ char * decimal32ToString(const decimal32 *d32, char *string){
uInt msd; /* coefficient MSD */
Int exp; /* exponent top two bits or full */
uInt comb; /* combination field */
char *cstart; /* coefficient start */
char *cstart; /* coefficient start */
char *c; /* output pointer in string */
const uByte *u; /* work */
const uInt *pu; /* work */
const uByte *u; /* .. */
char *s, *t; /* .. (source, target) */
Int dpd; /* .. */
Int pre, e; /* .. */
uInt uiwork; /* for macros */
uInt sour; /* source 32-bit */
/* load source from storage; this is endian */
sour=UBTOUI(d32->bytes); /* directly load the int */
pu=(const uInt *)d32->bytes; /* overlay */
sour=*pu; /* directly load the int */
c=string; /* where result will go */
if (((Int)sour)<0) *c++='-'; /* handle sign */
comb=(sour>>26)&0x1f; /* combination field */
comb=(sour>>26)&0x1f; /* combination field */
msd=COMBMSD[comb]; /* decode the combination field */
exp=COMBEXP[comb]; /* .. */
if (exp==3) {
if (msd==0) { /* infinity */
strcpy(c, "Inf");
strcpy(c, "Inf");
strcpy(c+3, "inity");
return string; /* easy */
}
@ -306,18 +309,18 @@ char * decimal32ToString(const decimal32 *d32, char *string){
/* length. We use fixed-length memcpys because variable-length */
/* causes a subroutine call in GCC. (These are length 4 for speed */
/* and are safe because the array has an extra terminator byte.) */
#define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; \
#define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; \
if (c!=cstart) {memcpy(c, u+1, 4); c+=3;} \
else if (*u) {memcpy(c, u+4-*u, 4); c+=*u;}
dpd=(sour>>10)&0x3ff; /* declet 1 */
dpd=(sour>>10)&0x3ff; /* declet 1 */
dpd2char;
dpd=(sour)&0x3ff; /* declet 2 */
dpd2char;
if (c==cstart) *c++='0'; /* all zeros -- make 0 */
if (exp==0) { /* integer or NaN case -- easy */
if (exp==0) { /* integer or NaN case -- easy */
*c='\0'; /* terminate */
return string;
}
@ -345,13 +348,13 @@ char * decimal32ToString(const decimal32 *d32, char *string){
/* finally add the E-part, if needed; it will never be 0, and has */
/* a maximum length of 3 digits (E-101 case) */
if (e!=0) {
*c++='E'; /* starts with E */
*c++='+'; /* assume positive */
*c++='E'; /* starts with E */
*c++='+'; /* assume positive */
if (e<0) {
*(c-1)='-'; /* oops, need '-' */
e=-e; /* uInt, please */
}
u=&BIN2CHAR[e*4]; /* -> length byte */
u=&BIN2CHAR[e*4]; /* -> length byte */
memcpy(c, u+4-*u, 4); /* copy fixed 4 characters [is safe] */
c+=*u; /* bump pointer appropriately */
}
@ -381,7 +384,7 @@ char * decimal32ToString(const decimal32 *d32, char *string){
/* the conversion */
/* *string is the character string which should contain a valid */
/* 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 */
/* (setting of status and traps) and for the rounding mode, only. */
@ -390,7 +393,7 @@ char * decimal32ToString(const decimal32 *d32, char *string){
decimal32 * decimal32FromString(decimal32 *result, const char *string,
decContext *set) {
decContext dc; /* work */
decNumber dn; /* .. */
decNumber dn; /* .. */
decContextDefault(&dc, DEC_INIT_DECIMAL32); /* no traps, please */
dc.round=set->round; /* use supplied rounding */
@ -406,11 +409,11 @@ decimal32 * decimal32FromString(decimal32 *result, const char *string,
/* ------------------------------------------------------------------ */
/* decimal32IsCanonical -- test whether encoding is canonical */
/* 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. */
/* ------------------------------------------------------------------ */
uInt decimal32IsCanonical(const decimal32 *d32) {
decNumber dn; /* work */
uint32_t decimal32IsCanonical(const decimal32 *d32) {
decNumber dn; /* work */
decimal32 canon; /* .. */
decContext dc; /* .. */
decContextDefault(&dc, DEC_INIT_DECIMAL32);
@ -427,7 +430,7 @@ uInt decimal32IsCanonical(const decimal32 *d32) {
/* No error is possible. */
/* ------------------------------------------------------------------ */
decimal32 * decimal32Canonical(decimal32 *result, const decimal32 *d32) {
decNumber dn; /* work */
decNumber dn; /* work */
decContext dc; /* .. */
decContextDefault(&dc, DEC_INIT_DECIMAL32);
decimal32ToNumber(d32, &dn);
@ -457,8 +460,8 @@ decimal32 * decimal32Canonical(decimal32 *result, const decimal32 *d32) {
/* This assumes range has been checked and exponent previously 0; */
/* type of exponent must be unsigned */
#define decimal32SetExpCon(d, e) { \
(d)->bytes[0]|=(uByte)((e)>>4); \
(d)->bytes[1]|=(uByte)(((e)&0x0F)<<4);}
(d)->bytes[0]|=(uint8_t)((e)>>4); \
(d)->bytes[1]|=(uint8_t)(((e)&0x0F)<<4);}
/* ------------------------------------------------------------------ */
/* decimal32Show -- display a decimal32 in hexadecimal [debug aid] */

View File

@ -35,7 +35,7 @@
#if !defined(DECIMAL32)
#define DECIMAL32
#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 */
/* parameters for decimal32s */
@ -46,7 +46,7 @@
#define DECIMAL32_Bias 101 /* bias for the exponent */
#define DECIMAL32_String 15 /* maximum string length, +1 */
#define DECIMAL32_EconL 6 /* exp. continuation length */
/* highest biased exponent (Elimit-1) */
/* highest biased exponent (Elimit-1) */
#define DECIMAL32_Ehigh (DECIMAL32_Emax+DECIMAL32_Bias-DECIMAL32_Pmax+1)
/* check enough digits, if pre-defined */
@ -71,18 +71,18 @@
/* special values [top byte excluding sign bit; last two bits are */
/* don't-care for Infinity on input, last bit don't-care for NaN] */
#if !defined(DECIMAL_NaN)
#define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */
#define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */
#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
/* ---------------------------------------------------------------- */
/* Routines */
/* ---------------------------------------------------------------- */
#include "decimal32Symbols.h"
#include "decimal32Symbols.h"
/* String conversions */
/* String conversions */
decimal32 * decimal32FromString(decimal32 *, const char *, decContext *);
char * decimal32ToString(const decimal32 *, char *);
char * decimal32ToEngString(const decimal32 *, char *);
@ -92,7 +92,7 @@
decContext *);
decNumber * decimal32ToNumber(const decimal32 *, decNumber *);
/* Format-dependent utilities */
/* Format-dependent utilities */
uint32_t decimal32IsCanonical(const decimal32 *);
decimal32 * decimal32Canonical(decimal32 *, const decimal32 *);

View File

@ -29,7 +29,7 @@
02110-1301, USA. */
/* ------------------------------------------------------------------ */
/* Decimal 64-bit format module */
/* Decimal 64-bit format module */
/* ------------------------------------------------------------------ */
/* This module comprises the routines for decimal64 format numbers. */
/* Conversions are supplied to and from decNumber and String. */
@ -42,8 +42,8 @@
#include <string.h> /* [for memset/memcpy] */
#include <stdio.h> /* [for printf] */
#include "dconfig.h" /* GCC definitions */
#define DECNUMDIGITS 16 /* make decNumbers with space for 16 */
#include "dconfig.h" /* GCC definitions */
#define DECNUMDIGITS 16 /* make decNumbers with space for 16 */
#include "decNumber.h" /* base number library */
#include "decNumberLocal.h" /* decNumber local types, etc. */
#include "decimal64.h" /* our primary include */
@ -75,9 +75,9 @@ extern void decNumberShow(const decNumber *); /* .. */
/* ------------------------------------------------------------------ */
/* decimal64FromNumber -- convert decNumber to decimal64 */
/* */
/* ds is the target decimal64 */
/* ds is the target decimal64 */
/* 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 */
/* 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 */
decNumber dw; /* work */
decContext dc; /* .. */
uInt *pu; /* .. */
uInt comb, exp; /* .. */
uInt uiwork; /* for macros */
uInt targar[2]={0, 0}; /* target 64-bit */
#define targhi targar[1] /* name the word with the sign */
#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, */
/* so this check and rounding must be done before generating the */
/* decimal64] */
ae=dn->exponent+dn->digits-1; /* [0 if special] */
if (dn->digits>DECIMAL64_Pmax /* too many digits */
|| ae>DECIMAL64_Emax /* likely overflow */
ae=dn->exponent+dn->digits-1; /* [0 if special] */
if (dn->digits>DECIMAL64_Pmax /* too many digits */
|| ae>DECIMAL64_Emax /* likely overflow */
|| ae<DECIMAL64_Emin) { /* likely underflow */
decContextDefault(&dc, DEC_INIT_DECIMAL64); /* [no traps] */
dc.round=set->round; /* use supplied rounding */
@ -122,7 +122,7 @@ decimal64 * decimal64FromNumber(decimal64 *d64, const decNumber *dn,
if (dn->bits&DECSPECIAL) { /* a special value */
if (dn->bits&DECINF) targhi=DECIMAL_Inf<<24;
else { /* sNaN or qNaN */
if ((*dn->lsu!=0 || dn->digits>1) /* non-zero coefficient */
if ((*dn->lsu!=0 || dn->digits>1) /* non-zero coefficient */
&& (dn->digits<DECIMAL64_Pmax)) { /* coefficient fits */
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 .. */
}
else { /* non-zero finite number */
uInt msd; /* work */
uInt msd; /* work */
Int pad=0; /* coefficient pad digits */
/* the dn is known to fit, but it may need to be padded */
@ -193,15 +193,14 @@ decimal64 * decimal64FromNumber(decimal64 *d64, const decNumber *dn,
if (dn->bits&DECNEG) targhi|=0x80000000; /* add sign bit */
/* now write to storage; this is now always endian */
pu=(uInt *)d64->bytes; /* overlay */
if (DECLITEND) {
/* lo int then hi */
UBFROMUI(d64->bytes, targar[0]);
UBFROMUI(d64->bytes+4, targar[1]);
pu[0]=targar[0]; /* directly store the low int */
pu[1]=targar[1]; /* then the high int */
}
else {
/* hi int then lo */
UBFROMUI(d64->bytes, targar[1]);
UBFROMUI(d64->bytes+4, targar[0]);
pu[0]=targar[1]; /* directly store the high int */
pu[1]=targar[0]; /* then the low int */
}
if (status!=0) decContextSetStatus(set, status); /* pass on status */
@ -219,20 +218,21 @@ decNumber * decimal64ToNumber(const decimal64 *d64, decNumber *dn) {
uInt msd; /* coefficient MSD */
uInt exp; /* exponent top two bits */
uInt comb; /* combination field */
Int need; /* work */
uInt uiwork; /* for macros */
const uInt *pu; /* work */
Int need; /* .. */
uInt sourar[2]; /* source 64-bit */
#define sourhi sourar[1] /* name the word with the sign */
#define sourlo sourar[0] /* and the lower word */
/* load source from storage; this is endian */
pu=(const uInt *)d64->bytes; /* overlay */
if (DECLITEND) {
sourlo=UBTOUI(d64->bytes ); /* directly load the low int */
sourhi=UBTOUI(d64->bytes+4); /* then the high int */
sourlo=pu[0]; /* directly load the low int */
sourhi=pu[1]; /* then the high int */
}
else {
sourhi=UBTOUI(d64->bytes ); /* directly load the high int */
sourlo=UBTOUI(d64->bytes+4); /* then the low int */
sourhi=pu[0]; /* directly load the high int */
sourlo=pu[1]; /* then the low int */
}
comb=(sourhi>>26)&0x1f; /* combination field */
@ -243,7 +243,7 @@ decNumber * decimal64ToNumber(const decimal64 *d64, decNumber *dn) {
msd=COMBMSD[comb]; /* decode the combination field */
exp=COMBEXP[comb]; /* .. */
if (exp==3) { /* is a special */
if (exp==3) { /* is a special */
if (msd==0) {
dn->bits|=DECINF;
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 */
/* */
/* decimal64ToString(d64, string); */
/* decimal64ToEngString(d64, string); */
/* decimal64ToEngString(d64, string); */
/* */
/* d64 is the decimal64 format number to convert */
/* 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. */
/* ------------------------------------------------------------------ */
char * decimal64ToEngString(const decimal64 *d64, char *string){
decNumber dn; /* work */
decNumber dn; /* work */
decimal64ToNumber(d64, &dn);
decNumberToEngString(&dn, string);
return string;
@ -305,26 +305,27 @@ char * decimal64ToString(const decimal64 *d64, char *string){
uInt msd; /* coefficient MSD */
Int exp; /* exponent top two bits or full */
uInt comb; /* combination field */
char *cstart; /* coefficient start */
char *cstart; /* coefficient start */
char *c; /* output pointer in string */
const uByte *u; /* work */
const uInt *pu; /* work */
char *s, *t; /* .. (source, target) */
Int dpd; /* .. */
Int pre, e; /* .. */
uInt uiwork; /* for macros */
const uByte *u; /* .. */
uInt sourar[2]; /* source 64-bit */
#define sourhi sourar[1] /* name the word with the sign */
#define sourlo sourar[0] /* and the lower word */
/* load source from storage; this is endian */
pu=(const uInt *)d64->bytes; /* overlay */
if (DECLITEND) {
sourlo=UBTOUI(d64->bytes ); /* directly load the low int */
sourhi=UBTOUI(d64->bytes+4); /* then the high int */
sourlo=pu[0]; /* directly load the low int */
sourhi=pu[1]; /* then the high int */
}
else {
sourhi=UBTOUI(d64->bytes ); /* directly load the high int */
sourlo=UBTOUI(d64->bytes+4); /* then the low int */
sourhi=pu[0]; /* directly load the high int */
sourlo=pu[1]; /* then the low int */
}
c=string; /* where result will go */
@ -336,7 +337,7 @@ char * decimal64ToString(const decimal64 *d64, char *string){
if (exp==3) {
if (msd==0) { /* infinity */
strcpy(c, "Inf");
strcpy(c, "Inf");
strcpy(c+3, "inity");
return string; /* easy */
}
@ -361,7 +362,7 @@ char * decimal64ToString(const decimal64 *d64, char *string){
/* length. We use fixed-length memcpys because variable-length */
/* causes a subroutine call in GCC. (These are length 4 for speed */
/* and are safe because the array has an extra terminator byte.) */
#define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; \
#define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; \
if (c!=cstart) {memcpy(c, u+1, 4); c+=3;} \
else if (*u) {memcpy(c, u+4-*u, 4); c+=*u;}
@ -378,7 +379,7 @@ char * decimal64ToString(const decimal64 *d64, char *string){
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 */
return string;
}
@ -406,13 +407,13 @@ char * decimal64ToString(const decimal64 *d64, char *string){
/* finally add the E-part, if needed; it will never be 0, and has */
/* a maximum length of 3 digits */
if (e!=0) {
*c++='E'; /* starts with E */
*c++='+'; /* assume positive */
*c++='E'; /* starts with E */
*c++='+'; /* assume positive */
if (e<0) {
*(c-1)='-'; /* oops, need '-' */
e=-e; /* uInt, please */
}
u=&BIN2CHAR[e*4]; /* -> length byte */
u=&BIN2CHAR[e*4]; /* -> length byte */
memcpy(c, u+4-*u, 4); /* copy fixed 4 characters [is safe] */
c+=*u; /* bump pointer appropriately */
}
@ -442,7 +443,7 @@ char * decimal64ToString(const decimal64 *d64, char *string){
/* the conversion */
/* *string is the character string which should contain a valid */
/* 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 */
/* (setting of status and traps) and for the rounding mode, only. */
@ -451,7 +452,7 @@ char * decimal64ToString(const decimal64 *d64, char *string){
decimal64 * decimal64FromString(decimal64 *result, const char *string,
decContext *set) {
decContext dc; /* work */
decNumber dn; /* .. */
decNumber dn; /* .. */
decContextDefault(&dc, DEC_INIT_DECIMAL64); /* no traps, please */
dc.round=set->round; /* use supplied rounding */
@ -468,11 +469,11 @@ decimal64 * decimal64FromString(decimal64 *result, const char *string,
/* ------------------------------------------------------------------ */
/* decimal64IsCanonical -- test whether encoding is canonical */
/* 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. */
/* ------------------------------------------------------------------ */
uInt decimal64IsCanonical(const decimal64 *d64) {
decNumber dn; /* work */
uint32_t decimal64IsCanonical(const decimal64 *d64) {
decNumber dn; /* work */
decimal64 canon; /* .. */
decContext dc; /* .. */
decContextDefault(&dc, DEC_INIT_DECIMAL64);
@ -489,7 +490,7 @@ uInt decimal64IsCanonical(const decimal64 *d64) {
/* No error is possible. */
/* ------------------------------------------------------------------ */
decimal64 * decimal64Canonical(decimal64 *result, const decimal64 *d64) {
decNumber dn; /* work */
decNumber dn; /* work */
decContext dc; /* .. */
decContextDefault(&dc, DEC_INIT_DECIMAL64);
decimal64ToNumber(d64, &dn);
@ -519,8 +520,8 @@ decimal64 * decimal64Canonical(decimal64 *result, const decimal64 *d64) {
/* This assumes range has been checked and exponent previously 0; */
/* type of exponent must be unsigned */
#define decimal64SetExpCon(d, e) { \
(d)->bytes[0]|=(uByte)((e)>>6); \
(d)->bytes[1]|=(uByte)(((e)&0x3F)<<2);}
(d)->bytes[0]|=(uint8_t)((e)>>6); \
(d)->bytes[1]|=(uint8_t)(((e)&0x3F)<<2);}
/* ------------------------------------------------------------------ */
/* decimal64Show -- display a decimal64 in hexadecimal [debug aid] */
@ -590,12 +591,12 @@ const uInt COMBMSD[32]={0, 1, 2, 3, 4, 5, 6, 7,
/* ------------------------------------------------------------------ */
/* 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 */
/* have cleared to zeros */
/* have cleared to zeros */
/* shift is the number of 0 digits to add on the right (normally 0) */
/* */
/* The coefficient must be known small enough to fit. The full */
/* The coefficient must be known small enough to fit. The full */
/* coefficient is copied, including the leading 'odd' digit. This */
/* digit is retrieved and packed into the combination field by the */
/* caller. */
@ -624,7 +625,7 @@ void decDigitsToDPD(const decNumber *dn, uInt *targ, Int shift) {
uInt dpd; /* densely packed decimal value */
uInt bin; /* binary value 0-999 */
uInt *uout=targ; /* -> current output uInt */
uInt uoff=0; /* -> current output offset [from right] */
uInt uoff=0; /* -> current output offset [from right] */
const Unit *inu=dn->lsu; /* -> current input unit */
Unit uar[DECMAXUNITS]; /* working copy of units, iff shifted */
#if DECDPUN!=3 /* not fast path */
@ -635,7 +636,7 @@ void decDigitsToDPD(const decNumber *dn, uInt *targ, Int shift) {
/* shift the units array to the left by pad digits and copy */
/* [this code is a special case of decShiftToMost, which could */
/* be used instead if exposed and the array were copied first] */
const Unit *source; /* .. */
const Unit *source; /* .. */
Unit *target, *first; /* .. */
uInt next=0; /* work */
@ -680,12 +681,12 @@ void decDigitsToDPD(const decNumber *dn, uInt *targ, Int shift) {
for(n=0; digits>0; n++) { /* each output bunch */
#if DECDPUN==3 /* fast path, 3-at-a-time */
bin=*inu; /* 3 digits ready for convert */
bin=*inu; /* 3 digits ready for convert */
digits-=3; /* [may go negative] */
inu++; /* may need another */
#else /* must collect digit-by-digit */
Unit dig; /* current digit */
Unit dig; /* current digit */
Int j; /* digit-in-declet count */
for (j=0; j<3; j++) {
#if DECDPUN<=4
@ -697,7 +698,7 @@ void decDigitsToDPD(const decNumber *dn, uInt *targ, Int shift) {
in=in/10;
#endif
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);
digits--;
if (digits==0) break; /* [also protects *inu below] */
@ -749,12 +750,12 @@ void decDigitsFromDPD(decNumber *dn, const uInt *sour, Int declets) {
Int n; /* counter */
Unit *uout=dn->lsu; /* -> current output unit */
Unit *last=uout; /* will be unit containing msd */
const uInt *uin=sour; /* -> current input uInt */
uInt uoff=0; /* -> current input offset [from right] */
const uInt *uin=sour; /* -> current input uInt */
uInt uoff=0; /* -> current input offset [from right] */
#if DECDPUN!=3
uInt bcd; /* BCD result */
uInt nibble; /* work */
uInt nibble; /* work */
Unit out=0; /* accumulator */
Int cut=0; /* power of ten in current unit */
#endif
@ -771,7 +772,7 @@ void decDigitsFromDPD(decNumber *dn, const uInt *sour, Int declets) {
uoff-=32;
dpd|=*uin<<(10-uoff); /* get waiting bits */
}
dpd&=0x3ff; /* clear uninteresting bits */
dpd&=0x3ff; /* clear uninteresting bits */
#if DECDPUN==3
if (dpd==0) *uout=0;
@ -821,9 +822,9 @@ void decDigitsFromDPD(decNumber *dn, const uInt *sour, Int declets) {
cut++;
if (cut==DECDPUN) {*uout=out; if (out) {last=uout; out=0;} uout++; cut=0;}
} /* n */
if (cut!=0) { /* some more left over */
if (cut!=0) { /* some more left over */
*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
@ -833,14 +834,14 @@ void decDigitsFromDPD(decNumber *dn, const uInt *sour, Int declets) {
dn->digits=(last-dn->lsu)*DECDPUN+1; /* floor of digits, plus */
/* must be at least 1 digit */
#if DECDPUN>1
if (*last<10) return; /* common odd digit or 0 */
dn->digits++; /* must be 2 at least */
if (*last<10) return; /* common odd digit or 0 */
dn->digits++; /* must be 2 at least */
#if DECDPUN>2
if (*last<100) return; /* 10-99 */
dn->digits++; /* must be 3 at least */
dn->digits++; /* must be 3 at least */
#if DECDPUN>3
if (*last<1000) return; /* 100-999 */
dn->digits++; /* must be 4 at least */
dn->digits++; /* must be 4 at least */
#if DECDPUN>4
for (pow=&DECPOWERS[4]; *last>=*pow; pow++) dn->digits++;
#endif

View File

@ -35,7 +35,7 @@
#if !defined(DECIMAL64)
#define DECIMAL64
#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 */
@ -47,7 +47,7 @@
#define DECIMAL64_Bias 398 /* bias for the exponent */
#define DECIMAL64_String 24 /* maximum string length, +1 */
#define DECIMAL64_EconL 8 /* exp. continuation length */
/* highest biased exponent (Elimit-1) */
/* highest biased exponent (Elimit-1) */
#define DECIMAL64_Ehigh (DECIMAL64_Emax+DECIMAL64_Bias-DECIMAL64_Pmax+1)
/* check enough digits, if pre-defined */
@ -73,18 +73,18 @@
/* special values [top byte excluding sign bit; last two bits are */
/* don't-care for Infinity on input, last bit don't-care for NaN] */
#if !defined(DECIMAL_NaN)
#define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */
#define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */
#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
/* ---------------------------------------------------------------- */
/* Routines */
/* ---------------------------------------------------------------- */
#include "decimal64Symbols.h"
#include "decimal64Symbols.h"
/* String conversions */
/* String conversions */
decimal64 * decimal64FromString(decimal64 *, const char *, decContext *);
char * decimal64ToString(const decimal64 *, char *);
char * decimal64ToEngString(const decimal64 *, char *);
@ -94,7 +94,7 @@
decContext *);
decNumber * decimal64ToNumber(const decimal64 *, decNumber *);
/* Format-dependent utilities */
/* Format-dependent utilities */
uint32_t decimal64IsCanonical(const decimal64 *);
decimal64 * decimal64Canonical(decimal64 *, const decimal64 *);