dec_number 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. data/README +20 -0
  2. data/dec_number.gemspec +13 -0
  3. data/ext/dec_number/Gemfile +4 -0
  4. data/ext/dec_number/NOTES +10 -0
  5. data/ext/dec_number/decNumber/ICU-license.html +45 -0
  6. data/ext/dec_number/decNumber/Makefile.am +3 -0
  7. data/ext/dec_number/decNumber/Makefile.in +680 -0
  8. data/ext/dec_number/decNumber/aclocal.m4 +8988 -0
  9. data/ext/dec_number/decNumber/autom4te.cache/output.0 +5107 -0
  10. data/ext/dec_number/decNumber/autom4te.cache/output.1 +6026 -0
  11. data/ext/dec_number/decNumber/autom4te.cache/output.2 +13468 -0
  12. data/ext/dec_number/decNumber/autom4te.cache/output.3 +13472 -0
  13. data/ext/dec_number/decNumber/autom4te.cache/requests +407 -0
  14. data/ext/dec_number/decNumber/autom4te.cache/traces.0 +352 -0
  15. data/ext/dec_number/decNumber/autom4te.cache/traces.1 +772 -0
  16. data/ext/dec_number/decNumber/autom4te.cache/traces.2 +591 -0
  17. data/ext/dec_number/decNumber/autom4te.cache/traces.3 +2362 -0
  18. data/ext/dec_number/decNumber/config.guess +1501 -0
  19. data/ext/dec_number/decNumber/config.h.in +142 -0
  20. data/ext/dec_number/decNumber/config.sub +1705 -0
  21. data/ext/dec_number/decNumber/configure +13468 -0
  22. data/ext/dec_number/decNumber/configure.ac +36 -0
  23. data/ext/dec_number/decNumber/decBasic.c +3908 -0
  24. data/ext/dec_number/decNumber/decCommon.c +1835 -0
  25. data/ext/dec_number/decNumber/decContext.c +437 -0
  26. data/ext/dec_number/decNumber/decContext.h +254 -0
  27. data/ext/dec_number/decNumber/decDPD.h +1185 -0
  28. data/ext/dec_number/decNumber/decDouble.c +140 -0
  29. data/ext/dec_number/decNumber/decDouble.h +155 -0
  30. data/ext/dec_number/decNumber/decNumber.c +8141 -0
  31. data/ext/dec_number/decNumber/decNumber.h +182 -0
  32. data/ext/dec_number/decNumber/decNumberLocal.h +757 -0
  33. data/ext/dec_number/decNumber/decPacked.c +220 -0
  34. data/ext/dec_number/decNumber/decPacked.h +52 -0
  35. data/ext/dec_number/decNumber/decQuad.c +135 -0
  36. data/ext/dec_number/decNumber/decQuad.h +177 -0
  37. data/ext/dec_number/decNumber/decSingle.c +71 -0
  38. data/ext/dec_number/decNumber/decSingle.h +86 -0
  39. data/ext/dec_number/decNumber/decimal128.c +553 -0
  40. data/ext/dec_number/decNumber/decimal128.h +81 -0
  41. data/ext/dec_number/decNumber/decimal32.c +476 -0
  42. data/ext/dec_number/decNumber/decimal32.h +81 -0
  43. data/ext/dec_number/decNumber/decimal64.c +839 -0
  44. data/ext/dec_number/decNumber/decimal64.h +83 -0
  45. data/ext/dec_number/decNumber/decnumber.pdf +0 -0
  46. data/ext/dec_number/decNumber/depcomp +630 -0
  47. data/ext/dec_number/decNumber/example1.c +38 -0
  48. data/ext/dec_number/decNumber/example2.c +52 -0
  49. data/ext/dec_number/decNumber/example3.c +64 -0
  50. data/ext/dec_number/decNumber/example4.c +61 -0
  51. data/ext/dec_number/decNumber/example5.c +36 -0
  52. data/ext/dec_number/decNumber/example6.c +61 -0
  53. data/ext/dec_number/decNumber/example7.c +35 -0
  54. data/ext/dec_number/decNumber/example8.c +39 -0
  55. data/ext/dec_number/decNumber/install-sh +520 -0
  56. data/ext/dec_number/decNumber/libdecNumber.a +0 -0
  57. data/ext/dec_number/decNumber/ltmain.sh +8745 -0
  58. data/ext/dec_number/decNumber/missing +376 -0
  59. data/ext/dec_number/decNumber/readme.txt +81 -0
  60. data/ext/dec_number/dec_number.c +464 -0
  61. data/ext/dec_number/extconf.rb +52 -0
  62. data/ext/dec_number/extconf2.rb +50 -0
  63. data/ext/dec_number/recompile.sh +3 -0
  64. data/ext/dec_number/test_dec_number.rb +236 -0
  65. data/ext/dec_number/test_numeric.rb +235 -0
  66. metadata +111 -0
@@ -0,0 +1,86 @@
1
+ /* ------------------------------------------------------------------ */
2
+ /* decSingle.h -- Decimal 32-bit format module header */
3
+ /* ------------------------------------------------------------------ */
4
+ /* Copyright (c) IBM Corporation, 2000, 2008. All rights reserved. */
5
+ /* */
6
+ /* This software is made available under the terms of the */
7
+ /* ICU License -- ICU 1.8.1 and later. */
8
+ /* */
9
+ /* The description and User's Guide ("The decNumber C Library") for */
10
+ /* this software is included in the package as decNumber.pdf. This */
11
+ /* document is also available in HTML, together with specifications, */
12
+ /* testcases, and Web links, on the General Decimal Arithmetic page. */
13
+ /* */
14
+ /* Please send comments, suggestions, and corrections to the author: */
15
+ /* mfc@uk.ibm.com */
16
+ /* Mike Cowlishaw, IBM Fellow */
17
+ /* IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK */
18
+ /* ------------------------------------------------------------------ */
19
+
20
+ #if !defined(DECSINGLE)
21
+ #define DECSINGLE
22
+
23
+ #define DECSINGLENAME "decSingle" /* Short name */
24
+ #define DECSINGLETITLE "Decimal 32-bit datum" /* Verbose name */
25
+ #define DECSINGLEAUTHOR "Mike Cowlishaw" /* Who to blame */
26
+
27
+ /* parameters for decSingles */
28
+ #define DECSINGLE_Bytes 4 /* length */
29
+ #define DECSINGLE_Pmax 7 /* maximum precision (digits) */
30
+ #define DECSINGLE_Emin -95 /* minimum adjusted exponent */
31
+ #define DECSINGLE_Emax 96 /* maximum adjusted exponent */
32
+ #define DECSINGLE_EmaxD 3 /* maximum exponent digits */
33
+ #define DECSINGLE_Bias 101 /* bias for the exponent */
34
+ #define DECSINGLE_String 16 /* maximum string length, +1 */
35
+ #define DECSINGLE_EconL 6 /* exponent continuation length */
36
+ #define DECSINGLE_Declets 2 /* count of declets */
37
+ /* highest biased exponent (Elimit-1) */
38
+ #define DECSINGLE_Ehigh (DECSINGLE_Emax + DECSINGLE_Bias - (DECSINGLE_Pmax-1))
39
+
40
+ /* Required includes */
41
+ #include "decContext.h"
42
+ #include "decQuad.h"
43
+ #include "decDouble.h"
44
+
45
+ /* The decSingle decimal 32-bit type, accessible by all sizes */
46
+ typedef union {
47
+ uint8_t bytes[DECSINGLE_Bytes]; /* fields: 1, 5, 6, 20 bits */
48
+ uint16_t shorts[DECSINGLE_Bytes/2];
49
+ uint32_t words[DECSINGLE_Bytes/4];
50
+ } decSingle;
51
+
52
+ /* ---------------------------------------------------------------- */
53
+ /* Routines -- implemented as decFloat routines in common files */
54
+ /* ---------------------------------------------------------------- */
55
+
56
+ /* Utilities (binary argument(s) or result, extractors, etc.) */
57
+ extern decSingle * decSingleFromBCD(decSingle *, int32_t, const uint8_t *, int32_t);
58
+ extern decSingle * decSingleFromPacked(decSingle *, int32_t, const uint8_t *);
59
+ extern decSingle * decSingleFromPackedChecked(decSingle *, int32_t, const uint8_t *);
60
+ extern decSingle * decSingleFromString(decSingle *, const char *, decContext *);
61
+ extern decSingle * decSingleFromWider(decSingle *, const decDouble *, decContext *);
62
+ extern int32_t decSingleGetCoefficient(const decSingle *, uint8_t *);
63
+ extern int32_t decSingleGetExponent(const decSingle *);
64
+ extern decSingle * decSingleSetCoefficient(decSingle *, const uint8_t *, int32_t);
65
+ extern decSingle * decSingleSetExponent(decSingle *, decContext *, int32_t);
66
+ extern void decSingleShow(const decSingle *, const char *);
67
+ extern int32_t decSingleToBCD(const decSingle *, int32_t *, uint8_t *);
68
+ extern char * decSingleToEngString(const decSingle *, char *);
69
+ extern int32_t decSingleToPacked(const decSingle *, int32_t *, uint8_t *);
70
+ extern char * decSingleToString(const decSingle *, char *);
71
+ extern decDouble * decSingleToWider(const decSingle *, decDouble *);
72
+ extern decSingle * decSingleZero(decSingle *);
73
+
74
+ /* (No Arithmetic routines for decSingle) */
75
+
76
+ /* Non-computational */
77
+ extern uint32_t decSingleRadix(const decSingle *);
78
+ extern const char * decSingleVersion(void);
79
+
80
+ /* decNumber conversions; these are implemented as macros so as not */
81
+ /* to force a dependency on decimal32 and decNumber in decSingle. */
82
+ /* decSingleFromNumber returns a decimal32 * to avoid warnings. */
83
+ #define decSingleToNumber(dq, dn) decimal32ToNumber((decimal32 *)(dq), dn)
84
+ #define decSingleFromNumber(dq, dn, set) decimal32FromNumber((decimal32 *)(dq), dn, set)
85
+
86
+ #endif
@@ -0,0 +1,553 @@
1
+ /* ------------------------------------------------------------------ */
2
+ /* Decimal 128-bit format module */
3
+ /* ------------------------------------------------------------------ */
4
+ /* Copyright (c) IBM Corporation, 2000, 2008. All rights reserved. */
5
+ /* */
6
+ /* This software is made available under the terms of the */
7
+ /* ICU License -- ICU 1.8.1 and later. */
8
+ /* */
9
+ /* The description and User's Guide ("The decNumber C Library") for */
10
+ /* this software is called decNumber.pdf. This document is */
11
+ /* available, together with arithmetic and format specifications, */
12
+ /* testcases, and Web links, on the General Decimal Arithmetic page. */
13
+ /* */
14
+ /* Please send comments, suggestions, and corrections to the author: */
15
+ /* mfc@uk.ibm.com */
16
+ /* Mike Cowlishaw, IBM Fellow */
17
+ /* IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK */
18
+ /* ------------------------------------------------------------------ */
19
+ /* This module comprises the routines for decimal128 format numbers. */
20
+ /* Conversions are supplied to and from decNumber and String. */
21
+ /* */
22
+ /* This is used when decNumber provides operations, either for all */
23
+ /* operations or as a proxy between decNumber and decSingle. */
24
+ /* */
25
+ /* Error handling is the same as decNumber (qv.). */
26
+ /* ------------------------------------------------------------------ */
27
+ #include <string.h> // [for memset/memcpy]
28
+ #include <stdio.h> // [for printf]
29
+
30
+ #define DECNUMDIGITS 34 // make decNumbers with space for 34
31
+ #include "decNumber.h" // base number library
32
+ #include "decNumberLocal.h" // decNumber local types, etc.
33
+ #include "decimal128.h" // our primary include
34
+
35
+ /* Utility routines and tables [in decimal64.c] */
36
+ // DPD2BIN and the reverse are renamed to prevent link-time conflict
37
+ // if decQuad is also built in the same executable
38
+ #define DPD2BIN DPD2BINx
39
+ #define BIN2DPD BIN2DPDx
40
+ extern const uInt COMBEXP[32], COMBMSD[32];
41
+ extern const uShort DPD2BIN[1024];
42
+ extern const uShort BIN2DPD[1000]; // [not used]
43
+ extern const uByte BIN2CHAR[4001];
44
+
45
+ extern void decDigitsFromDPD(decNumber *, const uInt *, Int);
46
+ extern void decDigitsToDPD(const decNumber *, uInt *, Int);
47
+
48
+ #if DECTRACE || DECCHECK
49
+ void decimal128Show(const decimal128 *); // for debug
50
+ extern void decNumberShow(const decNumber *); // ..
51
+ #endif
52
+
53
+ /* Useful macro */
54
+ // Clear a structure (e.g., a decNumber)
55
+ #define DEC_clear(d) memset(d, 0, sizeof(*d))
56
+
57
+ /* ------------------------------------------------------------------ */
58
+ /* decimal128FromNumber -- convert decNumber to decimal128 */
59
+ /* */
60
+ /* ds is the target decimal128 */
61
+ /* dn is the source number (assumed valid) */
62
+ /* set is the context, used only for reporting errors */
63
+ /* */
64
+ /* The set argument is used only for status reporting and for the */
65
+ /* rounding mode (used if the coefficient is more than DECIMAL128_Pmax*/
66
+ /* digits or an overflow is detected). If the exponent is out of the */
67
+ /* valid range then Overflow or Underflow will be raised. */
68
+ /* After Underflow a subnormal result is possible. */
69
+ /* */
70
+ /* DEC_Clamped is set if the number has to be 'folded down' to fit, */
71
+ /* by reducing its exponent and multiplying the coefficient by a */
72
+ /* power of ten, or if the exponent on a zero had to be clamped. */
73
+ /* ------------------------------------------------------------------ */
74
+ decimal128 * decimal128FromNumber(decimal128 *d128, const decNumber *dn,
75
+ decContext *set) {
76
+ uInt status=0; // status accumulator
77
+ Int ae; // adjusted exponent
78
+ decNumber dw; // work
79
+ decContext dc; // ..
80
+ uInt comb, exp; // ..
81
+ uInt uiwork; // for macros
82
+ uInt targar[4]={0,0,0,0}; // target 128-bit
83
+ #define targhi targar[3] // name the word with the sign
84
+ #define targmh targar[2] // name the words
85
+ #define targml targar[1] // ..
86
+ #define targlo targar[0] // ..
87
+
88
+ // If the number has too many digits, or the exponent could be
89
+ // out of range then reduce the number under the appropriate
90
+ // constraints. This could push the number to Infinity or zero,
91
+ // so this check and rounding must be done before generating the
92
+ // decimal128]
93
+ ae=dn->exponent+dn->digits-1; // [0 if special]
94
+ if (dn->digits>DECIMAL128_Pmax // too many digits
95
+ || ae>DECIMAL128_Emax // likely overflow
96
+ || ae<DECIMAL128_Emin) { // likely underflow
97
+ decContextDefault(&dc, DEC_INIT_DECIMAL128); // [no traps]
98
+ dc.round=set->round; // use supplied rounding
99
+ decNumberPlus(&dw, dn, &dc); // (round and check)
100
+ // [this changes -0 to 0, so enforce the sign...]
101
+ dw.bits|=dn->bits&DECNEG;
102
+ status=dc.status; // save status
103
+ dn=&dw; // use the work number
104
+ } // maybe out of range
105
+
106
+ if (dn->bits&DECSPECIAL) { // a special value
107
+ if (dn->bits&DECINF) targhi=DECIMAL_Inf<<24;
108
+ else { // sNaN or qNaN
109
+ if ((*dn->lsu!=0 || dn->digits>1) // non-zero coefficient
110
+ && (dn->digits<DECIMAL128_Pmax)) { // coefficient fits
111
+ decDigitsToDPD(dn, targar, 0);
112
+ }
113
+ if (dn->bits&DECNAN) targhi|=DECIMAL_NaN<<24;
114
+ else targhi|=DECIMAL_sNaN<<24;
115
+ } // a NaN
116
+ } // special
117
+
118
+ else { // is finite
119
+ if (decNumberIsZero(dn)) { // is a zero
120
+ // set and clamp exponent
121
+ if (dn->exponent<-DECIMAL128_Bias) {
122
+ exp=0; // low clamp
123
+ status|=DEC_Clamped;
124
+ }
125
+ else {
126
+ exp=dn->exponent+DECIMAL128_Bias; // bias exponent
127
+ if (exp>DECIMAL128_Ehigh) { // top clamp
128
+ exp=DECIMAL128_Ehigh;
129
+ status|=DEC_Clamped;
130
+ }
131
+ }
132
+ comb=(exp>>9) & 0x18; // msd=0, exp top 2 bits ..
133
+ }
134
+ else { // non-zero finite number
135
+ uInt msd; // work
136
+ Int pad=0; // coefficient pad digits
137
+
138
+ // the dn is known to fit, but it may need to be padded
139
+ exp=(uInt)(dn->exponent+DECIMAL128_Bias); // bias exponent
140
+ if (exp>DECIMAL128_Ehigh) { // fold-down case
141
+ pad=exp-DECIMAL128_Ehigh;
142
+ exp=DECIMAL128_Ehigh; // [to maximum]
143
+ status|=DEC_Clamped;
144
+ }
145
+
146
+ // [fastpath for common case is not a win, here]
147
+ decDigitsToDPD(dn, targar, pad);
148
+ // save and clear the top digit
149
+ msd=targhi>>14;
150
+ targhi&=0x00003fff;
151
+
152
+ // create the combination field
153
+ if (msd>=8) comb=0x18 | ((exp>>11) & 0x06) | (msd & 0x01);
154
+ else comb=((exp>>9) & 0x18) | msd;
155
+ }
156
+ targhi|=comb<<26; // add combination field ..
157
+ targhi|=(exp&0xfff)<<14; // .. and exponent continuation
158
+ } // finite
159
+
160
+ if (dn->bits&DECNEG) targhi|=0x80000000; // add sign bit
161
+
162
+ // now write to storage; this is endian
163
+ if (DECLITEND) {
164
+ // lo -> hi
165
+ UBFROMUI(d128->bytes, targlo);
166
+ UBFROMUI(d128->bytes+4, targml);
167
+ UBFROMUI(d128->bytes+8, targmh);
168
+ UBFROMUI(d128->bytes+12, targhi);
169
+ }
170
+ else {
171
+ // hi -> lo
172
+ UBFROMUI(d128->bytes, targhi);
173
+ UBFROMUI(d128->bytes+4, targmh);
174
+ UBFROMUI(d128->bytes+8, targml);
175
+ UBFROMUI(d128->bytes+12, targlo);
176
+ }
177
+
178
+ if (status!=0) decContextSetStatus(set, status); // pass on status
179
+ // decimal128Show(d128);
180
+ return d128;
181
+ } // decimal128FromNumber
182
+
183
+ /* ------------------------------------------------------------------ */
184
+ /* decimal128ToNumber -- convert decimal128 to decNumber */
185
+ /* d128 is the source decimal128 */
186
+ /* dn is the target number, with appropriate space */
187
+ /* No error is possible. */
188
+ /* ------------------------------------------------------------------ */
189
+ decNumber * decimal128ToNumber(const decimal128 *d128, decNumber *dn) {
190
+ uInt msd; // coefficient MSD
191
+ uInt exp; // exponent top two bits
192
+ uInt comb; // combination field
193
+ Int need; // work
194
+ uInt uiwork; // for macros
195
+ uInt sourar[4]; // source 128-bit
196
+ #define sourhi sourar[3] // name the word with the sign
197
+ #define sourmh sourar[2] // and the mid-high word
198
+ #define sourml sourar[1] // and the mod-low word
199
+ #define sourlo sourar[0] // and the lowest word
200
+
201
+ // load source from storage; this is endian
202
+ if (DECLITEND) {
203
+ sourlo=UBTOUI(d128->bytes ); // directly load the low int
204
+ sourml=UBTOUI(d128->bytes+4 ); // then the mid-low
205
+ sourmh=UBTOUI(d128->bytes+8 ); // then the mid-high
206
+ sourhi=UBTOUI(d128->bytes+12); // then the high int
207
+ }
208
+ else {
209
+ sourhi=UBTOUI(d128->bytes ); // directly load the high int
210
+ sourmh=UBTOUI(d128->bytes+4 ); // then the mid-high
211
+ sourml=UBTOUI(d128->bytes+8 ); // then the mid-low
212
+ sourlo=UBTOUI(d128->bytes+12); // then the low int
213
+ }
214
+
215
+ comb=(sourhi>>26)&0x1f; // combination field
216
+
217
+ decNumberZero(dn); // clean number
218
+ if (sourhi&0x80000000) dn->bits=DECNEG; // set sign if negative
219
+
220
+ msd=COMBMSD[comb]; // decode the combination field
221
+ exp=COMBEXP[comb]; // ..
222
+
223
+ if (exp==3) { // is a special
224
+ if (msd==0) {
225
+ dn->bits|=DECINF;
226
+ return dn; // no coefficient needed
227
+ }
228
+ else if (sourhi&0x02000000) dn->bits|=DECSNAN;
229
+ else dn->bits|=DECNAN;
230
+ msd=0; // no top digit
231
+ }
232
+ else { // is a finite number
233
+ dn->exponent=(exp<<12)+((sourhi>>14)&0xfff)-DECIMAL128_Bias; // unbiased
234
+ }
235
+
236
+ // get the coefficient
237
+ sourhi&=0x00003fff; // clean coefficient continuation
238
+ if (msd) { // non-zero msd
239
+ sourhi|=msd<<14; // prefix to coefficient
240
+ need=12; // process 12 declets
241
+ }
242
+ else { // msd=0
243
+ if (sourhi) need=11; // declets to process
244
+ else if (sourmh) need=10;
245
+ else if (sourml) need=7;
246
+ else if (sourlo) need=4;
247
+ else return dn; // easy: coefficient is 0
248
+ } //msd=0
249
+
250
+ decDigitsFromDPD(dn, sourar, need); // process declets
251
+ // decNumberShow(dn);
252
+ return dn;
253
+ } // decimal128ToNumber
254
+
255
+ /* ------------------------------------------------------------------ */
256
+ /* to-scientific-string -- conversion to numeric string */
257
+ /* to-engineering-string -- conversion to numeric string */
258
+ /* */
259
+ /* decimal128ToString(d128, string); */
260
+ /* decimal128ToEngString(d128, string); */
261
+ /* */
262
+ /* d128 is the decimal128 format number to convert */
263
+ /* string is the string where the result will be laid out */
264
+ /* */
265
+ /* string must be at least 24 characters */
266
+ /* */
267
+ /* No error is possible, and no status can be set. */
268
+ /* ------------------------------------------------------------------ */
269
+ char * decimal128ToEngString(const decimal128 *d128, char *string){
270
+ decNumber dn; // work
271
+ decimal128ToNumber(d128, &dn);
272
+ decNumberToEngString(&dn, string);
273
+ return string;
274
+ } // decimal128ToEngString
275
+
276
+ char * decimal128ToString(const decimal128 *d128, char *string){
277
+ uInt msd; // coefficient MSD
278
+ Int exp; // exponent top two bits or full
279
+ uInt comb; // combination field
280
+ char *cstart; // coefficient start
281
+ char *c; // output pointer in string
282
+ const uByte *u; // work
283
+ char *s, *t; // .. (source, target)
284
+ Int dpd; // ..
285
+ Int pre, e; // ..
286
+ uInt uiwork; // for macros
287
+
288
+ uInt sourar[4]; // source 128-bit
289
+ #define sourhi sourar[3] // name the word with the sign
290
+ #define sourmh sourar[2] // and the mid-high word
291
+ #define sourml sourar[1] // and the mod-low word
292
+ #define sourlo sourar[0] // and the lowest word
293
+
294
+ // load source from storage; this is endian
295
+ if (DECLITEND) {
296
+ sourlo=UBTOUI(d128->bytes ); // directly load the low int
297
+ sourml=UBTOUI(d128->bytes+4 ); // then the mid-low
298
+ sourmh=UBTOUI(d128->bytes+8 ); // then the mid-high
299
+ sourhi=UBTOUI(d128->bytes+12); // then the high int
300
+ }
301
+ else {
302
+ sourhi=UBTOUI(d128->bytes ); // directly load the high int
303
+ sourmh=UBTOUI(d128->bytes+4 ); // then the mid-high
304
+ sourml=UBTOUI(d128->bytes+8 ); // then the mid-low
305
+ sourlo=UBTOUI(d128->bytes+12); // then the low int
306
+ }
307
+
308
+ c=string; // where result will go
309
+ if (((Int)sourhi)<0) *c++='-'; // handle sign
310
+
311
+ comb=(sourhi>>26)&0x1f; // combination field
312
+ msd=COMBMSD[comb]; // decode the combination field
313
+ exp=COMBEXP[comb]; // ..
314
+
315
+ if (exp==3) {
316
+ if (msd==0) { // infinity
317
+ strcpy(c, "Inf");
318
+ strcpy(c+3, "inity");
319
+ return string; // easy
320
+ }
321
+ if (sourhi&0x02000000) *c++='s'; // sNaN
322
+ strcpy(c, "NaN"); // complete word
323
+ c+=3; // step past
324
+ if (sourlo==0 && sourml==0 && sourmh==0
325
+ && (sourhi&0x0003ffff)==0) return string; // zero payload
326
+ // otherwise drop through to add integer; set correct exp
327
+ exp=0; msd=0; // setup for following code
328
+ }
329
+ else exp=(exp<<12)+((sourhi>>14)&0xfff)-DECIMAL128_Bias; // unbiased
330
+
331
+ // convert 34 digits of significand to characters
332
+ cstart=c; // save start of coefficient
333
+ if (msd) *c++='0'+(char)msd; // non-zero most significant digit
334
+
335
+ // Now decode the declets. After extracting each one, it is
336
+ // decoded to binary and then to a 4-char sequence by table lookup;
337
+ // the 4-chars are a 1-char length (significant digits, except 000
338
+ // has length 0). This allows us to left-align the first declet
339
+ // with non-zero content, then remaining ones are full 3-char
340
+ // length. We use fixed-length memcpys because variable-length
341
+ // causes a subroutine call in GCC. (These are length 4 for speed
342
+ // and are safe because the array has an extra terminator byte.)
343
+ #define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; \
344
+ if (c!=cstart) {memcpy(c, u+1, 4); c+=3;} \
345
+ else if (*u) {memcpy(c, u+4-*u, 4); c+=*u;}
346
+ dpd=(sourhi>>4)&0x3ff; // declet 1
347
+ dpd2char;
348
+ dpd=((sourhi&0xf)<<6) | (sourmh>>26); // declet 2
349
+ dpd2char;
350
+ dpd=(sourmh>>16)&0x3ff; // declet 3
351
+ dpd2char;
352
+ dpd=(sourmh>>6)&0x3ff; // declet 4
353
+ dpd2char;
354
+ dpd=((sourmh&0x3f)<<4) | (sourml>>28); // declet 5
355
+ dpd2char;
356
+ dpd=(sourml>>18)&0x3ff; // declet 6
357
+ dpd2char;
358
+ dpd=(sourml>>8)&0x3ff; // declet 7
359
+ dpd2char;
360
+ dpd=((sourml&0xff)<<2) | (sourlo>>30); // declet 8
361
+ dpd2char;
362
+ dpd=(sourlo>>20)&0x3ff; // declet 9
363
+ dpd2char;
364
+ dpd=(sourlo>>10)&0x3ff; // declet 10
365
+ dpd2char;
366
+ dpd=(sourlo)&0x3ff; // declet 11
367
+ dpd2char;
368
+
369
+ if (c==cstart) *c++='0'; // all zeros -- make 0
370
+
371
+ if (exp==0) { // integer or NaN case -- easy
372
+ *c='\0'; // terminate
373
+ return string;
374
+ }
375
+
376
+ /* non-0 exponent */
377
+ e=0; // assume no E
378
+ pre=c-cstart+exp;
379
+ // [here, pre-exp is the digits count (==1 for zero)]
380
+ if (exp>0 || pre<-5) { // need exponential form
381
+ e=pre-1; // calculate E value
382
+ pre=1; // assume one digit before '.'
383
+ } // exponential form
384
+
385
+ /* modify the coefficient, adding 0s, '.', and E+nn as needed */
386
+ s=c-1; // source (LSD)
387
+ if (pre>0) { // ddd.ddd (plain), perhaps with E
388
+ char *dotat=cstart+pre;
389
+ if (dotat<c) { // if embedded dot needed...
390
+ t=c; // target
391
+ for (; s>=dotat; s--, t--) *t=*s; // open the gap; leave t at gap
392
+ *t='.'; // insert the dot
393
+ c++; // length increased by one
394
+ }
395
+
396
+ // finally add the E-part, if needed; it will never be 0, and has
397
+ // a maximum length of 4 digits
398
+ if (e!=0) {
399
+ *c++='E'; // starts with E
400
+ *c++='+'; // assume positive
401
+ if (e<0) {
402
+ *(c-1)='-'; // oops, need '-'
403
+ e=-e; // uInt, please
404
+ }
405
+ if (e<1000) { // 3 (or fewer) digits case
406
+ u=&BIN2CHAR[e*4]; // -> length byte
407
+ memcpy(c, u+4-*u, 4); // copy fixed 4 characters [is safe]
408
+ c+=*u; // bump pointer appropriately
409
+ }
410
+ else { // 4-digits
411
+ Int thou=((e>>3)*1049)>>17; // e/1000
412
+ Int rem=e-(1000*thou); // e%1000
413
+ *c++='0'+(char)thou;
414
+ u=&BIN2CHAR[rem*4]; // -> length byte
415
+ memcpy(c, u+1, 4); // copy fixed 3+1 characters [is safe]
416
+ c+=3; // bump pointer, always 3 digits
417
+ }
418
+ }
419
+ *c='\0'; // add terminator
420
+ //printf("res %s\n", string);
421
+ return string;
422
+ } // pre>0
423
+
424
+ /* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (can never have E) */
425
+ t=c+1-pre;
426
+ *(t+1)='\0'; // can add terminator now
427
+ for (; s>=cstart; s--, t--) *t=*s; // shift whole coefficient right
428
+ c=cstart;
429
+ *c++='0'; // always starts with 0.
430
+ *c++='.';
431
+ for (; pre<0; pre++) *c++='0'; // add any 0's after '.'
432
+ //printf("res %s\n", string);
433
+ return string;
434
+ } // decimal128ToString
435
+
436
+ /* ------------------------------------------------------------------ */
437
+ /* to-number -- conversion from numeric string */
438
+ /* */
439
+ /* decimal128FromString(result, string, set); */
440
+ /* */
441
+ /* result is the decimal128 format number which gets the result of */
442
+ /* the conversion */
443
+ /* *string is the character string which should contain a valid */
444
+ /* number (which may be a special value) */
445
+ /* set is the context */
446
+ /* */
447
+ /* The context is supplied to this routine is used for error handling */
448
+ /* (setting of status and traps) and for the rounding mode, only. */
449
+ /* If an error occurs, the result will be a valid decimal128 NaN. */
450
+ /* ------------------------------------------------------------------ */
451
+ decimal128 * decimal128FromString(decimal128 *result, const char *string,
452
+ decContext *set) {
453
+ decContext dc; // work
454
+ decNumber dn; // ..
455
+
456
+ decContextDefault(&dc, DEC_INIT_DECIMAL128); // no traps, please
457
+ dc.round=set->round; // use supplied rounding
458
+
459
+ decNumberFromString(&dn, string, &dc); // will round if needed
460
+ decimal128FromNumber(result, &dn, &dc);
461
+ if (dc.status!=0) { // something happened
462
+ decContextSetStatus(set, dc.status); // .. pass it on
463
+ }
464
+ return result;
465
+ } // decimal128FromString
466
+
467
+ /* ------------------------------------------------------------------ */
468
+ /* decimal128IsCanonical -- test whether encoding is canonical */
469
+ /* d128 is the source decimal128 */
470
+ /* returns 1 if the encoding of d128 is canonical, 0 otherwise */
471
+ /* No error is possible. */
472
+ /* ------------------------------------------------------------------ */
473
+ uInt decimal128IsCanonical(const decimal128 *d128) {
474
+ decNumber dn; // work
475
+ decimal128 canon; // ..
476
+ decContext dc; // ..
477
+ decContextDefault(&dc, DEC_INIT_DECIMAL128);
478
+ decimal128ToNumber(d128, &dn);
479
+ decimal128FromNumber(&canon, &dn, &dc);// canon will now be canonical
480
+ return memcmp(d128, &canon, DECIMAL128_Bytes)==0;
481
+ } // decimal128IsCanonical
482
+
483
+ /* ------------------------------------------------------------------ */
484
+ /* decimal128Canonical -- copy an encoding, ensuring it is canonical */
485
+ /* d128 is the source decimal128 */
486
+ /* result is the target (may be the same decimal128) */
487
+ /* returns result */
488
+ /* No error is possible. */
489
+ /* ------------------------------------------------------------------ */
490
+ decimal128 * decimal128Canonical(decimal128 *result, const decimal128 *d128) {
491
+ decNumber dn; // work
492
+ decContext dc; // ..
493
+ decContextDefault(&dc, DEC_INIT_DECIMAL128);
494
+ decimal128ToNumber(d128, &dn);
495
+ decimal128FromNumber(result, &dn, &dc);// result will now be canonical
496
+ return result;
497
+ } // decimal128Canonical
498
+
499
+ #if DECTRACE || DECCHECK
500
+ /* Macros for accessing decimal128 fields. These assume the argument
501
+ is a reference (pointer) to the decimal128 structure, and the
502
+ decimal128 is in network byte order (big-endian) */
503
+ // Get sign
504
+ #define decimal128Sign(d) ((unsigned)(d)->bytes[0]>>7)
505
+
506
+ // Get combination field
507
+ #define decimal128Comb(d) (((d)->bytes[0] & 0x7c)>>2)
508
+
509
+ // Get exponent continuation [does not remove bias]
510
+ #define decimal128ExpCon(d) ((((d)->bytes[0] & 0x03)<<10) \
511
+ | ((unsigned)(d)->bytes[1]<<2) \
512
+ | ((unsigned)(d)->bytes[2]>>6))
513
+
514
+ // Set sign [this assumes sign previously 0]
515
+ #define decimal128SetSign(d, b) { \
516
+ (d)->bytes[0]|=((unsigned)(b)<<7);}
517
+
518
+ // Set exponent continuation [does not apply bias]
519
+ // This assumes range has been checked and exponent previously 0;
520
+ // type of exponent must be unsigned
521
+ #define decimal128SetExpCon(d, e) { \
522
+ (d)->bytes[0]|=(uByte)((e)>>10); \
523
+ (d)->bytes[1] =(uByte)(((e)&0x3fc)>>2); \
524
+ (d)->bytes[2]|=(uByte)(((e)&0x03)<<6);}
525
+
526
+ /* ------------------------------------------------------------------ */
527
+ /* decimal128Show -- display a decimal128 in hexadecimal [debug aid] */
528
+ /* d128 -- the number to show */
529
+ /* ------------------------------------------------------------------ */
530
+ // Also shows sign/cob/expconfields extracted
531
+ void decimal128Show(const decimal128 *d128) {
532
+ char buf[DECIMAL128_Bytes*2+1];
533
+ Int i, j=0;
534
+
535
+ if (DECLITEND) {
536
+ for (i=0; i<DECIMAL128_Bytes; i++, j+=2) {
537
+ sprintf(&buf[j], "%02x", d128->bytes[15-i]);
538
+ }
539
+ printf(" D128> %s [S:%d Cb:%02x Ec:%02x] LittleEndian\n", buf,
540
+ d128->bytes[15]>>7, (d128->bytes[15]>>2)&0x1f,
541
+ ((d128->bytes[15]&0x3)<<10)|(d128->bytes[14]<<2)|
542
+ (d128->bytes[13]>>6));
543
+ }
544
+ else {
545
+ for (i=0; i<DECIMAL128_Bytes; i++, j+=2) {
546
+ sprintf(&buf[j], "%02x", d128->bytes[i]);
547
+ }
548
+ printf(" D128> %s [S:%d Cb:%02x Ec:%02x] BigEndian\n", buf,
549
+ decimal128Sign(d128), decimal128Comb(d128),
550
+ decimal128ExpCon(d128));
551
+ }
552
+ } // decimal128Show
553
+ #endif