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