comparison libdecnumber/decCommon.c @ 0:a06113de4d67

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