Mercurial > hg > CbC > CbC_gcc
annotate libdecnumber/decCommon.c @ 70:b81903832de2
merge c-decl.c
author | Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 21 Aug 2011 09:24:16 +0900 |
parents | 77e2b8dfacca |
children | 04ced10e8804 |
rev | line source |
---|---|
0 | 1 /* Common code for fixed-size types in the decNumber C Library. |
2 Copyright (C) 2007, 2009 Free Software Foundation, Inc. | |
3 Contributed by IBM Corporation. Author Mike Cowlishaw. | |
4 | |
5 This file is part of GCC. | |
6 | |
7 GCC is free software; you can redistribute it and/or modify it under | |
8 the terms of the GNU General Public License as published by the Free | |
9 Software Foundation; either version 3, or (at your option) any later | |
10 version. | |
11 | |
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 Under Section 7 of GPL version 3, you are granted additional | |
18 permissions described in the GCC Runtime Library Exception, version | |
19 3.1, as published by the Free Software Foundation. | |
20 | |
21 You should have received a copy of the GNU General Public License and | |
22 a copy of the GCC Runtime Library Exception along with this program; | |
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
24 <http://www.gnu.org/licenses/>. */ | |
25 | |
26 /* ------------------------------------------------------------------ */ | |
27 /* decCommon.c -- common code for all three fixed-size types */ | |
28 /* ------------------------------------------------------------------ */ | |
29 /* This module comprises code that is shared between all the formats */ | |
30 /* (decSingle, decDouble, and decQuad); it includes set and extract */ | |
31 /* of format components, widening, narrowing, and string conversions. */ | |
32 /* */ | |
33 /* Unlike decNumber, parameterization takes place at compile time */ | |
34 /* rather than at runtime. The parameters are set in the decDouble.c */ | |
35 /* (etc.) files, which then include this one to produce the compiled */ | |
36 /* code. The functions here, therefore, are code shared between */ | |
37 /* multiple formats. */ | |
38 /* ------------------------------------------------------------------ */ | |
39 /* Names here refer to decFloat rather than to decDouble, etc., and */ | |
40 /* the functions are in strict alphabetical order. */ | |
41 /* Constants, tables, and debug function(s) are included only for QUAD */ | |
42 /* (which will always be compiled if DOUBLE or SINGLE are used). */ | |
43 /* */ | |
44 /* Whenever a decContext is used, only the status may be set (using */ | |
45 /* OR) or the rounding mode read; all other fields are ignored and */ | |
46 /* untouched. */ | |
47 | |
48 #include "decCommonSymbols.h" | |
49 | |
50 /* names for simpler testing and default context */ | |
51 #if DECPMAX==7 | |
52 #define SINGLE 1 | |
53 #define DOUBLE 0 | |
54 #define QUAD 0 | |
55 #define DEFCONTEXT DEC_INIT_DECIMAL32 | |
56 #elif DECPMAX==16 | |
57 #define SINGLE 0 | |
58 #define DOUBLE 1 | |
59 #define QUAD 0 | |
60 #define DEFCONTEXT DEC_INIT_DECIMAL64 | |
61 #elif DECPMAX==34 | |
62 #define SINGLE 0 | |
63 #define DOUBLE 0 | |
64 #define QUAD 1 | |
65 #define DEFCONTEXT DEC_INIT_DECIMAL128 | |
66 #else | |
67 #error Unexpected DECPMAX value | |
68 #endif | |
69 | |
70 /* Assertions */ | |
71 | |
72 #if DECPMAX!=7 && DECPMAX!=16 && DECPMAX!=34 | |
73 #error Unexpected Pmax (DECPMAX) value for this module | |
74 #endif | |
75 | |
76 /* Assert facts about digit characters, etc. */ | |
77 #if ('9'&0x0f)!=9 | |
78 #error This module assumes characters are of the form 0b....nnnn | |
79 /* where .... are don't care 4 bits and nnnn is 0000 through 1001 */ | |
80 #endif | |
81 #if ('9'&0xf0)==('.'&0xf0) | |
82 #error This module assumes '.' has a different mask than a digit | |
83 #endif | |
84 | |
85 /* Assert ToString lay-out conditions */ | |
86 #if DECSTRING<DECPMAX+9 | |
87 #error ToString needs at least 8 characters for lead-in and dot | |
88 #endif | |
89 #if DECPMAX+DECEMAXD+5 > DECSTRING | |
90 #error Exponent form can be too long for ToString to lay out safely | |
91 #endif | |
92 #if DECEMAXD > 4 | |
93 #error Exponent form is too long for ToString to lay out | |
94 /* Note: code for up to 9 digits exists in archives [decOct] */ | |
95 #endif | |
96 | |
97 /* Private functions used here and possibly in decBasic.c, etc. */ | |
98 static decFloat * decFinalize(decFloat *, bcdnum *, decContext *); | |
99 static Flag decBiStr(const char *, const char *, const char *); | |
100 | |
101 /* Macros and private tables; those which are not format-dependent */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
102 /* are only included if decQuad is being built. */ |
0 | 103 |
104 /* ------------------------------------------------------------------ */ | |
105 /* Combination field lookup tables (uInts to save measurable work) */ | |
106 /* */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
107 /* DECCOMBEXP - 2 most-significant-bits of exponent (00, 01, or */ |
0 | 108 /* 10), shifted left for format, or DECFLOAT_Inf/NaN */ |
109 /* DECCOMBWEXP - The same, for the next-wider format (unless QUAD) */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
110 /* DECCOMBMSD - 4-bit most-significant-digit */ |
0 | 111 /* [0 if the index is a special (Infinity or NaN)] */ |
112 /* DECCOMBFROM - 5-bit combination field from EXP top bits and MSD */ | |
113 /* (placed in uInt so no shift is needed) */ | |
114 /* */ | |
115 /* DECCOMBEXP, DECCOMBWEXP, and DECCOMBMSD are indexed by the sign */ | |
116 /* and 5-bit combination field (0-63, the second half of the table */ | |
117 /* identical to the first half) */ | |
118 /* DECCOMBFROM is indexed by expTopTwoBits*16 + msd */ | |
119 /* */ | |
120 /* DECCOMBMSD and DECCOMBFROM are not format-dependent and so are */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
121 /* only included once, when QUAD is being built */ |
0 | 122 /* ------------------------------------------------------------------ */ |
123 static const uInt DECCOMBEXP[64]={ | |
124 0, 0, 0, 0, 0, 0, 0, 0, | |
125 1<<DECECONL, 1<<DECECONL, 1<<DECECONL, 1<<DECECONL, | |
126 1<<DECECONL, 1<<DECECONL, 1<<DECECONL, 1<<DECECONL, | |
127 2<<DECECONL, 2<<DECECONL, 2<<DECECONL, 2<<DECECONL, | |
128 2<<DECECONL, 2<<DECECONL, 2<<DECECONL, 2<<DECECONL, | |
129 0, 0, 1<<DECECONL, 1<<DECECONL, | |
130 2<<DECECONL, 2<<DECECONL, DECFLOAT_Inf, DECFLOAT_NaN, | |
131 0, 0, 0, 0, 0, 0, 0, 0, | |
132 1<<DECECONL, 1<<DECECONL, 1<<DECECONL, 1<<DECECONL, | |
133 1<<DECECONL, 1<<DECECONL, 1<<DECECONL, 1<<DECECONL, | |
134 2<<DECECONL, 2<<DECECONL, 2<<DECECONL, 2<<DECECONL, | |
135 2<<DECECONL, 2<<DECECONL, 2<<DECECONL, 2<<DECECONL, | |
136 0, 0, 1<<DECECONL, 1<<DECECONL, | |
137 2<<DECECONL, 2<<DECECONL, DECFLOAT_Inf, DECFLOAT_NaN}; | |
138 #if !QUAD | |
139 static const uInt DECCOMBWEXP[64]={ | |
140 0, 0, 0, 0, 0, 0, 0, 0, | |
141 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, | |
142 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, | |
143 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, | |
144 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, | |
145 0, 0, 1<<DECWECONL, 1<<DECWECONL, | |
146 2<<DECWECONL, 2<<DECWECONL, DECFLOAT_Inf, DECFLOAT_NaN, | |
147 0, 0, 0, 0, 0, 0, 0, 0, | |
148 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, | |
149 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, | |
150 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, | |
151 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, | |
152 0, 0, 1<<DECWECONL, 1<<DECWECONL, | |
153 2<<DECWECONL, 2<<DECWECONL, DECFLOAT_Inf, DECFLOAT_NaN}; | |
154 #endif | |
155 | |
156 #if QUAD | |
157 const uInt DECCOMBMSD[64]={ | |
158 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
159 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 0, |
0 | 160 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, |
161 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 0}; | |
162 | |
163 const uInt DECCOMBFROM[48]={ | |
164 0x00000000, 0x04000000, 0x08000000, 0x0C000000, 0x10000000, 0x14000000, | |
165 0x18000000, 0x1C000000, 0x60000000, 0x64000000, 0x00000000, 0x00000000, | |
166 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x20000000, 0x24000000, | |
167 0x28000000, 0x2C000000, 0x30000000, 0x34000000, 0x38000000, 0x3C000000, | |
168 0x68000000, 0x6C000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | |
169 0x00000000, 0x00000000, 0x40000000, 0x44000000, 0x48000000, 0x4C000000, | |
170 0x50000000, 0x54000000, 0x58000000, 0x5C000000, 0x70000000, 0x74000000, | |
171 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}; | |
172 | |
173 /* ------------------------------------------------------------------ */ | |
174 /* Request and include the tables to use for conversions */ | |
175 /* ------------------------------------------------------------------ */ | |
176 #define DEC_BCD2DPD 1 /* 0-0x999 -> DPD */ | |
177 #define DEC_BIN2DPD 1 /* 0-999 -> DPD */ | |
178 #define DEC_BIN2BCD8 1 /* 0-999 -> ddd, len */ | |
179 #define DEC_DPD2BCD8 1 /* DPD -> ddd, len */ | |
180 #define DEC_DPD2BIN 1 /* DPD -> 0-999 */ | |
181 #define DEC_DPD2BINK 1 /* DPD -> 0-999000 */ | |
182 #define DEC_DPD2BINM 1 /* DPD -> 0-999000000 */ | |
183 #include "decDPD.h" /* source of the lookup tables */ | |
184 | |
185 #endif | |
186 | |
187 /* ----------------------------------------------------------------- */ | |
188 /* decBiStr -- compare string with pairwise options */ | |
189 /* */ | |
190 /* targ is the string to compare */ | |
191 /* str1 is one of the strings to compare against (length may be 0) */ | |
192 /* str2 is the other; it must be the same length as str1 */ | |
193 /* */ | |
194 /* returns 1 if strings compare equal, (that is, targ is the same */ | |
195 /* length as str1 and str2, and each character of targ is in one */ | |
196 /* of str1 or str2 in the corresponding position), or 0 otherwise */ | |
197 /* */ | |
198 /* This is used for generic caseless compare, including the awkward */ | |
199 /* case of the Turkish dotted and dotless Is. Use as (for example): */ | |
200 /* if (decBiStr(test, "mike", "MIKE")) ... */ | |
201 /* ----------------------------------------------------------------- */ | |
202 static Flag decBiStr(const char *targ, const char *str1, const char *str2) { | |
203 for (;;targ++, str1++, str2++) { | |
204 if (*targ!=*str1 && *targ!=*str2) return 0; | |
205 /* *targ has a match in one (or both, if terminator) */ | |
206 if (*targ=='\0') break; | |
207 } /* forever */ | |
208 return 1; | |
209 } /* decBiStr */ | |
210 | |
211 /* ------------------------------------------------------------------ */ | |
212 /* decFinalize -- adjust and store a final result */ | |
213 /* */ | |
214 /* df is the decFloat format number which gets the final result */ | |
215 /* num is the descriptor of the number to be checked and encoded */ | |
216 /* [its values, including the coefficient, may be modified] */ | |
217 /* set is the context to use */ | |
218 /* returns df */ | |
219 /* */ | |
220 /* The num descriptor may point to a bcd8 string of any length; this */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
221 /* string may have leading insignificant zeros. If it has more than */ |
0 | 222 /* DECPMAX digits then the final digit can be a round-for-reround */ |
223 /* digit (i.e., it may include a sticky bit residue). */ | |
224 /* */ | |
225 /* The exponent (q) may be one of the codes for a special value and */ | |
226 /* can be up to 999999999 for conversion from string. */ | |
227 /* */ | |
228 /* No error is possible, but Inexact, Underflow, and/or Overflow may */ | |
229 /* be set. */ | |
230 /* ------------------------------------------------------------------ */ | |
231 /* Constant whose size varies with format; also the check for surprises */ | |
232 static uByte allnines[DECPMAX]= | |
233 #if SINGLE | |
234 {9, 9, 9, 9, 9, 9, 9}; | |
235 #elif DOUBLE | |
236 {9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9}; | |
237 #elif QUAD | |
238 {9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, | |
239 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9}; | |
240 #endif | |
241 | |
242 static decFloat * decFinalize(decFloat *df, bcdnum *num, | |
243 decContext *set) { | |
244 uByte *ub; /* work */ | |
245 uInt dpd; /* .. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
246 uInt uiwork; /* for macros */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
247 uByte *umsd=num->msd; /* local copy */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
248 uByte *ulsd=num->lsd; /* .. */ |
0 | 249 uInt encode; /* encoding accumulator */ |
250 Int length; /* coefficient length */ | |
251 | |
252 #if DECCHECK | |
253 Int clen=ulsd-umsd+1; | |
254 #if QUAD | |
255 #define COEXTRA 2 /* extra-long coefficent */ | |
256 #else | |
257 #define COEXTRA 0 | |
258 #endif | |
259 if (clen<1 || clen>DECPMAX*3+2+COEXTRA) | |
260 printf("decFinalize: suspect coefficient [length=%ld]\n", (LI)clen); | |
261 if (num->sign!=0 && num->sign!=DECFLOAT_Sign) | |
262 printf("decFinalize: bad sign [%08lx]\n", (LI)num->sign); | |
263 if (!EXPISSPECIAL(num->exponent) | |
264 && (num->exponent>1999999999 || num->exponent<-1999999999)) | |
265 printf("decFinalize: improbable exponent [%ld]\n", (LI)num->exponent); | |
266 /* decShowNum(num, "final"); */ | |
267 #endif | |
268 | |
269 /* A special will have an 'exponent' which is very positive and a */ | |
270 /* coefficient < DECPMAX */ | |
271 length=(uInt)(ulsd-umsd+1); /* coefficient length */ | |
272 | |
273 if (!NUMISSPECIAL(num)) { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
274 Int drop; /* digits to be dropped */ |
0 | 275 /* skip leading insignificant zeros to calculate an exact length */ |
276 /* [this is quite expensive] */ | |
277 if (*umsd==0) { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
278 for (; umsd+3<ulsd && UBTOUI(umsd)==0;) umsd+=4; |
0 | 279 for (; *umsd==0 && umsd<ulsd;) umsd++; |
280 length=ulsd-umsd+1; /* recalculate */ | |
281 } | |
282 drop=MAXI(length-DECPMAX, DECQTINY-num->exponent); | |
283 /* drop can now be > digits for bottom-clamp (subnormal) cases */ | |
284 if (drop>0) { /* rounding needed */ | |
285 /* (decFloatQuantize has very similar code to this, so any */ | |
286 /* changes may need to be made there, too) */ | |
287 uByte *roundat; /* -> re-round digit */ | |
288 uByte reround; /* reround value */ | |
289 /* printf("Rounding; drop=%ld\n", (LI)drop); */ | |
290 | |
291 num->exponent+=drop; /* always update exponent */ | |
292 | |
293 /* Three cases here: */ | |
294 /* 1. new LSD is in coefficient (almost always) */ | |
295 /* 2. new LSD is digit to left of coefficient (so MSD is */ | |
296 /* round-for-reround digit) */ | |
297 /* 3. new LSD is to left of case 2 (whole coefficient is sticky) */ | |
298 /* [duplicate check-stickies code to save a test] */ | |
299 /* [by-digit check for stickies as runs of zeros are rare] */ | |
300 if (drop<length) { /* NB lengths not addresses */ | |
301 roundat=umsd+length-drop; | |
302 reround=*roundat; | |
303 for (ub=roundat+1; ub<=ulsd; ub++) { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
304 if (*ub!=0) { /* non-zero to be discarded */ |
0 | 305 reround=DECSTICKYTAB[reround]; /* apply sticky bit */ |
306 break; /* [remainder don't-care] */ | |
307 } | |
308 } /* check stickies */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
309 ulsd=roundat-1; /* new LSD */ |
0 | 310 } |
311 else { /* edge case */ | |
312 if (drop==length) { | |
313 roundat=umsd; | |
314 reround=*roundat; | |
315 } | |
316 else { | |
317 roundat=umsd-1; | |
318 reround=0; | |
319 } | |
320 for (ub=roundat+1; ub<=ulsd; ub++) { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
321 if (*ub!=0) { /* non-zero to be discarded */ |
0 | 322 reround=DECSTICKYTAB[reround]; /* apply sticky bit */ |
323 break; /* [remainder don't-care] */ | |
324 } | |
325 } /* check stickies */ | |
326 *umsd=0; /* coefficient is a 0 */ | |
327 ulsd=umsd; /* .. */ | |
328 } | |
329 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
330 if (reround!=0) { /* discarding non-zero */ |
0 | 331 uInt bump=0; |
332 set->status|=DEC_Inexact; | |
333 /* if adjusted exponent [exp+digits-1] is < EMIN then num is */ | |
334 /* subnormal -- so raise Underflow */ | |
335 if (num->exponent<DECEMIN && (num->exponent+(ulsd-umsd+1)-1)<DECEMIN) | |
336 set->status|=DEC_Underflow; | |
337 | |
338 /* next decide whether increment of the coefficient is needed */ | |
339 if (set->round==DEC_ROUND_HALF_EVEN) { /* fastpath slowest case */ | |
340 if (reround>5) bump=1; /* >0.5 goes up */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
341 else if (reround==5) /* exactly 0.5000 .. */ |
0 | 342 bump=*ulsd & 0x01; /* .. up iff [new] lsd is odd */ |
343 } /* r-h-e */ | |
344 else switch (set->round) { | |
345 case DEC_ROUND_DOWN: { | |
346 /* no change */ | |
347 break;} /* r-d */ | |
348 case DEC_ROUND_HALF_DOWN: { | |
349 if (reround>5) bump=1; | |
350 break;} /* r-h-d */ | |
351 case DEC_ROUND_HALF_UP: { | |
352 if (reround>=5) bump=1; | |
353 break;} /* r-h-u */ | |
354 case DEC_ROUND_UP: { | |
355 if (reround>0) bump=1; | |
356 break;} /* r-u */ | |
357 case DEC_ROUND_CEILING: { | |
358 /* same as _UP for positive numbers, and as _DOWN for negatives */ | |
359 if (!num->sign && reround>0) bump=1; | |
360 break;} /* r-c */ | |
361 case DEC_ROUND_FLOOR: { | |
362 /* same as _UP for negative numbers, and as _DOWN for positive */ | |
363 /* [negative reround cannot occur on 0] */ | |
364 if (num->sign && reround>0) bump=1; | |
365 break;} /* r-f */ | |
366 case DEC_ROUND_05UP: { | |
367 if (reround>0) { /* anything out there is 'sticky' */ | |
368 /* bump iff lsd=0 or 5; this cannot carry so it could be */ | |
369 /* effected immediately with no bump -- but the code */ | |
370 /* is clearer if this is done the same way as the others */ | |
371 if (*ulsd==0 || *ulsd==5) bump=1; | |
372 } | |
373 break;} /* r-r */ | |
374 default: { /* e.g., DEC_ROUND_MAX */ | |
375 set->status|=DEC_Invalid_context; | |
376 #if DECCHECK | |
377 printf("Unknown rounding mode: %ld\n", (LI)set->round); | |
378 #endif | |
379 break;} | |
380 } /* switch (not r-h-e) */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
381 /* printf("ReRound: %ld bump: %ld\n", (LI)reround, (LI)bump); */ |
0 | 382 |
383 if (bump!=0) { /* need increment */ | |
384 /* increment the coefficient; this might end up with 1000... */ | |
385 /* (after the all nines case) */ | |
386 ub=ulsd; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
387 for(; ub-3>=umsd && UBTOUI(ub-3)==0x09090909; ub-=4) { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
388 UBFROMUI(ub-3, 0); /* to 00000000 */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
389 } |
0 | 390 /* [note ub could now be to left of msd, and it is not safe */ |
391 /* to write to the the left of the msd] */ | |
392 /* now at most 3 digits left to non-9 (usually just the one) */ | |
393 for (; ub>=umsd; *ub=0, ub--) { | |
394 if (*ub==9) continue; /* carry */ | |
395 *ub+=1; | |
396 break; | |
397 } | |
398 if (ub<umsd) { /* had all-nines */ | |
399 *umsd=1; /* coefficient to 1000... */ | |
400 /* usually the 1000... coefficient can be used as-is */ | |
401 if ((ulsd-umsd+1)==DECPMAX) { | |
402 num->exponent++; | |
403 } | |
404 else { | |
405 /* if coefficient is shorter than Pmax then num is */ | |
406 /* subnormal, so extend it; this is safe as drop>0 */ | |
407 /* (or, if the coefficient was supplied above, it could */ | |
408 /* not be 9); this may make the result normal. */ | |
409 ulsd++; | |
410 *ulsd=0; | |
411 /* [exponent unchanged] */ | |
412 #if DECCHECK | |
413 if (num->exponent!=DECQTINY) /* sanity check */ | |
414 printf("decFinalize: bad all-nines extend [^%ld, %ld]\n", | |
415 (LI)num->exponent, (LI)(ulsd-umsd+1)); | |
416 #endif | |
417 } /* subnormal extend */ | |
418 } /* had all-nines */ | |
419 } /* bump needed */ | |
420 } /* inexact rounding */ | |
421 | |
422 length=ulsd-umsd+1; /* recalculate (may be <DECPMAX) */ | |
423 } /* need round (drop>0) */ | |
424 | |
425 /* The coefficient will now fit and has final length unless overflow */ | |
426 /* decShowNum(num, "rounded"); */ | |
427 | |
428 /* if exponent is >=emax may have to clamp, overflow, or fold-down */ | |
429 if (num->exponent>DECEMAX-(DECPMAX-1)) { /* is edge case */ | |
430 /* printf("overflow checks...\n"); */ | |
431 if (*ulsd==0 && ulsd==umsd) { /* have zero */ | |
432 num->exponent=DECEMAX-(DECPMAX-1); /* clamp to max */ | |
433 } | |
434 else if ((num->exponent+length-1)>DECEMAX) { /* > Nmax */ | |
435 /* Overflow -- these could go straight to encoding, here, but */ | |
436 /* instead num is adjusted to keep the code cleaner */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
437 Flag needmax=0; /* 1 for finite result */ |
0 | 438 set->status|=(DEC_Overflow | DEC_Inexact); |
439 switch (set->round) { | |
440 case DEC_ROUND_DOWN: { | |
441 needmax=1; /* never Infinity */ | |
442 break;} /* r-d */ | |
443 case DEC_ROUND_05UP: { | |
444 needmax=1; /* never Infinity */ | |
445 break;} /* r-05 */ | |
446 case DEC_ROUND_CEILING: { | |
447 if (num->sign) needmax=1; /* Infinity iff non-negative */ | |
448 break;} /* r-c */ | |
449 case DEC_ROUND_FLOOR: { | |
450 if (!num->sign) needmax=1; /* Infinity iff negative */ | |
451 break;} /* r-f */ | |
452 default: break; /* Infinity in all other cases */ | |
453 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
454 if (!needmax) { /* easy .. set Infinity */ |
0 | 455 num->exponent=DECFLOAT_Inf; |
456 *umsd=0; /* be clean: coefficient to 0 */ | |
457 ulsd=umsd; /* .. */ | |
458 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
459 else { /* return Nmax */ |
0 | 460 umsd=allnines; /* use constant array */ |
461 ulsd=allnines+DECPMAX-1; | |
462 num->exponent=DECEMAX-(DECPMAX-1); | |
463 } | |
464 } | |
465 else { /* no overflow but non-zero and may have to fold-down */ | |
466 Int shift=num->exponent-(DECEMAX-(DECPMAX-1)); | |
467 if (shift>0) { /* fold-down needed */ | |
468 /* fold down needed; must copy to buffer in order to pad */ | |
469 /* with zeros safely; fortunately this is not the worst case */ | |
470 /* path because cannot have had a round */ | |
471 uByte buffer[ROUNDUP(DECPMAX+3, 4)]; /* [+3 allows uInt padding] */ | |
472 uByte *s=umsd; /* source */ | |
473 uByte *t=buffer; /* safe target */ | |
474 uByte *tlsd=buffer+(ulsd-umsd)+shift; /* target LSD */ | |
475 /* printf("folddown shift=%ld\n", (LI)shift); */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
476 for (; s<=ulsd; s+=4, t+=4) UBFROMUI(t, UBTOUI(s)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
477 for (t=tlsd-shift+1; t<=tlsd; t+=4) UBFROMUI(t, 0); /* pad 0s */ |
0 | 478 num->exponent-=shift; |
479 umsd=buffer; | |
480 ulsd=tlsd; | |
481 } | |
482 } /* fold-down? */ | |
483 length=ulsd-umsd+1; /* recalculate length */ | |
484 } /* high-end edge case */ | |
485 } /* finite number */ | |
486 | |
487 /*------------------------------------------------------------------*/ | |
488 /* At this point the result will properly fit the decFloat */ | |
489 /* encoding, and it can be encoded with no possibility of error */ | |
490 /*------------------------------------------------------------------*/ | |
491 /* Following code does not alter coefficient (could be allnines array) */ | |
492 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
493 /* fast path possible when DECPMAX digits */ |
0 | 494 if (length==DECPMAX) { |
495 return decFloatFromBCD(df, num->exponent, umsd, num->sign); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
496 } /* full-length */ |
0 | 497 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
498 /* slower path when not a full-length number; must care about length */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
499 /* [coefficient length here will be < DECPMAX] */ |
0 | 500 if (!NUMISSPECIAL(num)) { /* is still finite */ |
501 /* encode the combination field and exponent continuation */ | |
502 uInt uexp=(uInt)(num->exponent+DECBIAS); /* biased exponent */ | |
503 uInt code=(uexp>>DECECONL)<<4; /* top two bits of exp */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
504 /* [msd==0] */ |
0 | 505 /* look up the combination field and make high word */ |
506 encode=DECCOMBFROM[code]; /* indexed by (0-2)*16+msd */ | |
507 encode|=(uexp<<(32-6-DECECONL)) & 0x03ffffff; /* exponent continuation */ | |
508 } | |
509 else encode=num->exponent; /* special [already in word] */ | |
510 encode|=num->sign; /* add sign */ | |
511 | |
512 /* private macro to extract a declet, n (where 0<=n<DECLETS and 0 */ | |
513 /* refers to the declet from the least significant three digits) */ | |
514 /* and put the corresponding DPD code into dpd. Access to umsd and */ | |
515 /* ulsd (pointers to the most and least significant digit of the */ | |
516 /* variable-length coefficient) is assumed, along with use of a */ | |
517 /* working pointer, uInt *ub. */ | |
518 /* As not full-length then chances are there are many leading zeros */ | |
519 /* [and there may be a partial triad] */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
520 #define getDPDt(dpd, n) ub=ulsd-(3*(n))-2; \ |
0 | 521 if (ub<umsd-2) dpd=0; \ |
522 else if (ub>=umsd) dpd=BCD2DPD[(*ub*256)+(*(ub+1)*16)+*(ub+2)]; \ | |
523 else {dpd=*(ub+2); if (ub+1==umsd) dpd+=*(ub+1)*16; dpd=BCD2DPD[dpd];} | |
524 | |
525 /* place the declets in the encoding words and copy to result (df), */ | |
526 /* according to endianness; in all cases complete the sign word */ | |
527 /* first */ | |
528 #if DECPMAX==7 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
529 getDPDt(dpd, 1); |
0 | 530 encode|=dpd<<10; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
531 getDPDt(dpd, 0); |
0 | 532 encode|=dpd; |
533 DFWORD(df, 0)=encode; /* just the one word */ | |
534 | |
535 #elif DECPMAX==16 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
536 getDPDt(dpd, 4); encode|=dpd<<8; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
537 getDPDt(dpd, 3); encode|=dpd>>2; |
0 | 538 DFWORD(df, 0)=encode; |
539 encode=dpd<<30; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
540 getDPDt(dpd, 2); encode|=dpd<<20; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
541 getDPDt(dpd, 1); encode|=dpd<<10; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
542 getDPDt(dpd, 0); encode|=dpd; |
0 | 543 DFWORD(df, 1)=encode; |
544 | |
545 #elif DECPMAX==34 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
546 getDPDt(dpd,10); encode|=dpd<<4; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
547 getDPDt(dpd, 9); encode|=dpd>>6; |
0 | 548 DFWORD(df, 0)=encode; |
549 | |
550 encode=dpd<<26; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
551 getDPDt(dpd, 8); encode|=dpd<<16; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
552 getDPDt(dpd, 7); encode|=dpd<<6; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
553 getDPDt(dpd, 6); encode|=dpd>>4; |
0 | 554 DFWORD(df, 1)=encode; |
555 | |
556 encode=dpd<<28; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
557 getDPDt(dpd, 5); encode|=dpd<<18; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
558 getDPDt(dpd, 4); encode|=dpd<<8; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
559 getDPDt(dpd, 3); encode|=dpd>>2; |
0 | 560 DFWORD(df, 2)=encode; |
561 | |
562 encode=dpd<<30; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
563 getDPDt(dpd, 2); encode|=dpd<<20; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
564 getDPDt(dpd, 1); encode|=dpd<<10; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
565 getDPDt(dpd, 0); encode|=dpd; |
0 | 566 DFWORD(df, 3)=encode; |
567 #endif | |
568 | |
569 /* printf("Status: %08lx\n", (LI)set->status); */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
570 /* decFloatShow(df, "final2"); */ |
0 | 571 return df; |
572 } /* decFinalize */ | |
573 | |
574 /* ------------------------------------------------------------------ */ | |
575 /* decFloatFromBCD -- set decFloat from exponent, BCD8, and sign */ | |
576 /* */ | |
577 /* df is the target decFloat */ | |
578 /* exp is the in-range unbiased exponent, q, or a special value in */ | |
579 /* the form returned by decFloatGetExponent */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
580 /* bcdar holds DECPMAX digits to set the coefficient from, one */ |
0 | 581 /* digit in each byte (BCD8 encoding); the first (MSD) is ignored */ |
582 /* if df is a NaN; all are ignored if df is infinite. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
583 /* All bytes must be in 0-9; results are undefined otherwise. */ |
0 | 584 /* sig is DECFLOAT_Sign to set the sign bit, 0 otherwise */ |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
585 /* returns df, which will be canonical */ |
0 | 586 /* */ |
587 /* No error is possible, and no status will be set. */ | |
588 /* ------------------------------------------------------------------ */ | |
589 decFloat * decFloatFromBCD(decFloat *df, Int exp, const uByte *bcdar, | |
590 Int sig) { | |
591 uInt encode, dpd; /* work */ | |
592 const uByte *ub; /* .. */ | |
593 | |
594 if (EXPISSPECIAL(exp)) encode=exp|sig;/* specials already encoded */ | |
595 else { /* is finite */ | |
596 /* encode the combination field and exponent continuation */ | |
597 uInt uexp=(uInt)(exp+DECBIAS); /* biased exponent */ | |
598 uInt code=(uexp>>DECECONL)<<4; /* top two bits of exp */ | |
599 code+=bcdar[0]; /* add msd */ | |
600 /* look up the combination field and make high word */ | |
601 encode=DECCOMBFROM[code]|sig; /* indexed by (0-2)*16+msd */ | |
602 encode|=(uexp<<(32-6-DECECONL)) & 0x03ffffff; /* exponent continuation */ | |
603 } | |
604 | |
605 /* private macro to extract a declet, n (where 0<=n<DECLETS and 0 */ | |
606 /* refers to the declet from the least significant three digits) */ | |
607 /* and put the corresponding DPD code into dpd. */ | |
608 /* Use of a working pointer, uInt *ub, is assumed. */ | |
609 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
610 #define getDPDb(dpd, n) ub=bcdar+DECPMAX-1-(3*(n))-2; \ |
0 | 611 dpd=BCD2DPD[(*ub*256)+(*(ub+1)*16)+*(ub+2)]; |
612 | |
613 /* place the declets in the encoding words and copy to result (df), */ | |
614 /* according to endianness; in all cases complete the sign word */ | |
615 /* first */ | |
616 #if DECPMAX==7 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
617 getDPDb(dpd, 1); |
0 | 618 encode|=dpd<<10; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
619 getDPDb(dpd, 0); |
0 | 620 encode|=dpd; |
621 DFWORD(df, 0)=encode; /* just the one word */ | |
622 | |
623 #elif DECPMAX==16 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
624 getDPDb(dpd, 4); encode|=dpd<<8; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
625 getDPDb(dpd, 3); encode|=dpd>>2; |
0 | 626 DFWORD(df, 0)=encode; |
627 encode=dpd<<30; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
628 getDPDb(dpd, 2); encode|=dpd<<20; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
629 getDPDb(dpd, 1); encode|=dpd<<10; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
630 getDPDb(dpd, 0); encode|=dpd; |
0 | 631 DFWORD(df, 1)=encode; |
632 | |
633 #elif DECPMAX==34 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
634 getDPDb(dpd,10); encode|=dpd<<4; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
635 getDPDb(dpd, 9); encode|=dpd>>6; |
0 | 636 DFWORD(df, 0)=encode; |
637 | |
638 encode=dpd<<26; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
639 getDPDb(dpd, 8); encode|=dpd<<16; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
640 getDPDb(dpd, 7); encode|=dpd<<6; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
641 getDPDb(dpd, 6); encode|=dpd>>4; |
0 | 642 DFWORD(df, 1)=encode; |
643 | |
644 encode=dpd<<28; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
645 getDPDb(dpd, 5); encode|=dpd<<18; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
646 getDPDb(dpd, 4); encode|=dpd<<8; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
647 getDPDb(dpd, 3); encode|=dpd>>2; |
0 | 648 DFWORD(df, 2)=encode; |
649 | |
650 encode=dpd<<30; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
651 getDPDb(dpd, 2); encode|=dpd<<20; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
652 getDPDb(dpd, 1); encode|=dpd<<10; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
653 getDPDb(dpd, 0); encode|=dpd; |
0 | 654 DFWORD(df, 3)=encode; |
655 #endif | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
656 /* decFloatShow(df, "fromB"); */ |
0 | 657 return df; |
658 } /* decFloatFromBCD */ | |
659 | |
660 /* ------------------------------------------------------------------ */ | |
661 /* decFloatFromPacked -- set decFloat from exponent and packed BCD */ | |
662 /* */ | |
663 /* df is the target decFloat */ | |
664 /* exp is the in-range unbiased exponent, q, or a special value in */ | |
665 /* the form returned by decFloatGetExponent */ | |
666 /* packed holds DECPMAX packed decimal digits plus a sign nibble */ | |
667 /* (all 6 codes are OK); the first (MSD) is ignored if df is a NaN */ | |
668 /* and all except sign are ignored if df is infinite. For DOUBLE */ | |
669 /* and QUAD the first (pad) nibble is also ignored in all cases. */ | |
670 /* All coefficient nibbles must be in 0-9 and sign in A-F; results */ | |
671 /* are undefined otherwise. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
672 /* returns df, which will be canonical */ |
0 | 673 /* */ |
674 /* No error is possible, and no status will be set. */ | |
675 /* ------------------------------------------------------------------ */ | |
676 decFloat * decFloatFromPacked(decFloat *df, Int exp, const uByte *packed) { | |
677 uByte bcdar[DECPMAX+2]; /* work [+1 for pad, +1 for sign] */ | |
678 const uByte *ip; /* .. */ | |
679 uByte *op; /* .. */ | |
680 Int sig=0; /* sign */ | |
681 | |
682 /* expand coefficient and sign to BCDAR */ | |
683 #if SINGLE | |
684 op=bcdar+1; /* no pad digit */ | |
685 #else | |
686 op=bcdar; /* first (pad) digit ignored */ | |
687 #endif | |
688 for (ip=packed; ip<packed+((DECPMAX+2)/2); ip++) { | |
689 *op++=*ip>>4; | |
690 *op++=(uByte)(*ip&0x0f); /* [final nibble is sign] */ | |
691 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
692 op--; /* -> sign byte */ |
0 | 693 if (*op==DECPMINUS || *op==DECPMINUSALT) sig=DECFLOAT_Sign; |
694 | |
695 if (EXPISSPECIAL(exp)) { /* Infinity or NaN */ | |
696 if (!EXPISINF(exp)) bcdar[1]=0; /* a NaN: ignore MSD */ | |
697 else memset(bcdar+1, 0, DECPMAX); /* Infinite: coefficient to 0 */ | |
698 } | |
699 return decFloatFromBCD(df, exp, bcdar+1, sig); | |
700 } /* decFloatFromPacked */ | |
701 | |
702 /* ------------------------------------------------------------------ */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
703 /* decFloatFromPackedChecked -- set from exponent and packed; checked */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
704 /* */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
705 /* df is the target decFloat */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
706 /* exp is the in-range unbiased exponent, q, or a special value in */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
707 /* the form returned by decFloatGetExponent */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
708 /* packed holds DECPMAX packed decimal digits plus a sign nibble */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
709 /* (all 6 codes are OK); the first (MSD) must be 0 if df is a NaN */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
710 /* and all digits must be 0 if df is infinite. For DOUBLE and */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
711 /* QUAD the first (pad) nibble must be 0. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
712 /* All coefficient nibbles must be in 0-9 and sign in A-F. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
713 /* returns df, which will be canonical or NULL if any of the */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
714 /* requirements are not met (if this case df is unchanged); that */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
715 /* is, the input data must be as returned by decFloatToPacked, */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
716 /* except that all six sign codes are acccepted. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
717 /* */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
718 /* No status will be set. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
719 /* ------------------------------------------------------------------ */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
720 decFloat * decFloatFromPackedChecked(decFloat *df, Int exp, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
721 const uByte *packed) { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
722 uByte bcdar[DECPMAX+2]; /* work [+1 for pad, +1 for sign] */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
723 const uByte *ip; /* .. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
724 uByte *op; /* .. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
725 Int sig=0; /* sign */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
726 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
727 /* expand coefficient and sign to BCDAR */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
728 #if SINGLE |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
729 op=bcdar+1; /* no pad digit */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
730 #else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
731 op=bcdar; /* first (pad) digit here */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
732 #endif |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
733 for (ip=packed; ip<packed+((DECPMAX+2)/2); ip++) { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
734 *op=*ip>>4; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
735 if (*op>9) return NULL; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
736 op++; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
737 *op=(uByte)(*ip&0x0f); /* [final nibble is sign] */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
738 if (*op>9 && ip<packed+((DECPMAX+2)/2)-1) return NULL; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
739 op++; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
740 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
741 op--; /* -> sign byte */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
742 if (*op<=9) return NULL; /* bad sign */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
743 if (*op==DECPMINUS || *op==DECPMINUSALT) sig=DECFLOAT_Sign; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
744 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
745 #if !SINGLE |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
746 if (bcdar[0]!=0) return NULL; /* bad pad nibble */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
747 #endif |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
748 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
749 if (EXPISNAN(exp)) { /* a NaN */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
750 if (bcdar[1]!=0) return NULL; /* bad msd */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
751 } /* NaN */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
752 else if (EXPISINF(exp)) { /* is infinite */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
753 Int i; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
754 for (i=0; i<DECPMAX; i++) { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
755 if (bcdar[i+1]!=0) return NULL; /* should be all zeros */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
756 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
757 } /* infinity */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
758 else { /* finite */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
759 /* check the exponent is in range */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
760 if (exp>DECEMAX-DECPMAX+1) return NULL; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
761 if (exp<DECEMIN-DECPMAX+1) return NULL; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
762 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
763 return decFloatFromBCD(df, exp, bcdar+1, sig); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
764 } /* decFloatFromPacked */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
765 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
766 /* ------------------------------------------------------------------ */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
767 /* decFloatFromString -- conversion from numeric string */ |
0 | 768 /* */ |
769 /* result is the decFloat format number which gets the result of */ | |
770 /* the conversion */ | |
771 /* *string is the character string which should contain a valid */ | |
772 /* number (which may be a special value), \0-terminated */ | |
773 /* If there are too many significant digits in the */ | |
774 /* coefficient it will be rounded. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
775 /* set is the context */ |
0 | 776 /* returns result */ |
777 /* */ | |
778 /* The length of the coefficient and the size of the exponent are */ | |
779 /* checked by this routine, so the correct error (Underflow or */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
780 /* Overflow) can be reported or rounding applied, as necessary. */ |
0 | 781 /* */ |
782 /* There is no limit to the coefficient length for finite inputs; */ | |
783 /* NaN payloads must be integers with no more than DECPMAX-1 digits. */ | |
784 /* Exponents may have up to nine significant digits. */ | |
785 /* */ | |
786 /* If bad syntax is detected, the result will be a quiet NaN. */ | |
787 /* ------------------------------------------------------------------ */ | |
788 decFloat * decFloatFromString(decFloat *result, const char *string, | |
789 decContext *set) { | |
790 Int digits; /* count of digits in coefficient */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
791 const char *dotchar=NULL; /* where dot was found [NULL if none] */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
792 const char *cfirst=string; /* -> first character of decimal part */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
793 const char *c; /* work */ |
0 | 794 uByte *ub; /* .. */ |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
795 uInt uiwork; /* for macros */ |
0 | 796 bcdnum num; /* collects data for finishing */ |
797 uInt error=DEC_Conversion_syntax; /* assume the worst */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
798 uByte buffer[ROUNDUP(DECSTRING+11, 8)]; /* room for most coefficents, */ |
0 | 799 /* some common rounding, +3, & pad */ |
800 #if DECTRACE | |
801 /* printf("FromString %s ...\n", string); */ | |
802 #endif | |
803 | |
804 for(;;) { /* once-only 'loop' */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
805 num.sign=0; /* assume non-negative */ |
0 | 806 num.msd=buffer; /* MSD is here always */ |
807 | |
808 /* detect and validate the coefficient, including any leading, */ | |
809 /* trailing, or embedded '.' */ | |
810 /* [could test four-at-a-time here (saving 10% for decQuads), */ | |
811 /* but that risks storage violation because the position of the */ | |
812 /* terminator is unknown] */ | |
813 for (c=string;; c++) { /* -> input character */ | |
814 if (((unsigned)(*c-'0'))<=9) continue; /* '0' through '9' is good */ | |
815 if (*c=='\0') break; /* most common non-digit */ | |
816 if (*c=='.') { | |
817 if (dotchar!=NULL) break; /* not first '.' */ | |
818 dotchar=c; /* record offset into decimal part */ | |
819 continue;} | |
820 if (c==string) { /* first in string... */ | |
821 if (*c=='-') { /* valid - sign */ | |
822 cfirst++; | |
823 num.sign=DECFLOAT_Sign; | |
824 continue;} | |
825 if (*c=='+') { /* valid + sign */ | |
826 cfirst++; | |
827 continue;} | |
828 } | |
829 /* *c is not a digit, terminator, or a valid +, -, or '.' */ | |
830 break; | |
831 } /* c loop */ | |
832 | |
833 digits=(uInt)(c-cfirst); /* digits (+1 if a dot) */ | |
834 | |
835 if (digits>0) { /* had digits and/or dot */ | |
836 const char *clast=c-1; /* note last coefficient char position */ | |
837 Int exp=0; /* exponent accumulator */ | |
838 if (*c!='\0') { /* something follows the coefficient */ | |
839 uInt edig; /* unsigned work */ | |
840 /* had some digits and more to come; expect E[+|-]nnn now */ | |
841 const char *firstexp; /* exponent first non-zero */ | |
842 if (*c!='E' && *c!='e') break; | |
843 c++; /* to (optional) sign */ | |
844 if (*c=='-' || *c=='+') c++; /* step over sign (c=clast+2) */ | |
845 if (*c=='\0') break; /* no digits! (e.g., '1.2E') */ | |
846 for (; *c=='0';) c++; /* skip leading zeros [even last] */ | |
847 firstexp=c; /* remember start [maybe '\0'] */ | |
848 /* gather exponent digits */ | |
849 edig=(uInt)*c-(uInt)'0'; | |
850 if (edig<=9) { /* [check not bad or terminator] */ | |
851 exp+=edig; /* avoid initial X10 */ | |
852 c++; | |
853 for (;; c++) { | |
854 edig=(uInt)*c-(uInt)'0'; | |
855 if (edig>9) break; | |
856 exp=exp*10+edig; | |
857 } | |
858 } | |
859 /* if not now on the '\0', *c must not be a digit */ | |
860 if (*c!='\0') break; | |
861 | |
862 /* (this next test must be after the syntax checks) */ | |
863 /* if definitely more than the possible digits for format then */ | |
864 /* the exponent may have wrapped, so simply set it to a certain */ | |
865 /* over/underflow value */ | |
866 if (c>firstexp+DECEMAXD) exp=DECEMAX*2; | |
867 if (*(clast+2)=='-') exp=-exp; /* was negative */ | |
868 } /* digits>0 */ | |
869 | |
870 if (dotchar!=NULL) { /* had a '.' */ | |
871 digits--; /* remove from digits count */ | |
872 if (digits==0) break; /* was dot alone: bad syntax */ | |
873 exp-=(Int)(clast-dotchar); /* adjust exponent */ | |
874 /* [the '.' can now be ignored] */ | |
875 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
876 num.exponent=exp; /* exponent is good; store it */ |
0 | 877 |
878 /* Here when whole string has been inspected and syntax is good */ | |
879 /* cfirst->first digit or dot, clast->last digit or dot */ | |
880 error=0; /* no error possible now */ | |
881 | |
882 /* if the number of digits in the coefficient will fit in buffer */ | |
883 /* then it can simply be converted to bcd8 and copied -- decFinalize */ | |
884 /* will take care of leading zeros and rounding; the buffer is big */ | |
885 /* enough for all canonical coefficients, including 0.00000nn... */ | |
886 ub=buffer; | |
887 if (digits<=(Int)(sizeof(buffer)-3)) { /* [-3 allows by-4s copy] */ | |
888 c=cfirst; | |
889 if (dotchar!=NULL) { /* a dot to worry about */ | |
890 if (*(c+1)=='.') { /* common canonical case */ | |
891 *ub++=(uByte)(*c-'0'); /* copy leading digit */ | |
892 c+=2; /* prepare to handle rest */ | |
893 } | |
894 else for (; c<=clast;) { /* '.' could be anywhere */ | |
895 /* as usual, go by fours when safe; NB it has been asserted */ | |
896 /* that a '.' does not have the same mask as a digit */ | |
897 if (c<=clast-3 /* safe for four */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
898 && (UBTOUI(c)&0xf0f0f0f0)==CHARMASK) { /* test four */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
899 UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f); /* to BCD8 */ |
0 | 900 ub+=4; |
901 c+=4; | |
902 continue; | |
903 } | |
904 if (*c=='.') { /* found the dot */ | |
905 c++; /* step over it .. */ | |
906 break; /* .. and handle the rest */ | |
907 } | |
908 *ub++=(uByte)(*c++-'0'); | |
909 } | |
910 } /* had dot */ | |
911 /* Now no dot; do this by fours (where safe) */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
912 for (; c<=clast-3; c+=4, ub+=4) UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f); |
0 | 913 for (; c<=clast; c++, ub++) *ub=(uByte)(*c-'0'); |
914 num.lsd=buffer+digits-1; /* record new LSD */ | |
915 } /* fits */ | |
916 | |
917 else { /* too long for buffer */ | |
918 /* [This is a rare and unusual case; arbitrary-length input] */ | |
919 /* strip leading zeros [but leave final 0 if all 0's] */ | |
920 if (*cfirst=='.') cfirst++; /* step past dot at start */ | |
921 if (*cfirst=='0') { /* [cfirst always -> digit] */ | |
922 for (; cfirst<clast; cfirst++) { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
923 if (*cfirst!='0') { /* non-zero found */ |
0 | 924 if (*cfirst=='.') continue; /* [ignore] */ |
925 break; /* done */ | |
926 } | |
927 digits--; /* 0 stripped */ | |
928 } /* cfirst */ | |
929 } /* at least one leading 0 */ | |
930 | |
931 /* the coefficient is now as short as possible, but may still */ | |
932 /* be too long; copy up to Pmax+1 digits to the buffer, then */ | |
933 /* just record any non-zeros (set round-for-reround digit) */ | |
934 for (c=cfirst; c<=clast && ub<=buffer+DECPMAX; c++) { | |
935 /* (see commentary just above) */ | |
936 if (c<=clast-3 /* safe for four */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
937 && (UBTOUI(c)&0xf0f0f0f0)==CHARMASK) { /* four digits */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
938 UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f); /* to BCD8 */ |
0 | 939 ub+=4; |
940 c+=3; /* [will become 4] */ | |
941 continue; | |
942 } | |
943 if (*c=='.') continue; /* [ignore] */ | |
944 *ub++=(uByte)(*c-'0'); | |
945 } | |
946 ub--; /* -> LSD */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
947 for (; c<=clast; c++) { /* inspect remaining chars */ |
0 | 948 if (*c!='0') { /* sticky bit needed */ |
949 if (*c=='.') continue; /* [ignore] */ | |
950 *ub=DECSTICKYTAB[*ub]; /* update round-for-reround */ | |
951 break; /* no need to look at more */ | |
952 } | |
953 } | |
954 num.lsd=ub; /* record LSD */ | |
955 /* adjust exponent for dropped digits */ | |
956 num.exponent+=digits-(Int)(ub-buffer+1); | |
957 } /* too long for buffer */ | |
958 } /* digits or dot */ | |
959 | |
960 else { /* no digits or dot were found */ | |
961 if (*c=='\0') break; /* nothing to come is bad */ | |
962 /* only Infinities and NaNs are allowed, here */ | |
963 buffer[0]=0; /* default a coefficient of 0 */ | |
964 num.lsd=buffer; /* .. */ | |
965 if (decBiStr(c, "infinity", "INFINITY") | |
966 || decBiStr(c, "inf", "INF")) num.exponent=DECFLOAT_Inf; | |
967 else { /* should be a NaN */ | |
968 num.exponent=DECFLOAT_qNaN; /* assume quiet NaN */ | |
969 if (*c=='s' || *c=='S') { /* probably an sNaN */ | |
970 c++; | |
971 num.exponent=DECFLOAT_sNaN; /* assume is in fact sNaN */ | |
972 } | |
973 if (*c!='N' && *c!='n') break; /* check caseless "NaN" */ | |
974 c++; | |
975 if (*c!='a' && *c!='A') break; /* .. */ | |
976 c++; | |
977 if (*c!='N' && *c!='n') break; /* .. */ | |
978 c++; | |
979 /* now either nothing, or nnnn payload (no dots), expected */ | |
980 /* -> start of integer, and skip leading 0s [including plain 0] */ | |
981 for (cfirst=c; *cfirst=='0';) cfirst++; | |
982 if (*cfirst!='\0') { /* not empty or all-0, payload */ | |
983 /* payload found; check all valid digits and copy to buffer as bcd8 */ | |
984 ub=buffer; | |
985 for (c=cfirst;; c++, ub++) { | |
986 if ((unsigned)(*c-'0')>9) break; /* quit if not 0-9 */ | |
987 if (c-cfirst==DECPMAX-1) break; /* too many digits */ | |
988 *ub=(uByte)(*c-'0'); /* good bcd8 */ | |
989 } | |
990 if (*c!='\0') break; /* not all digits, or too many */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
991 num.lsd=ub-1; /* record new LSD */ |
0 | 992 } |
993 } /* NaN or sNaN */ | |
994 error=0; /* syntax is OK */ | |
995 break; /* done with specials */ | |
996 } /* digits=0 (special expected) */ | |
997 break; | |
998 } /* [for(;;) break] */ | |
999 | |
1000 /* decShowNum(&num, "fromStr"); */ | |
1001 | |
1002 if (error!=0) { | |
1003 set->status|=error; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1004 num.exponent=DECFLOAT_qNaN; /* set up quiet NaN */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1005 num.sign=0; /* .. with 0 sign */ |
0 | 1006 buffer[0]=0; /* .. and coefficient */ |
1007 num.lsd=buffer; /* .. */ | |
1008 /* decShowNum(&num, "oops"); */ | |
1009 } | |
1010 | |
1011 /* decShowNum(&num, "dffs"); */ | |
1012 decFinalize(result, &num, set); /* round, check, and lay out */ | |
1013 /* decFloatShow(result, "fromString"); */ | |
1014 return result; | |
1015 } /* decFloatFromString */ | |
1016 | |
1017 /* ------------------------------------------------------------------ */ | |
1018 /* decFloatFromWider -- conversion from next-wider format */ | |
1019 /* */ | |
1020 /* result is the decFloat format number which gets the result of */ | |
1021 /* the conversion */ | |
1022 /* wider is the decFloatWider format number which will be narrowed */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1023 /* set is the context */ |
0 | 1024 /* returns result */ |
1025 /* */ | |
1026 /* Narrowing can cause rounding, overflow, etc., but not Invalid */ | |
1027 /* operation (sNaNs are copied and do not signal). */ | |
1028 /* ------------------------------------------------------------------ */ | |
1029 /* narrow-to is not possible for decQuad format numbers; simply omit */ | |
1030 #if !QUAD | |
1031 decFloat * decFloatFromWider(decFloat *result, const decFloatWider *wider, | |
1032 decContext *set) { | |
1033 bcdnum num; /* collects data for finishing */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1034 uByte bcdar[DECWPMAX]; /* room for wider coefficient */ |
0 | 1035 uInt widerhi=DFWWORD(wider, 0); /* top word */ |
1036 Int exp; | |
1037 | |
1038 GETWCOEFF(wider, bcdar); | |
1039 | |
1040 num.msd=bcdar; /* MSD is here always */ | |
1041 num.lsd=bcdar+DECWPMAX-1; /* LSD is here always */ | |
1042 num.sign=widerhi&0x80000000; /* extract sign [DECFLOAT_Sign=Neg] */ | |
1043 | |
1044 /* decode the wider combination field to exponent */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1045 exp=DECCOMBWEXP[widerhi>>26]; /* decode from wider combination field */ |
0 | 1046 /* if it is a special there's nothing to do unless sNaN; if it's */ |
1047 /* finite then add the (wider) exponent continuation and unbias */ | |
1048 if (EXPISSPECIAL(exp)) exp=widerhi&0x7e000000; /* include sNaN selector */ | |
1049 else exp+=GETWECON(wider)-DECWBIAS; | |
1050 num.exponent=exp; | |
1051 | |
1052 /* decShowNum(&num, "dffw"); */ | |
1053 return decFinalize(result, &num, set);/* round, check, and lay out */ | |
1054 } /* decFloatFromWider */ | |
1055 #endif | |
1056 | |
1057 /* ------------------------------------------------------------------ */ | |
1058 /* decFloatGetCoefficient -- get coefficient as BCD8 */ | |
1059 /* */ | |
1060 /* df is the decFloat from which to extract the coefficient */ | |
1061 /* bcdar is where DECPMAX bytes will be written, one BCD digit in */ | |
1062 /* each byte (BCD8 encoding); if df is a NaN the first byte will */ | |
1063 /* be zero, and if it is infinite they will all be zero */ | |
1064 /* returns the sign of the coefficient (DECFLOAT_Sign if negative, */ | |
1065 /* 0 otherwise) */ | |
1066 /* */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1067 /* No error is possible, and no status will be set. If df is a */ |
0 | 1068 /* special value the array is set to zeros (for Infinity) or to the */ |
1069 /* payload of a qNaN or sNaN. */ | |
1070 /* ------------------------------------------------------------------ */ | |
1071 Int decFloatGetCoefficient(const decFloat *df, uByte *bcdar) { | |
1072 if (DFISINF(df)) memset(bcdar, 0, DECPMAX); | |
1073 else { | |
1074 GETCOEFF(df, bcdar); /* use macro */ | |
1075 if (DFISNAN(df)) bcdar[0]=0; /* MSD needs correcting */ | |
1076 } | |
1077 return DFISSIGNED(df); | |
1078 } /* decFloatGetCoefficient */ | |
1079 | |
1080 /* ------------------------------------------------------------------ */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1081 /* decFloatGetExponent -- get unbiased exponent */ |
0 | 1082 /* */ |
1083 /* df is the decFloat from which to extract the exponent */ | |
1084 /* returns the exponent, q. */ | |
1085 /* */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1086 /* No error is possible, and no status will be set. If df is a */ |
0 | 1087 /* special value the first seven bits of the decFloat are returned, */ |
1088 /* left adjusted and with the first (sign) bit set to 0 (followed by */ | |
1089 /* 25 0 bits). e.g., -sNaN would return 0x7e000000 (DECFLOAT_sNaN). */ | |
1090 /* ------------------------------------------------------------------ */ | |
1091 Int decFloatGetExponent(const decFloat *df) { | |
1092 if (DFISSPECIAL(df)) return DFWORD(df, 0)&0x7e000000; | |
1093 return GETEXPUN(df); | |
1094 } /* decFloatGetExponent */ | |
1095 | |
1096 /* ------------------------------------------------------------------ */ | |
1097 /* decFloatSetCoefficient -- set coefficient from BCD8 */ | |
1098 /* */ | |
1099 /* df is the target decFloat (and source of exponent/special value) */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1100 /* bcdar holds DECPMAX digits to set the coefficient from, one */ |
0 | 1101 /* digit in each byte (BCD8 encoding); the first (MSD) is ignored */ |
1102 /* if df is a NaN; all are ignored if df is infinite. */ | |
1103 /* sig is DECFLOAT_Sign to set the sign bit, 0 otherwise */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1104 /* returns df, which will be canonical */ |
0 | 1105 /* */ |
1106 /* No error is possible, and no status will be set. */ | |
1107 /* ------------------------------------------------------------------ */ | |
1108 decFloat * decFloatSetCoefficient(decFloat *df, const uByte *bcdar, | |
1109 Int sig) { | |
1110 uInt exp; /* for exponent */ | |
1111 uByte bcdzero[DECPMAX]; /* for infinities */ | |
1112 | |
1113 /* Exponent/special code is extracted from df */ | |
1114 if (DFISSPECIAL(df)) { | |
1115 exp=DFWORD(df, 0)&0x7e000000; | |
1116 if (DFISINF(df)) { | |
1117 memset(bcdzero, 0, DECPMAX); | |
1118 return decFloatFromBCD(df, exp, bcdzero, sig); | |
1119 } | |
1120 } | |
1121 else exp=GETEXPUN(df); | |
1122 return decFloatFromBCD(df, exp, bcdar, sig); | |
1123 } /* decFloatSetCoefficient */ | |
1124 | |
1125 /* ------------------------------------------------------------------ */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1126 /* decFloatSetExponent -- set exponent or special value */ |
0 | 1127 /* */ |
1128 /* df is the target decFloat (and source of coefficient/payload) */ | |
1129 /* set is the context for reporting status */ | |
1130 /* exp is the unbiased exponent, q, or a special value in the form */ | |
1131 /* returned by decFloatGetExponent */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1132 /* returns df, which will be canonical */ |
0 | 1133 /* */ |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1134 /* No error is possible, but Overflow or Underflow might occur. */ |
0 | 1135 /* ------------------------------------------------------------------ */ |
1136 decFloat * decFloatSetExponent(decFloat *df, decContext *set, Int exp) { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1137 uByte bcdcopy[DECPMAX]; /* for coefficient */ |
0 | 1138 bcdnum num; /* work */ |
1139 num.exponent=exp; | |
1140 num.sign=decFloatGetCoefficient(df, bcdcopy); /* extract coefficient */ | |
1141 if (DFISSPECIAL(df)) { /* MSD or more needs correcting */ | |
1142 if (DFISINF(df)) memset(bcdcopy, 0, DECPMAX); | |
1143 bcdcopy[0]=0; | |
1144 } | |
1145 num.msd=bcdcopy; | |
1146 num.lsd=bcdcopy+DECPMAX-1; | |
1147 return decFinalize(df, &num, set); | |
1148 } /* decFloatSetExponent */ | |
1149 | |
1150 /* ------------------------------------------------------------------ */ | |
1151 /* decFloatRadix -- returns the base (10) */ | |
1152 /* */ | |
1153 /* df is any decFloat of this format */ | |
1154 /* ------------------------------------------------------------------ */ | |
1155 uInt decFloatRadix(const decFloat *df) { | |
1156 if (df) return 10; /* to placate compiler */ | |
1157 return 10; | |
1158 } /* decFloatRadix */ | |
1159 | |
36 | 1160 #if (DECCHECK || DECTRACE) |
0 | 1161 /* ------------------------------------------------------------------ */ |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1162 /* decFloatShow -- printf a decFloat in hexadecimal and decimal */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1163 /* df is the decFloat to show */ |
0 | 1164 /* tag is a tag string displayed with the number */ |
1165 /* */ | |
1166 /* This is a debug aid; the precise format of the string may change. */ | |
1167 /* ------------------------------------------------------------------ */ | |
1168 void decFloatShow(const decFloat *df, const char *tag) { | |
1169 char hexbuf[DECBYTES*2+DECBYTES/4+1]; /* NB blank after every fourth */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1170 char buff[DECSTRING]; /* for value in decimal */ |
0 | 1171 Int i, j=0; |
1172 | |
1173 for (i=0; i<DECBYTES; i++) { | |
1174 #if DECLITEND | |
1175 sprintf(&hexbuf[j], "%02x", df->bytes[DECBYTES-1-i]); | |
1176 #else | |
1177 sprintf(&hexbuf[j], "%02x", df->bytes[i]); | |
1178 #endif | |
1179 j+=2; | |
1180 /* the next line adds blank (and terminator) after final pair, too */ | |
1181 if ((i+1)%4==0) {strcpy(&hexbuf[j], " "); j++;} | |
1182 } | |
1183 decFloatToString(df, buff); | |
1184 printf(">%s> %s [big-endian] %s\n", tag, hexbuf, buff); | |
1185 return; | |
1186 } /* decFloatShow */ | |
36 | 1187 #endif |
0 | 1188 |
1189 /* ------------------------------------------------------------------ */ | |
1190 /* decFloatToBCD -- get sign, exponent, and BCD8 from a decFloat */ | |
1191 /* */ | |
1192 /* df is the source decFloat */ | |
1193 /* exp will be set to the unbiased exponent, q, or to a special */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1194 /* value in the form returned by decFloatGetExponent */ |
0 | 1195 /* bcdar is where DECPMAX bytes will be written, one BCD digit in */ |
1196 /* each byte (BCD8 encoding); if df is a NaN the first byte will */ | |
1197 /* be zero, and if it is infinite they will all be zero */ | |
1198 /* returns the sign of the coefficient (DECFLOAT_Sign if negative, */ | |
1199 /* 0 otherwise) */ | |
1200 /* */ | |
1201 /* No error is possible, and no status will be set. */ | |
1202 /* ------------------------------------------------------------------ */ | |
1203 Int decFloatToBCD(const decFloat *df, Int *exp, uByte *bcdar) { | |
1204 if (DFISINF(df)) { | |
1205 memset(bcdar, 0, DECPMAX); | |
1206 *exp=DFWORD(df, 0)&0x7e000000; | |
1207 } | |
1208 else { | |
1209 GETCOEFF(df, bcdar); /* use macro */ | |
1210 if (DFISNAN(df)) { | |
1211 bcdar[0]=0; /* MSD needs correcting */ | |
1212 *exp=DFWORD(df, 0)&0x7e000000; | |
1213 } | |
1214 else { /* finite */ | |
1215 *exp=GETEXPUN(df); | |
1216 } | |
1217 } | |
1218 return DFISSIGNED(df); | |
1219 } /* decFloatToBCD */ | |
1220 | |
1221 /* ------------------------------------------------------------------ */ | |
1222 /* decFloatToEngString -- conversion to numeric string, engineering */ | |
1223 /* */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1224 /* df is the decFloat format number to convert */ |
0 | 1225 /* string is the string where the result will be laid out */ |
1226 /* */ | |
1227 /* string must be at least DECPMAX+9 characters (the worst case is */ | |
1228 /* "-0.00000nnn...nnn\0", which is as long as the exponent form when */ | |
1229 /* DECEMAXD<=4); this condition is asserted above */ | |
1230 /* */ | |
1231 /* No error is possible, and no status will be set */ | |
1232 /* ------------------------------------------------------------------ */ | |
1233 char * decFloatToEngString(const decFloat *df, char *string){ | |
1234 uInt msd; /* coefficient MSD */ | |
1235 Int exp; /* exponent top two bits or full */ | |
1236 uInt comb; /* combination field */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1237 char *cstart; /* coefficient start */ |
0 | 1238 char *c; /* output pointer in string */ |
1239 char *s, *t; /* .. (source, target) */ | |
1240 Int pre, e; /* work */ | |
1241 const uByte *u; /* .. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1242 uInt uiwork; /* for macros [one compiler needs */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1243 /* volatile here to avoid bug, but */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1244 /* that doubles execution time] */ |
0 | 1245 |
1246 /* Source words; macro handles endianness */ | |
1247 uInt sourhi=DFWORD(df, 0); /* word with sign */ | |
1248 #if DECPMAX==16 | |
1249 uInt sourlo=DFWORD(df, 1); | |
1250 #elif DECPMAX==34 | |
1251 uInt sourmh=DFWORD(df, 1); | |
1252 uInt sourml=DFWORD(df, 2); | |
1253 uInt sourlo=DFWORD(df, 3); | |
1254 #endif | |
1255 | |
1256 c=string; /* where result will go */ | |
1257 if (((Int)sourhi)<0) *c++='-'; /* handle sign */ | |
1258 comb=sourhi>>26; /* sign+combination field */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1259 msd=DECCOMBMSD[comb]; /* decode the combination field */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1260 exp=DECCOMBEXP[comb]; /* .. */ |
0 | 1261 |
1262 if (EXPISSPECIAL(exp)) { /* special */ | |
1263 if (exp==DECFLOAT_Inf) { /* infinity */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1264 strcpy(c, "Inf"); |
0 | 1265 strcpy(c+3, "inity"); |
1266 return string; /* easy */ | |
1267 } | |
1268 if (sourhi&0x02000000) *c++='s'; /* sNaN */ | |
1269 strcpy(c, "NaN"); /* complete word */ | |
1270 c+=3; /* step past */ | |
1271 /* quick exit if the payload is zero */ | |
1272 #if DECPMAX==7 | |
1273 if ((sourhi&0x000fffff)==0) return string; | |
1274 #elif DECPMAX==16 | |
1275 if (sourlo==0 && (sourhi&0x0003ffff)==0) return string; | |
1276 #elif DECPMAX==34 | |
1277 if (sourlo==0 && sourml==0 && sourmh==0 | |
1278 && (sourhi&0x00003fff)==0) return string; | |
1279 #endif | |
1280 /* otherwise drop through to add integer; set correct exp etc. */ | |
1281 exp=0; msd=0; /* setup for following code */ | |
1282 } | |
1283 else { /* complete exponent; top two bits are in place */ | |
1284 exp+=GETECON(df)-DECBIAS; /* .. + continuation and unbias */ | |
1285 } | |
1286 | |
1287 /* convert the digits of the significand to characters */ | |
1288 cstart=c; /* save start of coefficient */ | |
1289 if (msd) *c++=(char)('0'+(char)msd); /* non-zero most significant digit */ | |
1290 | |
1291 /* Decode the declets. After extracting each declet, it is */ | |
1292 /* decoded to a 4-uByte sequence by table lookup; the four uBytes */ | |
1293 /* are the three encoded BCD8 digits followed by a 1-byte length */ | |
1294 /* (significant digits, except that 000 has length 0). This allows */ | |
1295 /* us to left-align the first declet with non-zero content, then */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1296 /* the remaining ones are full 3-char length. Fixed-length copies */ |
0 | 1297 /* are used because variable-length memcpy causes a subroutine call */ |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1298 /* in at least two compilers. (The copies are length 4 for speed */ |
0 | 1299 /* and are safe because the last item in the array is of length */ |
1300 /* three and has the length byte following.) */ | |
1301 #define dpd2char(dpdin) u=&DPD2BCD8[((dpdin)&0x3ff)*4]; \ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1302 if (c!=cstart) {UBFROMUI(c, UBTOUI(u)|CHARMASK); c+=3;} \ |
0 | 1303 else if (*(u+3)) { \ |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1304 UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); c+=*(u+3);} |
0 | 1305 |
1306 #if DECPMAX==7 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1307 dpd2char(sourhi>>10); /* declet 1 */ |
0 | 1308 dpd2char(sourhi); /* declet 2 */ |
1309 | |
1310 #elif DECPMAX==16 | |
1311 dpd2char(sourhi>>8); /* declet 1 */ | |
1312 dpd2char((sourhi<<2) | (sourlo>>30)); /* declet 2 */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1313 dpd2char(sourlo>>20); /* declet 3 */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1314 dpd2char(sourlo>>10); /* declet 4 */ |
0 | 1315 dpd2char(sourlo); /* declet 5 */ |
1316 | |
1317 #elif DECPMAX==34 | |
1318 dpd2char(sourhi>>4); /* declet 1 */ | |
1319 dpd2char((sourhi<<6) | (sourmh>>26)); /* declet 2 */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1320 dpd2char(sourmh>>16); /* declet 3 */ |
0 | 1321 dpd2char(sourmh>>6); /* declet 4 */ |
1322 dpd2char((sourmh<<4) | (sourml>>28)); /* declet 5 */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1323 dpd2char(sourml>>18); /* declet 6 */ |
0 | 1324 dpd2char(sourml>>8); /* declet 7 */ |
1325 dpd2char((sourml<<2) | (sourlo>>30)); /* declet 8 */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1326 dpd2char(sourlo>>20); /* declet 9 */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1327 dpd2char(sourlo>>10); /* declet 10 */ |
0 | 1328 dpd2char(sourlo); /* declet 11 */ |
1329 #endif | |
1330 | |
1331 if (c==cstart) *c++='0'; /* all zeros, empty -- make "0" */ | |
1332 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1333 if (exp==0) { /* integer or NaN case -- easy */ |
0 | 1334 *c='\0'; /* terminate */ |
1335 return string; | |
1336 } | |
1337 /* non-0 exponent */ | |
1338 | |
1339 e=0; /* assume no E */ | |
1340 pre=(Int)(c-cstart)+exp; /* length+exp [c->LSD+1] */ | |
1341 /* [here, pre-exp is the digits count (==1 for zero)] */ | |
1342 | |
1343 if (exp>0 || pre<-5) { /* need exponential form */ | |
1344 e=pre-1; /* calculate E value */ | |
1345 pre=1; /* assume one digit before '.' */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1346 if (e!=0) { /* engineering: may need to adjust */ |
0 | 1347 Int adj; /* adjustment */ |
1348 /* The C remainder operator is undefined for negative numbers, so */ | |
1349 /* a positive remainder calculation must be used here */ | |
1350 if (e<0) { | |
1351 adj=(-e)%3; | |
1352 if (adj!=0) adj=3-adj; | |
1353 } | |
1354 else { /* e>0 */ | |
1355 adj=e%3; | |
1356 } | |
1357 e=e-adj; | |
1358 /* if dealing with zero still produce an exponent which is a */ | |
1359 /* multiple of three, as expected, but there will only be the */ | |
1360 /* one zero before the E, still. Otherwise note the padding. */ | |
1361 if (!DFISZERO(df)) pre+=adj; | |
1362 else { /* is zero */ | |
1363 if (adj!=0) { /* 0.00Esnn needed */ | |
1364 e=e+3; | |
1365 pre=-(2-adj); | |
1366 } | |
1367 } /* zero */ | |
1368 } /* engineering adjustment */ | |
1369 } /* exponential form */ | |
1370 /* printf("e=%ld pre=%ld exp=%ld\n", (LI)e, (LI)pre, (LI)exp); */ | |
1371 | |
1372 /* modify the coefficient, adding 0s, '.', and E+nn as needed */ | |
1373 if (pre>0) { /* ddd.ddd (plain), perhaps with E */ | |
1374 /* or dd00 padding for engineering */ | |
1375 char *dotat=cstart+pre; | |
1376 if (dotat<c) { /* if embedded dot needed... */ | |
1377 /* move by fours; there must be space for junk at the end */ | |
1378 /* because there is still space for exponent */ | |
1379 s=dotat+ROUNDDOWN4(c-dotat); /* source */ | |
1380 t=s+1; /* target */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1381 /* open the gap [cannot use memcpy] */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1382 for (; s>=dotat; s-=4, t-=4) UBFROMUI(t, UBTOUI(s)); |
0 | 1383 *dotat='.'; |
1384 c++; /* length increased by one */ | |
1385 } /* need dot? */ | |
1386 else for (; c<dotat; c++) *c='0'; /* pad for engineering */ | |
1387 } /* pre>0 */ | |
1388 else { | |
1389 /* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (may have | |
1390 E, but only for 0.00E+3 kind of case -- with plenty of spare | |
1391 space in this case */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1392 pre=-pre+2; /* gap width, including "0." */ |
0 | 1393 t=cstart+ROUNDDOWN4(c-cstart)+pre; /* preferred first target point */ |
1394 /* backoff if too far to the right */ | |
1395 if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */ | |
1396 /* now shift the entire coefficient to the right, being careful not */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1397 /* to access to the left of string [cannot use memcpy] */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1398 for (s=t-pre; s>=string; s-=4, t-=4) UBFROMUI(t, UBTOUI(s)); |
0 | 1399 /* for Quads and Singles there may be a character or two left... */ |
1400 s+=3; /* where next would come from */ | |
1401 for(; s>=cstart; s--, t--) *(t+3)=*(s); | |
1402 /* now have fill 0. through 0.00000; use overlaps to avoid tests */ | |
1403 if (pre>=4) { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1404 memcpy(cstart+pre-4, "0000", 4); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1405 memcpy(cstart, "0.00", 4); |
0 | 1406 } |
1407 else { /* 2 or 3 */ | |
1408 *(cstart+pre-1)='0'; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1409 memcpy(cstart, "0.", 2); |
0 | 1410 } |
1411 c+=pre; /* to end */ | |
1412 } | |
1413 | |
1414 /* finally add the E-part, if needed; it will never be 0, and has */ | |
1415 /* a maximum length of 3 or 4 digits (asserted above) */ | |
1416 if (e!=0) { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1417 memcpy(c, "E+", 2); /* starts with E, assume + */ |
0 | 1418 c++; |
1419 if (e<0) { | |
1420 *c='-'; /* oops, need '-' */ | |
1421 e=-e; /* uInt, please */ | |
1422 } | |
1423 c++; | |
1424 /* Three-character exponents are easy; 4-character a little trickier */ | |
1425 #if DECEMAXD<=3 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1426 u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ |
0 | 1427 /* copy fixed 4 characters [is safe], starting at non-zero */ |
1428 /* and with character mask to convert BCD to char */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1429 UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); |
0 | 1430 c+=*(u+3); /* bump pointer appropriately */ |
1431 #elif DECEMAXD==4 | |
1432 if (e<1000) { /* 3 (or fewer) digits case */ | |
1433 u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1434 UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); /* [as above] */ |
0 | 1435 c+=*(u+3); /* bump pointer appropriately */ |
1436 } | |
1437 else { /* 4-digits */ | |
1438 Int thou=((e>>3)*1049)>>17; /* e/1000 */ | |
1439 Int rem=e-(1000*thou); /* e%1000 */ | |
1440 *c++=(char)('0'+(char)thou); /* the thousands digit */ | |
1441 u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1442 UBFROMUI(c, UBTOUI(u)|CHARMASK);/* copy fixed 3+1 characters [is safe] */ |
0 | 1443 c+=3; /* bump pointer, always 3 digits */ |
1444 } | |
1445 #endif | |
1446 } | |
1447 *c='\0'; /* terminate */ | |
1448 /*printf("res %s\n", string); */ | |
1449 return string; | |
1450 } /* decFloatToEngString */ | |
1451 | |
1452 /* ------------------------------------------------------------------ */ | |
1453 /* decFloatToPacked -- convert decFloat to Packed decimal + exponent */ | |
1454 /* */ | |
1455 /* df is the source decFloat */ | |
1456 /* exp will be set to the unbiased exponent, q, or to a special */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1457 /* value in the form returned by decFloatGetExponent */ |
0 | 1458 /* packed is where DECPMAX nibbles will be written with the sign as */ |
1459 /* final nibble (0x0c for +, 0x0d for -); a NaN has a first nibble */ | |
1460 /* of zero, and an infinity is all zeros. decDouble and decQuad */ | |
1461 /* have a additional leading zero nibble, leading to result */ | |
1462 /* lengths of 4, 9, and 18 bytes. */ | |
1463 /* returns the sign of the coefficient (DECFLOAT_Sign if negative, */ | |
1464 /* 0 otherwise) */ | |
1465 /* */ | |
1466 /* No error is possible, and no status will be set. */ | |
1467 /* ------------------------------------------------------------------ */ | |
1468 Int decFloatToPacked(const decFloat *df, Int *exp, uByte *packed) { | |
1469 uByte bcdar[DECPMAX+2]; /* work buffer */ | |
1470 uByte *ip=bcdar, *op=packed; /* work pointers */ | |
1471 if (DFISINF(df)) { | |
1472 memset(bcdar, 0, DECPMAX+2); | |
1473 *exp=DECFLOAT_Inf; | |
1474 } | |
1475 else { | |
1476 GETCOEFF(df, bcdar+1); /* use macro */ | |
1477 if (DFISNAN(df)) { | |
1478 bcdar[1]=0; /* MSD needs clearing */ | |
1479 *exp=DFWORD(df, 0)&0x7e000000; | |
1480 } | |
1481 else { /* finite */ | |
1482 *exp=GETEXPUN(df); | |
1483 } | |
1484 } | |
1485 /* now pack; coefficient currently at bcdar+1 */ | |
1486 #if SINGLE | |
1487 ip++; /* ignore first byte */ | |
1488 #else | |
1489 *ip=0; /* need leading zero */ | |
1490 #endif | |
1491 /* set final byte to Packed BCD sign value */ | |
1492 bcdar[DECPMAX+1]=(DFISSIGNED(df) ? DECPMINUS : DECPPLUS); | |
1493 /* pack an even number of bytes... */ | |
1494 for (; op<packed+((DECPMAX+2)/2); op++, ip+=2) { | |
1495 *op=(uByte)((*ip<<4)+*(ip+1)); | |
1496 } | |
1497 return (bcdar[DECPMAX+1]==DECPMINUS ? DECFLOAT_Sign : 0); | |
1498 } /* decFloatToPacked */ | |
1499 | |
1500 /* ------------------------------------------------------------------ */ | |
1501 /* decFloatToString -- conversion to numeric string */ | |
1502 /* */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1503 /* df is the decFloat format number to convert */ |
0 | 1504 /* string is the string where the result will be laid out */ |
1505 /* */ | |
1506 /* string must be at least DECPMAX+9 characters (the worst case is */ | |
1507 /* "-0.00000nnn...nnn\0", which is as long as the exponent form when */ | |
1508 /* DECEMAXD<=4); this condition is asserted above */ | |
1509 /* */ | |
1510 /* No error is possible, and no status will be set */ | |
1511 /* ------------------------------------------------------------------ */ | |
1512 char * decFloatToString(const decFloat *df, char *string){ | |
1513 uInt msd; /* coefficient MSD */ | |
1514 Int exp; /* exponent top two bits or full */ | |
1515 uInt comb; /* combination field */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1516 char *cstart; /* coefficient start */ |
0 | 1517 char *c; /* output pointer in string */ |
1518 char *s, *t; /* .. (source, target) */ | |
1519 Int pre, e; /* work */ | |
1520 const uByte *u; /* .. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1521 uInt uiwork; /* for macros [one compiler needs */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1522 /* volatile here to avoid bug, but */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1523 /* that doubles execution time] */ |
0 | 1524 |
1525 /* Source words; macro handles endianness */ | |
1526 uInt sourhi=DFWORD(df, 0); /* word with sign */ | |
1527 #if DECPMAX==16 | |
1528 uInt sourlo=DFWORD(df, 1); | |
1529 #elif DECPMAX==34 | |
1530 uInt sourmh=DFWORD(df, 1); | |
1531 uInt sourml=DFWORD(df, 2); | |
1532 uInt sourlo=DFWORD(df, 3); | |
1533 #endif | |
1534 | |
1535 c=string; /* where result will go */ | |
1536 if (((Int)sourhi)<0) *c++='-'; /* handle sign */ | |
1537 comb=sourhi>>26; /* sign+combination field */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1538 msd=DECCOMBMSD[comb]; /* decode the combination field */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1539 exp=DECCOMBEXP[comb]; /* .. */ |
0 | 1540 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1541 if (!EXPISSPECIAL(exp)) { /* finite */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1542 /* complete exponent; top two bits are in place */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1543 exp+=GETECON(df)-DECBIAS; /* .. + continuation and unbias */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1544 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1545 else { /* IS special */ |
0 | 1546 if (exp==DECFLOAT_Inf) { /* infinity */ |
1547 strcpy(c, "Infinity"); | |
1548 return string; /* easy */ | |
1549 } | |
1550 if (sourhi&0x02000000) *c++='s'; /* sNaN */ | |
1551 strcpy(c, "NaN"); /* complete word */ | |
1552 c+=3; /* step past */ | |
1553 /* quick exit if the payload is zero */ | |
1554 #if DECPMAX==7 | |
1555 if ((sourhi&0x000fffff)==0) return string; | |
1556 #elif DECPMAX==16 | |
1557 if (sourlo==0 && (sourhi&0x0003ffff)==0) return string; | |
1558 #elif DECPMAX==34 | |
1559 if (sourlo==0 && sourml==0 && sourmh==0 | |
1560 && (sourhi&0x00003fff)==0) return string; | |
1561 #endif | |
1562 /* otherwise drop through to add integer; set correct exp etc. */ | |
1563 exp=0; msd=0; /* setup for following code */ | |
1564 } | |
1565 | |
1566 /* convert the digits of the significand to characters */ | |
1567 cstart=c; /* save start of coefficient */ | |
1568 if (msd) *c++=(char)('0'+(char)msd); /* non-zero most significant digit */ | |
1569 | |
1570 /* Decode the declets. After extracting each declet, it is */ | |
1571 /* decoded to a 4-uByte sequence by table lookup; the four uBytes */ | |
1572 /* are the three encoded BCD8 digits followed by a 1-byte length */ | |
1573 /* (significant digits, except that 000 has length 0). This allows */ | |
1574 /* us to left-align the first declet with non-zero content, then */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1575 /* the remaining ones are full 3-char length. Fixed-length copies */ |
0 | 1576 /* are used because variable-length memcpy causes a subroutine call */ |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1577 /* in at least two compilers. (The copies are length 4 for speed */ |
0 | 1578 /* and are safe because the last item in the array is of length */ |
1579 /* three and has the length byte following.) */ | |
1580 #define dpd2char(dpdin) u=&DPD2BCD8[((dpdin)&0x3ff)*4]; \ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1581 if (c!=cstart) {UBFROMUI(c, UBTOUI(u)|CHARMASK); c+=3;} \ |
0 | 1582 else if (*(u+3)) { \ |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1583 UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); c+=*(u+3);} |
0 | 1584 |
1585 #if DECPMAX==7 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1586 dpd2char(sourhi>>10); /* declet 1 */ |
0 | 1587 dpd2char(sourhi); /* declet 2 */ |
1588 | |
1589 #elif DECPMAX==16 | |
1590 dpd2char(sourhi>>8); /* declet 1 */ | |
1591 dpd2char((sourhi<<2) | (sourlo>>30)); /* declet 2 */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1592 dpd2char(sourlo>>20); /* declet 3 */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1593 dpd2char(sourlo>>10); /* declet 4 */ |
0 | 1594 dpd2char(sourlo); /* declet 5 */ |
1595 | |
1596 #elif DECPMAX==34 | |
1597 dpd2char(sourhi>>4); /* declet 1 */ | |
1598 dpd2char((sourhi<<6) | (sourmh>>26)); /* declet 2 */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1599 dpd2char(sourmh>>16); /* declet 3 */ |
0 | 1600 dpd2char(sourmh>>6); /* declet 4 */ |
1601 dpd2char((sourmh<<4) | (sourml>>28)); /* declet 5 */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1602 dpd2char(sourml>>18); /* declet 6 */ |
0 | 1603 dpd2char(sourml>>8); /* declet 7 */ |
1604 dpd2char((sourml<<2) | (sourlo>>30)); /* declet 8 */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1605 dpd2char(sourlo>>20); /* declet 9 */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1606 dpd2char(sourlo>>10); /* declet 10 */ |
0 | 1607 dpd2char(sourlo); /* declet 11 */ |
1608 #endif | |
1609 | |
1610 if (c==cstart) *c++='0'; /* all zeros, empty -- make "0" */ | |
1611 | |
1612 /*[This fast path is valid but adds 3-5 cycles to worst case length] */ | |
1613 /*if (exp==0) { // integer or NaN case -- easy */ | |
1614 /* *c='\0'; // terminate */ | |
1615 /* return string; */ | |
1616 /* } */ | |
1617 | |
1618 e=0; /* assume no E */ | |
1619 pre=(Int)(c-cstart)+exp; /* length+exp [c->LSD+1] */ | |
1620 /* [here, pre-exp is the digits count (==1 for zero)] */ | |
1621 | |
1622 if (exp>0 || pre<-5) { /* need exponential form */ | |
1623 e=pre-1; /* calculate E value */ | |
1624 pre=1; /* assume one digit before '.' */ | |
1625 } /* exponential form */ | |
1626 | |
1627 /* modify the coefficient, adding 0s, '.', and E+nn as needed */ | |
1628 if (pre>0) { /* ddd.ddd (plain), perhaps with E */ | |
1629 char *dotat=cstart+pre; | |
1630 if (dotat<c) { /* if embedded dot needed... */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1631 /* [memmove is a disaster, here] */ |
0 | 1632 /* move by fours; there must be space for junk at the end */ |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1633 /* because exponent is still possible */ |
0 | 1634 s=dotat+ROUNDDOWN4(c-dotat); /* source */ |
1635 t=s+1; /* target */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1636 /* open the gap [cannot use memcpy] */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1637 for (; s>=dotat; s-=4, t-=4) UBFROMUI(t, UBTOUI(s)); |
0 | 1638 *dotat='.'; |
1639 c++; /* length increased by one */ | |
1640 } /* need dot? */ | |
1641 | |
1642 /* finally add the E-part, if needed; it will never be 0, and has */ | |
1643 /* a maximum length of 3 or 4 digits (asserted above) */ | |
1644 if (e!=0) { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1645 memcpy(c, "E+", 2); /* starts with E, assume + */ |
0 | 1646 c++; |
1647 if (e<0) { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1648 *c='-'; /* oops, need '-' */ |
0 | 1649 e=-e; /* uInt, please */ |
1650 } | |
1651 c++; | |
1652 /* Three-character exponents are easy; 4-character a little trickier */ | |
1653 #if DECEMAXD<=3 | |
1654 u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ | |
1655 /* copy fixed 4 characters [is safe], starting at non-zero */ | |
1656 /* and with character mask to convert BCD to char */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1657 UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); |
0 | 1658 c+=*(u+3); /* bump pointer appropriately */ |
1659 #elif DECEMAXD==4 | |
1660 if (e<1000) { /* 3 (or fewer) digits case */ | |
1661 u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1662 UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); /* [as above] */ |
0 | 1663 c+=*(u+3); /* bump pointer appropriately */ |
1664 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1665 else { /* 4-digits */ |
0 | 1666 Int thou=((e>>3)*1049)>>17; /* e/1000 */ |
1667 Int rem=e-(1000*thou); /* e%1000 */ | |
1668 *c++=(char)('0'+(char)thou); /* the thousands digit */ | |
1669 u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1670 UBFROMUI(c, UBTOUI(u)|CHARMASK); /* copy fixed 3+1 characters [is safe] */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1671 c+=3; /* bump pointer, always 3 digits */ |
0 | 1672 } |
1673 #endif | |
1674 } | |
1675 *c='\0'; /* add terminator */ | |
1676 /*printf("res %s\n", string); */ | |
1677 return string; | |
1678 } /* pre>0 */ | |
1679 | |
1680 /* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (can never have E) */ | |
1681 /* Surprisingly, this is close to being the worst-case path, so the */ | |
1682 /* shift is done by fours; this is a little tricky because the */ | |
1683 /* rightmost character to be written must not be beyond where the */ | |
1684 /* rightmost terminator could be -- so backoff to not touch */ | |
1685 /* terminator position if need be (this can make exact alignments */ | |
1686 /* for full Doubles, but in some cases needs care not to access too */ | |
1687 /* far to the left) */ | |
1688 | |
1689 pre=-pre+2; /* gap width, including "0." */ | |
1690 t=cstart+ROUNDDOWN4(c-cstart)+pre; /* preferred first target point */ | |
1691 /* backoff if too far to the right */ | |
1692 if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */ | |
1693 /* now shift the entire coefficient to the right, being careful not */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1694 /* to access to the left of string [cannot use memcpy] */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1695 for (s=t-pre; s>=string; s-=4, t-=4) UBFROMUI(t, UBTOUI(s)); |
0 | 1696 /* for Quads and Singles there may be a character or two left... */ |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1697 s+=3; /* where next would come from */ |
0 | 1698 for(; s>=cstart; s--, t--) *(t+3)=*(s); |
1699 /* now have fill 0. through 0.00000; use overlaps to avoid tests */ | |
1700 if (pre>=4) { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1701 memcpy(cstart+pre-4, "0000", 4); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1702 memcpy(cstart, "0.00", 4); |
0 | 1703 } |
1704 else { /* 2 or 3 */ | |
1705 *(cstart+pre-1)='0'; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1706 memcpy(cstart, "0.", 2); |
0 | 1707 } |
1708 *(c+pre)='\0'; /* terminate */ | |
1709 return string; | |
1710 } /* decFloatToString */ | |
1711 | |
1712 /* ------------------------------------------------------------------ */ | |
1713 /* decFloatToWider -- conversion to next-wider format */ | |
1714 /* */ | |
1715 /* source is the decFloat format number which gets the result of */ | |
1716 /* the conversion */ | |
1717 /* wider is the decFloatWider format number which will be narrowed */ | |
1718 /* returns wider */ | |
1719 /* */ | |
1720 /* Widening is always exact; no status is set (sNaNs are copied and */ | |
1721 /* do not signal). The result will be canonical if the source is, */ | |
1722 /* and may or may not be if the source is not. */ | |
1723 /* ------------------------------------------------------------------ */ | |
1724 /* widening is not possible for decQuad format numbers; simply omit */ | |
1725 #if !QUAD | |
1726 decFloatWider * decFloatToWider(const decFloat *source, decFloatWider *wider) { | |
1727 uInt msd; | |
1728 | |
1729 /* Construct and copy the sign word */ | |
1730 if (DFISSPECIAL(source)) { | |
1731 /* copy sign, combination, and first bit of exponent (sNaN selector) */ | |
1732 DFWWORD(wider, 0)=DFWORD(source, 0)&0xfe000000; | |
1733 msd=0; | |
1734 } | |
1735 else { /* is finite number */ | |
1736 uInt exp=GETEXPUN(source)+DECWBIAS; /* get unbiased exponent and rebias */ | |
1737 uInt code=(exp>>DECWECONL)<<29; /* set two bits of exp [msd=0] */ | |
1738 code|=(exp<<(32-6-DECWECONL)) & 0x03ffffff; /* add exponent continuation */ | |
1739 code|=DFWORD(source, 0)&0x80000000; /* add sign */ | |
1740 DFWWORD(wider, 0)=code; /* .. and place top word in wider */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1741 msd=GETMSD(source); /* get source coefficient MSD [0-9] */ |
0 | 1742 } |
1743 /* Copy the coefficient and clear any 'unused' words to left */ | |
1744 #if SINGLE | |
1745 DFWWORD(wider, 1)=(DFWORD(source, 0)&0x000fffff)|(msd<<20); | |
1746 #elif DOUBLE | |
1747 DFWWORD(wider, 2)=(DFWORD(source, 0)&0x0003ffff)|(msd<<18); | |
1748 DFWWORD(wider, 3)=DFWORD(source, 1); | |
1749 DFWWORD(wider, 1)=0; | |
1750 #endif | |
1751 return wider; | |
1752 } /* decFloatToWider */ | |
1753 #endif | |
1754 | |
1755 /* ------------------------------------------------------------------ */ | |
1756 /* decFloatVersion -- return package version string */ | |
1757 /* */ | |
1758 /* returns a constant string describing this package */ | |
1759 /* ------------------------------------------------------------------ */ | |
1760 const char *decFloatVersion(void) { | |
1761 return DECVERSION; | |
1762 } /* decFloatVersion */ | |
1763 | |
1764 /* ------------------------------------------------------------------ */ | |
1765 /* decFloatZero -- set to canonical (integer) zero */ | |
1766 /* */ | |
1767 /* df is the decFloat format number to integer +0 (q=0, c=+0) */ | |
1768 /* returns df */ | |
1769 /* */ | |
1770 /* No error is possible, and no status can be set. */ | |
1771 /* ------------------------------------------------------------------ */ | |
1772 decFloat * decFloatZero(decFloat *df){ | |
1773 DFWORD(df, 0)=ZEROWORD; /* set appropriate top word */ | |
1774 #if DOUBLE || QUAD | |
1775 DFWORD(df, 1)=0; | |
1776 #if QUAD | |
1777 DFWORD(df, 2)=0; | |
1778 DFWORD(df, 3)=0; | |
1779 #endif | |
1780 #endif | |
1781 /* decFloatShow(df, "zero"); */ | |
1782 return df; | |
1783 } /* decFloatZero */ | |
1784 | |
1785 /* ------------------------------------------------------------------ */ | |
1786 /* Private generic function (not format-specific) for development use */ | |
1787 /* ------------------------------------------------------------------ */ | |
1788 /* This is included once only, for all to use */ | |
1789 #if QUAD && (DECCHECK || DECTRACE) | |
1790 /* ---------------------------------------------------------------- */ | |
1791 /* decShowNum -- display bcd8 number in debug form */ | |
1792 /* */ | |
1793 /* num is the bcdnum to display */ | |
1794 /* tag is a string to label the display */ | |
1795 /* ---------------------------------------------------------------- */ | |
1796 void decShowNum(const bcdnum *num, const char *tag) { | |
1797 const char *csign="+"; /* sign character */ | |
1798 uByte *ub; /* work */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1799 uInt uiwork; /* for macros */ |
0 | 1800 if (num->sign==DECFLOAT_Sign) csign="-"; |
1801 | |
1802 printf(">%s> ", tag); | |
1803 if (num->exponent==DECFLOAT_Inf) printf("%sInfinity", csign); | |
1804 else if (num->exponent==DECFLOAT_qNaN) printf("%sqNaN", csign); | |
1805 else if (num->exponent==DECFLOAT_sNaN) printf("%ssNaN", csign); | |
1806 else { /* finite */ | |
1807 char qbuf[10]; /* for right-aligned q */ | |
1808 char *c; /* work */ | |
1809 const uByte *u; /* .. */ | |
1810 Int e=num->exponent; /* .. exponent */ | |
1811 strcpy(qbuf, "q="); | |
1812 c=&qbuf[2]; /* where exponent will go */ | |
1813 /* lay out the exponent */ | |
1814 if (e<0) { | |
1815 *c++='-'; /* add '-' */ | |
1816 e=-e; /* uInt, please */ | |
1817 } | |
1818 #if DECEMAXD>4 | |
1819 #error Exponent form is too long for ShowNum to lay out | |
1820 #endif | |
1821 if (e==0) *c++='0'; /* 0-length case */ | |
1822 else if (e<1000) { /* 3 (or fewer) digits case */ | |
1823 u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1824 UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); /* [as above] */ |
0 | 1825 c+=*(u+3); /* bump pointer appropriately */ |
1826 } | |
1827 else { /* 4-digits */ | |
1828 Int thou=((e>>3)*1049)>>17; /* e/1000 */ | |
1829 Int rem=e-(1000*thou); /* e%1000 */ | |
1830 *c++=(char)('0'+(char)thou); /* the thousands digit */ | |
1831 u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1832 UBFROMUI(c, UBTOUI(u)|CHARMASK); /* copy fixed 3+1 characters [is safe] */ |
0 | 1833 c+=3; /* bump pointer, always 3 digits */ |
1834 } | |
1835 *c='\0'; /* add terminator */ | |
1836 printf("%7s c=%s", qbuf, csign); | |
1837 } | |
1838 | |
1839 if (!EXPISSPECIAL(num->exponent) || num->msd!=num->lsd || *num->lsd!=0) { | |
1840 for (ub=num->msd; ub<=num->lsd; ub++) { /* coefficient... */ | |
1841 printf("%1x", *ub); | |
1842 if ((num->lsd-ub)%3==0 && ub!=num->lsd) printf(" "); /* 4-space */ | |
1843 } | |
1844 } | |
1845 printf("\n"); | |
1846 } /* decShowNum */ | |
1847 #endif |