File: decNumberLocal.h

package info (click to toggle)
hercules 3.13-9
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 14,392 kB
  • sloc: ansic: 175,124; sh: 8,792; makefile: 760; perl: 149
file content (200 lines) | stat: -rw-r--r-- 8,914 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/* ------------------------------------------------------------------ */
/* decNumber package local type, tuning, and macro definitions        */
/* ------------------------------------------------------------------ */
/* Copyright (c) IBM Corporation, 2000, 2005.  All rights reserved.   */
/*                                                                    */
/* This software is made available under the terms of the             */
/* ICU License -- ICU 1.8.1 and later.                                */
/*                                                                    */
/* The description and User's Guide ("The decNumber C Library") for   */
/* this software is called decNumber.pdf.  This document is           */
/* available, together with arithmetic and format specifications,     */
/* testcases, and Web links, at: http://www2.hursley.ibm.com/decimal  */
/*                                                                    */
/* Please send comments, suggestions, and corrections to the author:  */
/*   mfc@uk.ibm.com                                                   */
/*   Mike Cowlishaw, IBM Fellow                                       */
/*   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         */
/* ------------------------------------------------------------------ */
/* This header file is included by all modules in the decNumber       */
/* library, and contains local type definitions, tuning parameters,   */
/* etc.  It must only be included once, and should not need to be     */
/* used by application programs.  decNumber.h must be included first. */
/* ------------------------------------------------------------------ */

#if !defined(DECNUMBERLOC)
  #define DECNUMBERLOC
  #define DECNLAUTHOR   "Mike Cowlishaw"              /* Who to blame */

  /* Tuning parameter */
  #define DECBUFFER 36        // Maximum size basis for local buffers.
                              // Should be a common maximum precision
                              // rounded up to a multiple of 4; must
                              // be zero or positive.

  /* Conditional code flags -- set these to 1 for best performance */
  #define DECENDIAN 1         // 1=concrete formats are endian
  #define DECUSE64  1         // 1 to allow use of 64-bit integers

  /* Conditional check flags -- set these to 0 for best performance */
  #define DECCHECK  0         // 1 to enable robust checking
  #define DECALLOC  0         // 1 to enable memory allocation accounting
  #define DECTRACE  0         // 1 to trace critical intermediates, etc.

  /* Local names for common types -- for safety, decNumber modules do
     not use int or long directly */
  #define Flag   uint8_t
  #define Byte   int8_t
  #define uByte  uint8_t
  #define Short  int16_t
  #define uShort uint16_t
  #define Int    int32_t
  #define uInt   uint32_t
  #define Unit   decNumberUnit
  #if DECUSE64
  #define Long   int64_t
  #define uLong  uint64_t
  #endif

  /* Development-use defines */
  #if DECALLOC
    // if these interfere with your C includes, just comment them out
    #define  int ?            // enable to ensure that plain C 'int' or
    #define  long ??          // .. 'long' types are not used
  #endif

  /* Limits and constants */
  #define DECNUMMAXP 999999999  // maximum precision code can handle
  #define DECNUMMAXE 999999999  // maximum adjusted exponent ditto
  #define DECNUMMINE -999999999 // minimum adjusted exponent ditto
  #if (DECNUMMAXP != DEC_MAX_DIGITS)
    #error Maximum digits mismatch
  #endif
  #if (DECNUMMAXE != DEC_MAX_EMAX)
    #error Maximum exponent mismatch
  #endif
  #if (DECNUMMINE != DEC_MIN_EMIN)
    #error Minimum exponent mismatch
  #endif

  /* Set DECDPUNMAX -- the maximum integer that fits in DECDPUN    */
  /* digits, and D2UTABLE -- the initializer for the D2U table     */
  #if   DECDPUN==1
    #define DECDPUNMAX 9
    #define D2UTABLE {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,  \
                      18,19,20,21,22,23,24,25,26,27,28,29,30,31,32, \
                      33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, \
                      48,49}
  #elif DECDPUN==2
    #define DECDPUNMAX 99
    #define D2UTABLE {0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,  \
                      11,11,12,12,13,13,14,14,15,15,16,16,17,17,18, \
                      18,19,19,20,20,21,21,22,22,23,23,24,24,25}
  #elif DECDPUN==3
    #define DECDPUNMAX 999
    #define D2UTABLE {0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,  \
                      8,8,8,9,9,9,10,10,10,11,11,11,12,12,12,13,13, \
                      13,14,14,14,15,15,15,16,16,16,17}
  #elif DECDPUN==4
    #define DECDPUNMAX 9999
    #define D2UTABLE {0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,  \
                      6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10,11, \
                      11,11,11,12,12,12,12,13}
  #elif DECDPUN==5
    #define DECDPUNMAX 99999
    #define D2UTABLE {0,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,  \
                      5,5,5,5,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8,9,9,9,  \
                      9,9,10,10,10,10}
  #elif DECDPUN==6
    #define DECDPUNMAX 999999
    #define D2UTABLE {0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,  \
                      4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,8,  \
                      8,8,8,8,8,9}
  #elif DECDPUN==7
    #define DECDPUNMAX 9999999
    #define D2UTABLE {0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3,  \
                      4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,7,  \
                      7,7,7,7,7,7}
  #elif DECDPUN==8
    #define DECDPUNMAX 99999999
    #define D2UTABLE {0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,  \
                      3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,  \
                      6,6,6,6,6,7}
  #elif DECDPUN==9
    #define DECDPUNMAX 999999999
    #define D2UTABLE {0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,  \
                      3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,  \
                      5,5,6,6,6,6}
  #elif defined(DECDPUN)
    #error DECDPUN must be in the range 1-9
  #endif

  /* ----- Shared data (in decNumber.c) ----- */
  // Public powers of of ten array (powers[n]==10**n, 0<=n<=10)
  extern const uInt powers[];
  // Public lookup table used by the D2U macro (see below)
  #define DECMAXD2U 49
  extern const uByte d2utable[DECMAXD2U+1];

  /* ----- Macros ----- */
  // ISZERO -- return true if decNumber dn is a zero
  // [performance-critical in some situations]
  #define ISZERO(dn) decNumberIsZero(dn)     // now just a local name

  // X10 and X100 -- multiply integer i by 10 or 100
  // [shifts are usually faster than multiply; could be conditional]
  #define X10(i)  (((i)<<1)+((i)<<3))
  #define X100(i) (((i)<<2)+((i)<<5)+((i)<<6))

  // D2U -- return the number of Units needed to hold d digits
  // (runtime version, with table lookaside for small d)
  #if DECDPUN==8
    #define D2U(d) ((unsigned)((d)<=DECMAXD2U?d2utable[d]:((d)+7)>>3))
  #elif DECDPUN==4
    #define D2U(d) ((unsigned)((d)<=DECMAXD2U?d2utable[d]:((d)+3)>>2))
  #else
    #define D2U(d) ((d)<=DECMAXD2U?d2utable[d]:((d)+DECDPUN-1)/DECDPUN)
  #endif
  // SD2U -- static D2U macro (for compile-time calculation)
  #define SD2U(d) (((d)+DECDPUN-1)/DECDPUN)

  // MSUDIGITS -- returns digits in msu, calculated using D2U
  #define MSUDIGITS(d) ((d)-(D2U(d)-1)*DECDPUN)

  // D2N -- return the number of decNumber structs that would be
  // needed to contain that number of digits (and the initial
  // decNumber struct) safely.  Note that one Unit is included in the
  // initial structure.  Used for allocating space that is aligned on
  // a decNumber struct boundary.
  #define D2N(d) \
    ((((SD2U(d)-1)*sizeof(Unit))+sizeof(decNumber)*2-1)/sizeof(decNumber))

  // TODIGIT -- macro to remove the leading digit from the unsigned
  // integer u at column cut (counting from the right, LSD=0) and
  // place it as an ASCII character into the character pointed to by
  // c.  Note that cut must be <= 9, and the maximum value for u is
  // 2,000,000,000 (as is needed for negative exponents of
  // subnormals).  The unsigned integer pow is used as a temporary
  // variable.
  #define TODIGIT(u, cut, c, pow) {       \
    *(c)='0';                             \
    pow=powers[cut]*2;                    \
    if ((u)>pow) {                        \
      pow*=4;                             \
      if ((u)>=pow) {(u)-=pow; *(c)+=8;}  \
      pow/=2;                             \
      if ((u)>=pow) {(u)-=pow; *(c)+=4;}  \
      pow/=2;                             \
      }                                   \
    if ((u)>=pow) {(u)-=pow; *(c)+=2;}    \
    pow/=2;                               \
    if ((u)>=pow) {(u)-=pow; *(c)+=1;}    \
    }

  // MAX and MIN -- general max & min (not in ANSI)
  #define MAX(x,y) ((x)<(y)?(y):(x))
  #define MIN(x,y) ((x)>(y)?(y):(x))

#else
  #error decNumberLocal included more than once
#endif