Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(288)

Side by Side Diff: gcc/libdecnumber/dpd/decimal64.c

Issue 3050029: [gcc] GCC 4.5.0=>4.5.1 (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/nacl-toolchain.git
Patch Set: Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « gcc/libdecnumber/dpd/decimal32.c ('k') | gcc/libgcc/Makefile.in » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* Decimal 64-bit format module for the decNumber C Library. 1 /* Decimal 64-bit format module for the decNumber C Library.
2 Copyright (C) 2005, 2007, 2009 Free Software Foundation, Inc. 2 Copyright (C) 2005, 2007, 2009 Free Software Foundation, Inc.
3 Contributed by IBM Corporation. Author Mike Cowlishaw. 3 Contributed by IBM Corporation. Author Mike Cowlishaw.
4 4
5 This file is part of GCC. 5 This file is part of GCC.
6 6
7 GCC is free software; you can redistribute it and/or modify it under 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 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 9 Software Foundation; either version 3, or (at your option) any later
10 version. 10 version.
11 11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 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 13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details. 15 for more details.
16 16
17 Under Section 7 of GPL version 3, you are granted additional 17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version 18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation. 19 3.1, as published by the Free Software Foundation.
20 20
21 You should have received a copy of the GNU General Public License and 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; 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 23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */ 24 <http://www.gnu.org/licenses/>. */
25 25
26 /* ------------------------------------------------------------------ */ 26 /* ------------------------------------------------------------------ */
27 /* Decimal 64-bit format module»» » » » */ 27 /* Decimal 64-bit format module » » » » */
28 /* ------------------------------------------------------------------ */ 28 /* ------------------------------------------------------------------ */
29 /* This module comprises the routines for decimal64 format numbers. */ 29 /* This module comprises the routines for decimal64 format numbers. */
30 /* Conversions are supplied to and from decNumber and String. */ 30 /* Conversions are supplied to and from decNumber and String. */
31 /* */ 31 /* */
32 /* This is used when decNumber provides operations, either for all */ 32 /* This is used when decNumber provides operations, either for all */
33 /* operations or as a proxy between decNumber and decSingle. */ 33 /* operations or as a proxy between decNumber and decSingle. */
34 /* */ 34 /* */
35 /* Error handling is the same as decNumber (qv.). */ 35 /* Error handling is the same as decNumber (qv.). */
36 /* ------------------------------------------------------------------ */ 36 /* ------------------------------------------------------------------ */
37 #include <string.h> /* [for memset/memcpy] */ 37 #include <string.h> /* [for memset/memcpy] */
38 #include <stdio.h> /* [for printf] */ 38 #include <stdio.h> /* [for printf] */
39 39
40 #include "dconfig.h"» /* GCC definitions */ 40 #include "dconfig.h" /* GCC definitions */
41 #define» DECNUMDIGITS 16 /* make decNumbers with space for 16 */ 41 #define DECNUMDIGITS 16 /* make decNumbers with space for 16 */
42 #include "decNumber.h" /* base number library */ 42 #include "decNumber.h" /* base number library */
43 #include "decNumberLocal.h" /* decNumber local types, etc. */ 43 #include "decNumberLocal.h" /* decNumber local types, etc. */
44 #include "decimal64.h" /* our primary include */ 44 #include "decimal64.h" /* our primary include */
45 45
46 /* Utility routines and tables [in decimal64.c]; externs for C++ */ 46 /* Utility routines and tables [in decimal64.c]; externs for C++ */
47 extern const uInt COMBEXP[32], COMBMSD[32]; 47 extern const uInt COMBEXP[32], COMBMSD[32];
48 extern const uShort DPD2BIN[1024]; 48 extern const uShort DPD2BIN[1024];
49 extern const uShort BIN2DPD[1000]; 49 extern const uShort BIN2DPD[1000];
50 extern const uByte BIN2CHAR[4001]; 50 extern const uByte BIN2CHAR[4001];
51 51
(...skipping 11 matching lines...) Expand all
63 63
64 /* define and include the tables to use for conversions */ 64 /* define and include the tables to use for conversions */
65 #define DEC_BIN2CHAR 1 65 #define DEC_BIN2CHAR 1
66 #define DEC_DPD2BIN 1 66 #define DEC_DPD2BIN 1
67 #define DEC_BIN2DPD 1 /* used for all sizes */ 67 #define DEC_BIN2DPD 1 /* used for all sizes */
68 #include "decDPD.h" /* lookup tables */ 68 #include "decDPD.h" /* lookup tables */
69 69
70 /* ------------------------------------------------------------------ */ 70 /* ------------------------------------------------------------------ */
71 /* decimal64FromNumber -- convert decNumber to decimal64 */ 71 /* decimal64FromNumber -- convert decNumber to decimal64 */
72 /* */ 72 /* */
73 /* ds is the target decimal64»» » » » */ 73 /* ds is the target decimal64 » » » » */
74 /* dn is the source number (assumed valid) */ 74 /* dn is the source number (assumed valid) */
75 /* set is the context, used only for reporting errors»» */ 75 /* set is the context, used only for reporting errors » */
76 /* */ 76 /* */
77 /* The set argument is used only for status reporting and for the */ 77 /* The set argument is used only for status reporting and for the */
78 /* rounding mode (used if the coefficient is more than DECIMAL64_Pmax */ 78 /* rounding mode (used if the coefficient is more than DECIMAL64_Pmax */
79 /* digits or an overflow is detected). If the exponent is out of the */ 79 /* digits or an overflow is detected). If the exponent is out of the */
80 /* valid range then Overflow or Underflow will be raised. */ 80 /* valid range then Overflow or Underflow will be raised. */
81 /* After Underflow a subnormal result is possible. */ 81 /* After Underflow a subnormal result is possible. */
82 /* */ 82 /* */
83 /* DEC_Clamped is set if the number has to be 'folded down' to fit, */ 83 /* DEC_Clamped is set if the number has to be 'folded down' to fit, */
84 /* by reducing its exponent and multiplying the coefficient by a */ 84 /* by reducing its exponent and multiplying the coefficient by a */
85 /* power of ten, or if the exponent on a zero had to be clamped. */ 85 /* power of ten, or if the exponent on a zero had to be clamped. */
86 /* ------------------------------------------------------------------ */ 86 /* ------------------------------------------------------------------ */
87 decimal64 * decimal64FromNumber(decimal64 *d64, const decNumber *dn, 87 decimal64 * decimal64FromNumber(decimal64 *d64, const decNumber *dn,
88 decContext *set) { 88 decContext *set) {
89 uInt status=0; /* status accumulator */ 89 uInt status=0; /* status accumulator */
90 Int ae; /* adjusted exponent */ 90 Int ae; /* adjusted exponent */
91 decNumber dw; /* work */ 91 decNumber dw; /* work */
92 decContext dc; /* .. */ 92 decContext dc; /* .. */
93 uInt *pu; /* .. */
94 uInt comb, exp; /* .. */ 93 uInt comb, exp; /* .. */
94 uInt uiwork; /* for macros */
95 uInt targar[2]={0, 0}; /* target 64-bit */ 95 uInt targar[2]={0, 0}; /* target 64-bit */
96 #define targhi targar[1] /* name the word with the sign */ 96 #define targhi targar[1] /* name the word with the sign */
97 #define targlo targar[0] /* and the other */ 97 #define targlo targar[0] /* and the other */
98 98
99 /* If the number has too many digits, or the exponent could be */ 99 /* If the number has too many digits, or the exponent could be */
100 /* out of range then reduce the number under the appropriate */ 100 /* out of range then reduce the number under the appropriate */
101 /* constraints. This could push the number to Infinity or zero, */ 101 /* constraints. This could push the number to Infinity or zero, */
102 /* so this check and rounding must be done before generating the */ 102 /* so this check and rounding must be done before generating the */
103 /* decimal64] */ 103 /* decimal64] */
104 ae=dn->exponent+dn->digits-1;»» /* [0 if special] */ 104 ae=dn->exponent+dn->digits-1; » /* [0 if special] */
105 if (dn->digits>DECIMAL64_Pmax»» /* too many digits */ 105 if (dn->digits>DECIMAL64_Pmax » /* too many digits */
106 || ae>DECIMAL64_Emax»» » /* likely overflow */ 106 || ae>DECIMAL64_Emax » » /* likely overflow */
107 || ae<DECIMAL64_Emin) { /* likely underflow */ 107 || ae<DECIMAL64_Emin) { /* likely underflow */
108 decContextDefault(&dc, DEC_INIT_DECIMAL64); /* [no traps] */ 108 decContextDefault(&dc, DEC_INIT_DECIMAL64); /* [no traps] */
109 dc.round=set->round; /* use supplied rounding */ 109 dc.round=set->round; /* use supplied rounding */
110 decNumberPlus(&dw, dn, &dc); /* (round and check) */ 110 decNumberPlus(&dw, dn, &dc); /* (round and check) */
111 /* [this changes -0 to 0, so enforce the sign...] */ 111 /* [this changes -0 to 0, so enforce the sign...] */
112 dw.bits|=dn->bits&DECNEG; 112 dw.bits|=dn->bits&DECNEG;
113 status=dc.status; /* save status */ 113 status=dc.status; /* save status */
114 dn=&dw; /* use the work number */ 114 dn=&dw; /* use the work number */
115 } /* maybe out of range */ 115 } /* maybe out of range */
116 116
117 if (dn->bits&DECSPECIAL) { /* a special value */ 117 if (dn->bits&DECSPECIAL) { /* a special value */
118 if (dn->bits&DECINF) targhi=DECIMAL_Inf<<24; 118 if (dn->bits&DECINF) targhi=DECIMAL_Inf<<24;
119 else { /* sNaN or qNaN */ 119 else { /* sNaN or qNaN */
120 if ((*dn->lsu!=0 || dn->digits>1)»» /* non-zero coefficient */ 120 if ((*dn->lsu!=0 || dn->digits>1) » /* non-zero coefficient */
121 && (dn->digits<DECIMAL64_Pmax)) { /* coefficient fits */ 121 && (dn->digits<DECIMAL64_Pmax)) { /* coefficient fits */
122 decDigitsToDPD(dn, targar, 0); 122 decDigitsToDPD(dn, targar, 0);
123 } 123 }
124 if (dn->bits&DECNAN) targhi|=DECIMAL_NaN<<24; 124 if (dn->bits&DECNAN) targhi|=DECIMAL_NaN<<24;
125 else targhi|=DECIMAL_sNaN<<24; 125 else targhi|=DECIMAL_sNaN<<24;
126 } /* a NaN */ 126 } /* a NaN */
127 } /* special */ 127 } /* special */
128 128
129 else { /* is finite */ 129 else { /* is finite */
130 if (decNumberIsZero(dn)) { /* is a zero */ 130 if (decNumberIsZero(dn)) { /* is a zero */
131 /* set and clamp exponent */ 131 /* set and clamp exponent */
132 if (dn->exponent<-DECIMAL64_Bias) { 132 if (dn->exponent<-DECIMAL64_Bias) {
133 exp=0; /* low clamp */ 133 exp=0; /* low clamp */
134 status|=DEC_Clamped; 134 status|=DEC_Clamped;
135 } 135 }
136 else { 136 else {
137 exp=dn->exponent+DECIMAL64_Bias; /* bias exponent */ 137 exp=dn->exponent+DECIMAL64_Bias; /* bias exponent */
138 if (exp>DECIMAL64_Ehigh) { /* top clamp */ 138 if (exp>DECIMAL64_Ehigh) { /* top clamp */
139 exp=DECIMAL64_Ehigh; 139 exp=DECIMAL64_Ehigh;
140 status|=DEC_Clamped; 140 status|=DEC_Clamped;
141 } 141 }
142 } 142 }
143 comb=(exp>>5) & 0x18; /* msd=0, exp top 2 bits .. */ 143 comb=(exp>>5) & 0x18; /* msd=0, exp top 2 bits .. */
144 } 144 }
145 else { /* non-zero finite number */ 145 else { /* non-zero finite number */
146 uInt msd;»» » » /* work */ 146 uInt msd; » » » /* work */
147 Int pad=0; /* coefficient pad digits */ 147 Int pad=0; /* coefficient pad digits */
148 148
149 /* the dn is known to fit, but it may need to be padded */ 149 /* the dn is known to fit, but it may need to be padded */
150 exp=(uInt)(dn->exponent+DECIMAL64_Bias); /* bias exponent */ 150 exp=(uInt)(dn->exponent+DECIMAL64_Bias); /* bias exponent */
151 if (exp>DECIMAL64_Ehigh) { /* fold-down case */ 151 if (exp>DECIMAL64_Ehigh) { /* fold-down case */
152 pad=exp-DECIMAL64_Ehigh; 152 pad=exp-DECIMAL64_Ehigh;
153 exp=DECIMAL64_Ehigh; /* [to maximum] */ 153 exp=DECIMAL64_Ehigh; /* [to maximum] */
154 status|=DEC_Clamped; 154 status|=DEC_Clamped;
155 } 155 }
156 156
(...skipping 24 matching lines...) Expand all
181 if (msd>=8) comb=0x18 | ((exp>>7) & 0x06) | (msd & 0x01); 181 if (msd>=8) comb=0x18 | ((exp>>7) & 0x06) | (msd & 0x01);
182 else comb=((exp>>5) & 0x18) | msd; 182 else comb=((exp>>5) & 0x18) | msd;
183 } 183 }
184 targhi|=comb<<26; /* add combination field .. */ 184 targhi|=comb<<26; /* add combination field .. */
185 targhi|=(exp&0xff)<<18; /* .. and exponent continuation */ 185 targhi|=(exp&0xff)<<18; /* .. and exponent continuation */
186 } /* finite */ 186 } /* finite */
187 187
188 if (dn->bits&DECNEG) targhi|=0x80000000; /* add sign bit */ 188 if (dn->bits&DECNEG) targhi|=0x80000000; /* add sign bit */
189 189
190 /* now write to storage; this is now always endian */ 190 /* now write to storage; this is now always endian */
191 pu=(uInt *)d64->bytes; /* overlay */
192 if (DECLITEND) { 191 if (DECLITEND) {
193 pu[0]=targar[0];» » /* directly store the low int */ 192 /* lo int then hi */
194 pu[1]=targar[1];» » /* then the high int */ 193 UBFROMUI(d64->bytes, targar[0]);
194 UBFROMUI(d64->bytes+4, targar[1]);
195 } 195 }
196 else { 196 else {
197 pu[0]=targar[1];» » /* directly store the high int */ 197 /* hi int then lo */
198 pu[1]=targar[0];» » /* then the low int */ 198 UBFROMUI(d64->bytes, targar[1]);
199 UBFROMUI(d64->bytes+4, targar[0]);
199 } 200 }
200 201
201 if (status!=0) decContextSetStatus(set, status); /* pass on status */ 202 if (status!=0) decContextSetStatus(set, status); /* pass on status */
202 /* decimal64Show(d64); */ 203 /* decimal64Show(d64); */
203 return d64; 204 return d64;
204 } /* decimal64FromNumber */ 205 } /* decimal64FromNumber */
205 206
206 /* ------------------------------------------------------------------ */ 207 /* ------------------------------------------------------------------ */
207 /* decimal64ToNumber -- convert decimal64 to decNumber */ 208 /* decimal64ToNumber -- convert decimal64 to decNumber */
208 /* d64 is the source decimal64 */ 209 /* d64 is the source decimal64 */
209 /* dn is the target number, with appropriate space */ 210 /* dn is the target number, with appropriate space */
210 /* No error is possible. */ 211 /* No error is possible. */
211 /* ------------------------------------------------------------------ */ 212 /* ------------------------------------------------------------------ */
212 decNumber * decimal64ToNumber(const decimal64 *d64, decNumber *dn) { 213 decNumber * decimal64ToNumber(const decimal64 *d64, decNumber *dn) {
213 uInt msd; /* coefficient MSD */ 214 uInt msd; /* coefficient MSD */
214 uInt exp; /* exponent top two bits */ 215 uInt exp; /* exponent top two bits */
215 uInt comb; /* combination field */ 216 uInt comb; /* combination field */
216 const uInt *pu;» » /* work */ 217 Int need;» » » /* work */
217 Int need;» » » /* .. */ 218 uInt uiwork;» » » /* for macros */
218 uInt sourar[2]; /* source 64-bit */ 219 uInt sourar[2]; /* source 64-bit */
219 #define sourhi sourar[1] /* name the word with the sign */ 220 #define sourhi sourar[1] /* name the word with the sign */
220 #define sourlo sourar[0] /* and the lower word */ 221 #define sourlo sourar[0] /* and the lower word */
221 222
222 /* load source from storage; this is endian */ 223 /* load source from storage; this is endian */
223 pu=(const uInt *)d64->bytes; /* overlay */
224 if (DECLITEND) { 224 if (DECLITEND) {
225 sourlo=pu[0];» » /* directly load the low int */ 225 sourlo=UBTOUI(d64->bytes ); /* directly load the low int */
226 sourhi=pu[1];» » /* then the high int */ 226 sourhi=UBTOUI(d64->bytes+4); /* then the high int */
227 } 227 }
228 else { 228 else {
229 sourhi=pu[0];» » /* directly load the high int */ 229 sourhi=UBTOUI(d64->bytes ); /* directly load the high int */
230 sourlo=pu[1];» » /* then the low int */ 230 sourlo=UBTOUI(d64->bytes+4); /* then the low int */
231 } 231 }
232 232
233 comb=(sourhi>>26)&0x1f; /* combination field */ 233 comb=(sourhi>>26)&0x1f; /* combination field */
234 234
235 decNumberZero(dn); /* clean number */ 235 decNumberZero(dn); /* clean number */
236 if (sourhi&0x80000000) dn->bits=DECNEG; /* set sign if negative */ 236 if (sourhi&0x80000000) dn->bits=DECNEG; /* set sign if negative */
237 237
238 msd=COMBMSD[comb]; /* decode the combination field */ 238 msd=COMBMSD[comb]; /* decode the combination field */
239 exp=COMBEXP[comb]; /* .. */ 239 exp=COMBEXP[comb]; /* .. */
240 240
241 if (exp==3) {»» » /* is a special */ 241 if (exp==3) { » » /* is a special */
242 if (msd==0) { 242 if (msd==0) {
243 dn->bits|=DECINF; 243 dn->bits|=DECINF;
244 return dn; /* no coefficient needed */ 244 return dn; /* no coefficient needed */
245 } 245 }
246 else if (sourhi&0x02000000) dn->bits|=DECSNAN; 246 else if (sourhi&0x02000000) dn->bits|=DECSNAN;
247 else dn->bits|=DECNAN; 247 else dn->bits|=DECNAN;
248 msd=0; /* no top digit */ 248 msd=0; /* no top digit */
249 } 249 }
250 else { /* is a finite number */ 250 else { /* is a finite number */
251 dn->exponent=(exp<<8)+((sourhi>>18)&0xff)-DECIMAL64_Bias; /* unbiased */ 251 dn->exponent=(exp<<8)+((sourhi>>18)&0xff)-DECIMAL64_Bias; /* unbiased */
(...skipping 17 matching lines...) Expand all
269 if (sourhi&0x0003ff00) need++; /* top declet!=0, process 5 */ 269 if (sourhi&0x0003ff00) need++; /* top declet!=0, process 5 */
270 } 270 }
271 } /*msd=0 */ 271 } /*msd=0 */
272 272
273 decDigitsFromDPD(dn, sourar, need); /* process declets */ 273 decDigitsFromDPD(dn, sourar, need); /* process declets */
274 return dn; 274 return dn;
275 } /* decimal64ToNumber */ 275 } /* decimal64ToNumber */
276 276
277 277
278 /* ------------------------------------------------------------------ */ 278 /* ------------------------------------------------------------------ */
279 /* to-scientific-string -- conversion to numeric string»» */ 279 /* to-scientific-string -- conversion to numeric string » */
280 /* to-engineering-string -- conversion to numeric string */ 280 /* to-engineering-string -- conversion to numeric string */
281 /* */ 281 /* */
282 /* decimal64ToString(d64, string); */ 282 /* decimal64ToString(d64, string); */
283 /* decimal64ToEngString(d64, string);»» » » */ 283 /* decimal64ToEngString(d64, string); » » » */
284 /* */ 284 /* */
285 /* d64 is the decimal64 format number to convert */ 285 /* d64 is the decimal64 format number to convert */
286 /* string is the string where the result will be laid out */ 286 /* string is the string where the result will be laid out */
287 /* */ 287 /* */
288 /* string must be at least 24 characters */ 288 /* string must be at least 24 characters */
289 /* */ 289 /* */
290 /* No error is possible, and no status can be set. */ 290 /* No error is possible, and no status can be set. */
291 /* ------------------------------------------------------------------ */ 291 /* ------------------------------------------------------------------ */
292 char * decimal64ToEngString(const decimal64 *d64, char *string){ 292 char * decimal64ToEngString(const decimal64 *d64, char *string){
293 decNumber dn;»» » » /* work */ 293 decNumber dn; » » » /* work */
294 decimal64ToNumber(d64, &dn); 294 decimal64ToNumber(d64, &dn);
295 decNumberToEngString(&dn, string); 295 decNumberToEngString(&dn, string);
296 return string; 296 return string;
297 } /* decimal64ToEngString */ 297 } /* decimal64ToEngString */
298 298
299 char * decimal64ToString(const decimal64 *d64, char *string){ 299 char * decimal64ToString(const decimal64 *d64, char *string){
300 uInt msd; /* coefficient MSD */ 300 uInt msd; /* coefficient MSD */
301 Int exp; /* exponent top two bits or full */ 301 Int exp; /* exponent top two bits or full */
302 uInt comb; /* combination field */ 302 uInt comb; /* combination field */
303 char *cstart;»» » /* coefficient start */ 303 char *cstart; » » /* coefficient start */
304 char *c; /* output pointer in string */ 304 char *c; /* output pointer in string */
305 const uInt *pu;» » /* work */ 305 const uByte *u;» » /* work */
306 char *s, *t; /* .. (source, target) */ 306 char *s, *t; /* .. (source, target) */
307 Int dpd; /* .. */ 307 Int dpd; /* .. */
308 Int pre, e; /* .. */ 308 Int pre, e; /* .. */
309 const uByte *u;» » /* .. */ 309 uInt uiwork;» » » /* for macros */
310 310
311 uInt sourar[2]; /* source 64-bit */ 311 uInt sourar[2]; /* source 64-bit */
312 #define sourhi sourar[1] /* name the word with the sign */ 312 #define sourhi sourar[1] /* name the word with the sign */
313 #define sourlo sourar[0] /* and the lower word */ 313 #define sourlo sourar[0] /* and the lower word */
314 314
315 /* load source from storage; this is endian */ 315 /* load source from storage; this is endian */
316 pu=(const uInt *)d64->bytes; /* overlay */
317 if (DECLITEND) { 316 if (DECLITEND) {
318 sourlo=pu[0];» » /* directly load the low int */ 317 sourlo=UBTOUI(d64->bytes ); /* directly load the low int */
319 sourhi=pu[1];» » /* then the high int */ 318 sourhi=UBTOUI(d64->bytes+4); /* then the high int */
320 } 319 }
321 else { 320 else {
322 sourhi=pu[0];» » /* directly load the high int */ 321 sourhi=UBTOUI(d64->bytes ); /* directly load the high int */
323 sourlo=pu[1];» » /* then the low int */ 322 sourlo=UBTOUI(d64->bytes+4); /* then the low int */
324 } 323 }
325 324
326 c=string; /* where result will go */ 325 c=string; /* where result will go */
327 if (((Int)sourhi)<0) *c++='-'; /* handle sign */ 326 if (((Int)sourhi)<0) *c++='-'; /* handle sign */
328 327
329 comb=(sourhi>>26)&0x1f; /* combination field */ 328 comb=(sourhi>>26)&0x1f; /* combination field */
330 msd=COMBMSD[comb]; /* decode the combination field */ 329 msd=COMBMSD[comb]; /* decode the combination field */
331 exp=COMBEXP[comb]; /* .. */ 330 exp=COMBEXP[comb]; /* .. */
332 331
333 if (exp==3) { 332 if (exp==3) {
334 if (msd==0) { /* infinity */ 333 if (msd==0) { /* infinity */
335 strcpy(c,» "Inf"); 334 strcpy(c, "Inf");
336 strcpy(c+3, "inity"); 335 strcpy(c+3, "inity");
337 return string; /* easy */ 336 return string; /* easy */
338 } 337 }
339 if (sourhi&0x02000000) *c++='s'; /* sNaN */ 338 if (sourhi&0x02000000) *c++='s'; /* sNaN */
340 strcpy(c, "NaN"); /* complete word */ 339 strcpy(c, "NaN"); /* complete word */
341 c+=3; /* step past */ 340 c+=3; /* step past */
342 if (sourlo==0 && (sourhi&0x0003ffff)==0) return string; /* zero payload */ 341 if (sourlo==0 && (sourhi&0x0003ffff)==0) return string; /* zero payload */
343 /* otherwise drop through to add integer; set correct exp */ 342 /* otherwise drop through to add integer; set correct exp */
344 exp=0; msd=0; /* setup for following code */ 343 exp=0; msd=0; /* setup for following code */
345 } 344 }
346 else exp=(exp<<8)+((sourhi>>18)&0xff)-DECIMAL64_Bias; 345 else exp=(exp<<8)+((sourhi>>18)&0xff)-DECIMAL64_Bias;
347 346
348 /* convert 16 digits of significand to characters */ 347 /* convert 16 digits of significand to characters */
349 cstart=c; /* save start of coefficient */ 348 cstart=c; /* save start of coefficient */
350 if (msd) *c++='0'+(char)msd; /* non-zero most significant digit */ 349 if (msd) *c++='0'+(char)msd; /* non-zero most significant digit */
351 350
352 /* Now decode the declets. After extracting each one, it is */ 351 /* Now decode the declets. After extracting each one, it is */
353 /* decoded to binary and then to a 4-char sequence by table lookup; */ 352 /* decoded to binary and then to a 4-char sequence by table lookup; */
354 /* the 4-chars are a 1-char length (significant digits, except 000 */ 353 /* the 4-chars are a 1-char length (significant digits, except 000 */
355 /* has length 0). This allows us to left-align the first declet */ 354 /* has length 0). This allows us to left-align the first declet */
356 /* with non-zero content, then remaining ones are full 3-char */ 355 /* with non-zero content, then remaining ones are full 3-char */
357 /* length. We use fixed-length memcpys because variable-length */ 356 /* length. We use fixed-length memcpys because variable-length */
358 /* causes a subroutine call in GCC. (These are length 4 for speed */ 357 /* causes a subroutine call in GCC. (These are length 4 for speed */
359 /* and are safe because the array has an extra terminator byte.) */ 358 /* and are safe because the array has an extra terminator byte.) */
360 #define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4];»» » \ 359 #define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; » » \
361 if (c!=cstart) {memcpy(c, u+1, 4); c+=3;} \ 360 if (c!=cstart) {memcpy(c, u+1, 4); c+=3;} \
362 else if (*u) {memcpy(c, u+4-*u, 4); c+=*u;} 361 else if (*u) {memcpy(c, u+4-*u, 4); c+=*u;}
363 362
364 dpd=(sourhi>>8)&0x3ff; /* declet 1 */ 363 dpd=(sourhi>>8)&0x3ff; /* declet 1 */
365 dpd2char; 364 dpd2char;
366 dpd=((sourhi&0xff)<<2) | (sourlo>>30); /* declet 2 */ 365 dpd=((sourhi&0xff)<<2) | (sourlo>>30); /* declet 2 */
367 dpd2char; 366 dpd2char;
368 dpd=(sourlo>>20)&0x3ff; /* declet 3 */ 367 dpd=(sourlo>>20)&0x3ff; /* declet 3 */
369 dpd2char; 368 dpd2char;
370 dpd=(sourlo>>10)&0x3ff; /* declet 4 */ 369 dpd=(sourlo>>10)&0x3ff; /* declet 4 */
371 dpd2char; 370 dpd2char;
372 dpd=(sourlo)&0x3ff; /* declet 5 */ 371 dpd=(sourlo)&0x3ff; /* declet 5 */
373 dpd2char; 372 dpd2char;
374 373
375 if (c==cstart) *c++='0'; /* all zeros -- make 0 */ 374 if (c==cstart) *c++='0'; /* all zeros -- make 0 */
376 375
377 if (exp==0) {»» » /* integer or NaN case -- easy */ 376 if (exp==0) { » » /* integer or NaN case -- easy */
378 *c='\0'; /* terminate */ 377 *c='\0'; /* terminate */
379 return string; 378 return string;
380 } 379 }
381 380
382 /* non-0 exponent */ 381 /* non-0 exponent */
383 e=0; /* assume no E */ 382 e=0; /* assume no E */
384 pre=c-cstart+exp; 383 pre=c-cstart+exp;
385 /* [here, pre-exp is the digits count (==1 for zero)] */ 384 /* [here, pre-exp is the digits count (==1 for zero)] */
386 if (exp>0 || pre<-5) { /* need exponential form */ 385 if (exp>0 || pre<-5) { /* need exponential form */
387 e=pre-1; /* calculate E value */ 386 e=pre-1; /* calculate E value */
388 pre=1; /* assume one digit before '.' */ 387 pre=1; /* assume one digit before '.' */
389 } /* exponential form */ 388 } /* exponential form */
390 389
391 /* modify the coefficient, adding 0s, '.', and E+nn as needed */ 390 /* modify the coefficient, adding 0s, '.', and E+nn as needed */
392 s=c-1; /* source (LSD) */ 391 s=c-1; /* source (LSD) */
393 if (pre>0) { /* ddd.ddd (plain), perhaps with E */ 392 if (pre>0) { /* ddd.ddd (plain), perhaps with E */
394 char *dotat=cstart+pre; 393 char *dotat=cstart+pre;
395 if (dotat<c) { /* if embedded dot needed... */ 394 if (dotat<c) { /* if embedded dot needed... */
396 t=c; /* target */ 395 t=c; /* target */
397 for (; s>=dotat; s--, t--) *t=*s; /* open the gap; leave t at gap */ 396 for (; s>=dotat; s--, t--) *t=*s; /* open the gap; leave t at gap */
398 *t='.'; /* insert the dot */ 397 *t='.'; /* insert the dot */
399 c++; /* length increased by one */ 398 c++; /* length increased by one */
400 } 399 }
401 400
402 /* finally add the E-part, if needed; it will never be 0, and has */ 401 /* finally add the E-part, if needed; it will never be 0, and has */
403 /* a maximum length of 3 digits */ 402 /* a maximum length of 3 digits */
404 if (e!=0) { 403 if (e!=0) {
405 *c++='E';»» » /* starts with E */ 404 *c++='E'; » » /* starts with E */
406 *c++='+';»» » /* assume positive */ 405 *c++='+'; » » /* assume positive */
407 if (e<0) { 406 if (e<0) {
408 *(c-1)='-'; /* oops, need '-' */ 407 *(c-1)='-'; /* oops, need '-' */
409 e=-e; /* uInt, please */ 408 e=-e; /* uInt, please */
410 } 409 }
411 u=&BIN2CHAR[e*4];»» /* -> length byte */ 410 u=&BIN2CHAR[e*4]; » /* -> length byte */
412 memcpy(c, u+4-*u, 4); /* copy fixed 4 characters [is safe] */ 411 memcpy(c, u+4-*u, 4); /* copy fixed 4 characters [is safe] */
413 c+=*u; /* bump pointer appropriately */ 412 c+=*u; /* bump pointer appropriately */
414 } 413 }
415 *c='\0'; /* add terminator */ 414 *c='\0'; /* add terminator */
416 /*printf("res %s\n", string); */ 415 /*printf("res %s\n", string); */
417 return string; 416 return string;
418 } /* pre>0 */ 417 } /* pre>0 */
419 418
420 /* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (can never have E) */ 419 /* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (can never have E) */
421 t=c+1-pre; 420 t=c+1-pre;
422 *(t+1)='\0'; /* can add terminator now */ 421 *(t+1)='\0'; /* can add terminator now */
423 for (; s>=cstart; s--, t--) *t=*s; /* shift whole coefficient right */ 422 for (; s>=cstart; s--, t--) *t=*s; /* shift whole coefficient right */
424 c=cstart; 423 c=cstart;
425 *c++='0'; /* always starts with 0. */ 424 *c++='0'; /* always starts with 0. */
426 *c++='.'; 425 *c++='.';
427 for (; pre<0; pre++) *c++='0'; /* add any 0's after '.' */ 426 for (; pre<0; pre++) *c++='0'; /* add any 0's after '.' */
428 /*printf("res %s\n", string); */ 427 /*printf("res %s\n", string); */
429 return string; 428 return string;
430 } /* decimal64ToString */ 429 } /* decimal64ToString */
431 430
432 /* ------------------------------------------------------------------ */ 431 /* ------------------------------------------------------------------ */
433 /* to-number -- conversion from numeric string */ 432 /* to-number -- conversion from numeric string */
434 /* */ 433 /* */
435 /* decimal64FromString(result, string, set); */ 434 /* decimal64FromString(result, string, set); */
436 /* */ 435 /* */
437 /* result is the decimal64 format number which gets the result of */ 436 /* result is the decimal64 format number which gets the result of */
438 /* the conversion */ 437 /* the conversion */
439 /* *string is the character string which should contain a valid */ 438 /* *string is the character string which should contain a valid */
440 /* number (which may be a special value) */ 439 /* number (which may be a special value) */
441 /* set» is the context» » » » » */ 440 /* set is the context» » » » » */
442 /* */ 441 /* */
443 /* The context is supplied to this routine is used for error handling */ 442 /* The context is supplied to this routine is used for error handling */
444 /* (setting of status and traps) and for the rounding mode, only. */ 443 /* (setting of status and traps) and for the rounding mode, only. */
445 /* If an error occurs, the result will be a valid decimal64 NaN. */ 444 /* If an error occurs, the result will be a valid decimal64 NaN. */
446 /* ------------------------------------------------------------------ */ 445 /* ------------------------------------------------------------------ */
447 decimal64 * decimal64FromString(decimal64 *result, const char *string, 446 decimal64 * decimal64FromString(decimal64 *result, const char *string,
448 decContext *set) { 447 decContext *set) {
449 decContext dc; /* work */ 448 decContext dc; /* work */
450 decNumber dn;»» » » /* .. */ 449 decNumber dn; » » » /* .. */
451 450
452 decContextDefault(&dc, DEC_INIT_DECIMAL64); /* no traps, please */ 451 decContextDefault(&dc, DEC_INIT_DECIMAL64); /* no traps, please */
453 dc.round=set->round; /* use supplied rounding */ 452 dc.round=set->round; /* use supplied rounding */
454 453
455 decNumberFromString(&dn, string, &dc); /* will round if needed */ 454 decNumberFromString(&dn, string, &dc); /* will round if needed */
456 455
457 decimal64FromNumber(result, &dn, &dc); 456 decimal64FromNumber(result, &dn, &dc);
458 if (dc.status!=0) { /* something happened */ 457 if (dc.status!=0) { /* something happened */
459 decContextSetStatus(set, dc.status); /* .. pass it on */ 458 decContextSetStatus(set, dc.status); /* .. pass it on */
460 } 459 }
461 return result; 460 return result;
462 } /* decimal64FromString */ 461 } /* decimal64FromString */
463 462
464 /* ------------------------------------------------------------------ */ 463 /* ------------------------------------------------------------------ */
465 /* decimal64IsCanonical -- test whether encoding is canonical */ 464 /* decimal64IsCanonical -- test whether encoding is canonical */
466 /* d64 is the source decimal64 */ 465 /* d64 is the source decimal64 */
467 /* returns 1 if the encoding of d64 is canonical, 0 otherwise» */ 466 /* returns 1 if the encoding of d64 is canonical, 0 otherwise */
468 /* No error is possible. */ 467 /* No error is possible. */
469 /* ------------------------------------------------------------------ */ 468 /* ------------------------------------------------------------------ */
470 uint32_t decimal64IsCanonical(const decimal64 *d64) { 469 uInt decimal64IsCanonical(const decimal64 *d64) {
471 decNumber dn;»» » » /* work */ 470 decNumber dn; » » » /* work */
472 decimal64 canon; /* .. */ 471 decimal64 canon; /* .. */
473 decContext dc; /* .. */ 472 decContext dc; /* .. */
474 decContextDefault(&dc, DEC_INIT_DECIMAL64); 473 decContextDefault(&dc, DEC_INIT_DECIMAL64);
475 decimal64ToNumber(d64, &dn); 474 decimal64ToNumber(d64, &dn);
476 decimal64FromNumber(&canon, &dn, &dc);/* canon will now be canonical */ 475 decimal64FromNumber(&canon, &dn, &dc);/* canon will now be canonical */
477 return memcmp(d64, &canon, DECIMAL64_Bytes)==0; 476 return memcmp(d64, &canon, DECIMAL64_Bytes)==0;
478 } /* decimal64IsCanonical */ 477 } /* decimal64IsCanonical */
479 478
480 /* ------------------------------------------------------------------ */ 479 /* ------------------------------------------------------------------ */
481 /* decimal64Canonical -- copy an encoding, ensuring it is canonical */ 480 /* decimal64Canonical -- copy an encoding, ensuring it is canonical */
482 /* d64 is the source decimal64 */ 481 /* d64 is the source decimal64 */
483 /* result is the target (may be the same decimal64) */ 482 /* result is the target (may be the same decimal64) */
484 /* returns result */ 483 /* returns result */
485 /* No error is possible. */ 484 /* No error is possible. */
486 /* ------------------------------------------------------------------ */ 485 /* ------------------------------------------------------------------ */
487 decimal64 * decimal64Canonical(decimal64 *result, const decimal64 *d64) { 486 decimal64 * decimal64Canonical(decimal64 *result, const decimal64 *d64) {
488 decNumber dn;»» » » /* work */ 487 decNumber dn; » » » /* work */
489 decContext dc; /* .. */ 488 decContext dc; /* .. */
490 decContextDefault(&dc, DEC_INIT_DECIMAL64); 489 decContextDefault(&dc, DEC_INIT_DECIMAL64);
491 decimal64ToNumber(d64, &dn); 490 decimal64ToNumber(d64, &dn);
492 decimal64FromNumber(result, &dn, &dc);/* result will now be canonical */ 491 decimal64FromNumber(result, &dn, &dc);/* result will now be canonical */
493 return result; 492 return result;
494 } /* decimal64Canonical */ 493 } /* decimal64Canonical */
495 494
496 #if DECTRACE || DECCHECK 495 #if DECTRACE || DECCHECK
497 /* Macros for accessing decimal64 fields. These assume the 496 /* Macros for accessing decimal64 fields. These assume the
498 argument is a reference (pointer) to the decimal64 structure, 497 argument is a reference (pointer) to the decimal64 structure,
499 and the decimal64 is in network byte order (big-endian) */ 498 and the decimal64 is in network byte order (big-endian) */
500 /* Get sign */ 499 /* Get sign */
501 #define decimal64Sign(d) ((unsigned)(d)->bytes[0]>>7) 500 #define decimal64Sign(d) ((unsigned)(d)->bytes[0]>>7)
502 501
503 /* Get combination field */ 502 /* Get combination field */
504 #define decimal64Comb(d) (((d)->bytes[0] & 0x7c)>>2) 503 #define decimal64Comb(d) (((d)->bytes[0] & 0x7c)>>2)
505 504
506 /* Get exponent continuation [does not remove bias] */ 505 /* Get exponent continuation [does not remove bias] */
507 #define decimal64ExpCon(d) ((((d)->bytes[0] & 0x03)<<6) \ 506 #define decimal64ExpCon(d) ((((d)->bytes[0] & 0x03)<<6) \
508 | ((unsigned)(d)->bytes[1]>>2)) 507 | ((unsigned)(d)->bytes[1]>>2))
509 508
510 /* Set sign [this assumes sign previously 0] */ 509 /* Set sign [this assumes sign previously 0] */
511 #define decimal64SetSign(d, b) { \ 510 #define decimal64SetSign(d, b) { \
512 (d)->bytes[0]|=((unsigned)(b)<<7);} 511 (d)->bytes[0]|=((unsigned)(b)<<7);}
513 512
514 /* Set exponent continuation [does not apply bias] */ 513 /* Set exponent continuation [does not apply bias] */
515 /* This assumes range has been checked and exponent previously 0; */ 514 /* This assumes range has been checked and exponent previously 0; */
516 /* type of exponent must be unsigned */ 515 /* type of exponent must be unsigned */
517 #define decimal64SetExpCon(d, e) { \ 516 #define decimal64SetExpCon(d, e) { \
518 (d)->bytes[0]|=(uint8_t)((e)>>6);» » » » \ 517 (d)->bytes[0]|=(uByte)((e)>>6);» » » » \
519 (d)->bytes[1]|=(uint8_t)(((e)&0x3F)<<2);} 518 (d)->bytes[1]|=(uByte)(((e)&0x3F)<<2);}
520 519
521 /* ------------------------------------------------------------------ */ 520 /* ------------------------------------------------------------------ */
522 /* decimal64Show -- display a decimal64 in hexadecimal [debug aid] */ 521 /* decimal64Show -- display a decimal64 in hexadecimal [debug aid] */
523 /* d64 -- the number to show */ 522 /* d64 -- the number to show */
524 /* ------------------------------------------------------------------ */ 523 /* ------------------------------------------------------------------ */
525 /* Also shows sign/cob/expconfields extracted */ 524 /* Also shows sign/cob/expconfields extracted */
526 void decimal64Show(const decimal64 *d64) { 525 void decimal64Show(const decimal64 *d64) {
527 char buf[DECIMAL64_Bytes*2+1]; 526 char buf[DECIMAL64_Bytes*2+1];
528 Int i, j=0; 527 Int i, j=0;
529 528
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 2, 2, 2, 2, 2, 2, 2, 2, 578 2, 2, 2, 2, 2, 2, 2, 2,
580 0, 0, 1, 1, 2, 2, 3, 3}; 579 0, 0, 1, 1, 2, 2, 3, 3};
581 const uInt COMBMSD[32]={0, 1, 2, 3, 4, 5, 6, 7, 580 const uInt COMBMSD[32]={0, 1, 2, 3, 4, 5, 6, 7,
582 0, 1, 2, 3, 4, 5, 6, 7, 581 0, 1, 2, 3, 4, 5, 6, 7,
583 0, 1, 2, 3, 4, 5, 6, 7, 582 0, 1, 2, 3, 4, 5, 6, 7,
584 8, 9, 8, 9, 8, 9, 0, 1}; 583 8, 9, 8, 9, 8, 9, 0, 1};
585 584
586 /* ------------------------------------------------------------------ */ 585 /* ------------------------------------------------------------------ */
587 /* decDigitsToDPD -- pack coefficient into DPD form */ 586 /* decDigitsToDPD -- pack coefficient into DPD form */
588 /* */ 587 /* */
589 /* dn» is the source number (assumed valid, max DECMAX754 digits) */ 588 /* dn is the source number (assumed valid, max DECMAX754 digits) */
590 /* targ is 1, 2, or 4-element uInt array, which the caller must */ 589 /* targ is 1, 2, or 4-element uInt array, which the caller must */
591 /*» have cleared to zeros»» » » » */ 590 /*» have cleared to zeros » » » » */
592 /* shift is the number of 0 digits to add on the right (normally 0) */ 591 /* shift is the number of 0 digits to add on the right (normally 0) */
593 /* */ 592 /* */
594 /* The coefficient must be known small enough to fit. The full» */ 593 /* The coefficient must be known small enough to fit. The full */
595 /* coefficient is copied, including the leading 'odd' digit. This */ 594 /* coefficient is copied, including the leading 'odd' digit. This */
596 /* digit is retrieved and packed into the combination field by the */ 595 /* digit is retrieved and packed into the combination field by the */
597 /* caller. */ 596 /* caller. */
598 /* */ 597 /* */
599 /* The target uInts are altered only as necessary to receive the */ 598 /* The target uInts are altered only as necessary to receive the */
600 /* digits of the decNumber. When more than one uInt is needed, they */ 599 /* digits of the decNumber. When more than one uInt is needed, they */
601 /* are filled from left to right (that is, the uInt at offset 0 will */ 600 /* are filled from left to right (that is, the uInt at offset 0 will */
602 /* end up with the least-significant digits). */ 601 /* end up with the least-significant digits). */
603 /* */ 602 /* */
604 /* shift is used for 'fold-down' padding. */ 603 /* shift is used for 'fold-down' padding. */
605 /* */ 604 /* */
606 /* No error is possible. */ 605 /* No error is possible. */
607 /* ------------------------------------------------------------------ */ 606 /* ------------------------------------------------------------------ */
608 #if DECDPUN<=4 607 #if DECDPUN<=4
609 /* Constant multipliers for divide-by-power-of five using reciprocal */ 608 /* Constant multipliers for divide-by-power-of five using reciprocal */
610 /* multiply, after removing powers of 2 by shifting, and final shift */ 609 /* multiply, after removing powers of 2 by shifting, and final shift */
611 /* of 17 [we only need up to **4] */ 610 /* of 17 [we only need up to **4] */
612 static const uInt multies[]={131073, 26215, 5243, 1049, 210}; 611 static const uInt multies[]={131073, 26215, 5243, 1049, 210};
613 /* QUOT10 -- macro to return the quotient of unit u divided by 10**n */ 612 /* QUOT10 -- macro to return the quotient of unit u divided by 10**n */
614 #define QUOT10(u, n) ((((uInt)(u)>>(n))*multies[n])>>17) 613 #define QUOT10(u, n) ((((uInt)(u)>>(n))*multies[n])>>17)
615 #endif 614 #endif
616 void decDigitsToDPD(const decNumber *dn, uInt *targ, Int shift) { 615 void decDigitsToDPD(const decNumber *dn, uInt *targ, Int shift) {
617 Int cut; /* work */ 616 Int cut; /* work */
618 Int n; /* output bunch counter */ 617 Int n; /* output bunch counter */
619 Int digits=dn->digits; /* digit countdown */ 618 Int digits=dn->digits; /* digit countdown */
620 uInt dpd; /* densely packed decimal value */ 619 uInt dpd; /* densely packed decimal value */
621 uInt bin; /* binary value 0-999 */ 620 uInt bin; /* binary value 0-999 */
622 uInt *uout=targ; /* -> current output uInt */ 621 uInt *uout=targ; /* -> current output uInt */
623 uInt» uoff=0;»» /* -> current output offset [from right] */ 622 uInt» uoff=0; » /* -> current output offset [from right] */
624 const Unit *inu=dn->lsu; /* -> current input unit */ 623 const Unit *inu=dn->lsu; /* -> current input unit */
625 Unit uar[DECMAXUNITS]; /* working copy of units, iff shifted */ 624 Unit uar[DECMAXUNITS]; /* working copy of units, iff shifted */
626 #if DECDPUN!=3 /* not fast path */ 625 #if DECDPUN!=3 /* not fast path */
627 Unit in; /* current unit */ 626 Unit in; /* current unit */
628 #endif 627 #endif
629 628
630 if (shift!=0) { /* shift towards most significant required */ 629 if (shift!=0) { /* shift towards most significant required */
631 /* shift the units array to the left by pad digits and copy */ 630 /* shift the units array to the left by pad digits and copy */
632 /* [this code is a special case of decShiftToMost, which could */ 631 /* [this code is a special case of decShiftToMost, which could */
633 /* be used instead if exposed and the array were copied first] */ 632 /* be used instead if exposed and the array were copied first] */
634 const Unit *source;»» » /* .. */ 633 const Unit *source; » » /* .. */
635 Unit *target, *first; /* .. */ 634 Unit *target, *first; /* .. */
636 uInt next=0; /* work */ 635 uInt next=0; /* work */
637 636
638 source=dn->lsu+D2U(digits)-1; /* where msu comes from */ 637 source=dn->lsu+D2U(digits)-1; /* where msu comes from */
639 target=uar+D2U(digits)-1+D2U(shift);/* where upper part of first cut goes */ 638 target=uar+D2U(digits)-1+D2U(shift);/* where upper part of first cut goes */
640 cut=DECDPUN-MSUDIGITS(shift); /* where to slice */ 639 cut=DECDPUN-MSUDIGITS(shift); /* where to slice */
641 if (cut==0) { /* unit-boundary case */ 640 if (cut==0) { /* unit-boundary case */
642 for (; source>=dn->lsu; source--, target--) *target=*source; 641 for (; source>=dn->lsu; source--, target--) *target=*source;
643 } 642 }
644 else { 643 else {
(...skipping 24 matching lines...) Expand all
669 /* now densely pack the coefficient into DPD declets */ 668 /* now densely pack the coefficient into DPD declets */
670 669
671 #if DECDPUN!=3 /* not fast path */ 670 #if DECDPUN!=3 /* not fast path */
672 in=*inu; /* current unit */ 671 in=*inu; /* current unit */
673 cut=0; /* at lowest digit */ 672 cut=0; /* at lowest digit */
674 bin=0; /* [keep compiler quiet] */ 673 bin=0; /* [keep compiler quiet] */
675 #endif 674 #endif
676 675
677 for(n=0; digits>0; n++) { /* each output bunch */ 676 for(n=0; digits>0; n++) { /* each output bunch */
678 #if DECDPUN==3 /* fast path, 3-at-a-time */ 677 #if DECDPUN==3 /* fast path, 3-at-a-time */
679 bin=*inu;»» » /* 3 digits ready for convert */ 678 bin=*inu; » » /* 3 digits ready for convert */
680 digits-=3; /* [may go negative] */ 679 digits-=3; /* [may go negative] */
681 inu++; /* may need another */ 680 inu++; /* may need another */
682 681
683 #else /* must collect digit-by-digit */ 682 #else /* must collect digit-by-digit */
684 Unit dig;»» » /* current digit */ 683 Unit dig; » » /* current digit */
685 Int j; /* digit-in-declet count */ 684 Int j; /* digit-in-declet count */
686 for (j=0; j<3; j++) { 685 for (j=0; j<3; j++) {
687 #if DECDPUN<=4 686 #if DECDPUN<=4
688 Unit temp=(Unit)((uInt)(in*6554)>>16); 687 Unit temp=(Unit)((uInt)(in*6554)>>16);
689 dig=(Unit)(in-X10(temp)); 688 dig=(Unit)(in-X10(temp));
690 in=temp; 689 in=temp;
691 #else 690 #else
692 dig=in%10; 691 dig=in%10;
693 in=in/10; 692 in=in/10;
694 #endif 693 #endif
695 if (j==0) bin=dig; 694 if (j==0) bin=dig;
696 » else if (j==1)» bin+=X10(dig); 695 » else if (j==1) bin+=X10(dig);
697 else /* j==2 */ bin+=X100(dig); 696 else /* j==2 */ bin+=X100(dig);
698 digits--; 697 digits--;
699 if (digits==0) break; /* [also protects *inu below] */ 698 if (digits==0) break; /* [also protects *inu below] */
700 cut++; 699 cut++;
701 if (cut==DECDPUN) {inu++; in=*inu; cut=0;} 700 if (cut==DECDPUN) {inu++; in=*inu; cut=0;}
702 } 701 }
703 #endif 702 #endif
704 /* here there are 3 digits in bin, or have used all input digits */ 703 /* here there are 3 digits in bin, or have used all input digits */
705 704
706 dpd=BIN2DPD[bin]; 705 dpd=BIN2DPD[bin];
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 /* */ 737 /* */
739 /* dn->digits is set, but not the sign or exponent. */ 738 /* dn->digits is set, but not the sign or exponent. */
740 /* No error is possible [the redundant 888 codes are allowed]. */ 739 /* No error is possible [the redundant 888 codes are allowed]. */
741 /* ------------------------------------------------------------------ */ 740 /* ------------------------------------------------------------------ */
742 void decDigitsFromDPD(decNumber *dn, const uInt *sour, Int declets) { 741 void decDigitsFromDPD(decNumber *dn, const uInt *sour, Int declets) {
743 742
744 uInt dpd; /* collector for 10 bits */ 743 uInt dpd; /* collector for 10 bits */
745 Int n; /* counter */ 744 Int n; /* counter */
746 Unit *uout=dn->lsu; /* -> current output unit */ 745 Unit *uout=dn->lsu; /* -> current output unit */
747 Unit *last=uout; /* will be unit containing msd */ 746 Unit *last=uout; /* will be unit containing msd */
748 const uInt *uin=sour;»» /* -> current input uInt */ 747 const uInt *uin=sour; » /* -> current input uInt */
749 uInt» uoff=0;»» » /* -> current input offset [from right] */ 748 uInt» uoff=0; » » /* -> current input offset [from right] */
750 749
751 #if DECDPUN!=3 750 #if DECDPUN!=3
752 uInt bcd; /* BCD result */ 751 uInt bcd; /* BCD result */
753 uInt» nibble;»» » /* work */ 752 uInt» nibble; » » /* work */
754 Unit out=0; /* accumulator */ 753 Unit out=0; /* accumulator */
755 Int cut=0; /* power of ten in current unit */ 754 Int cut=0; /* power of ten in current unit */
756 #endif 755 #endif
757 #if DECDPUN>4 756 #if DECDPUN>4
758 uInt const *pow; /* work */ 757 uInt const *pow; /* work */
759 #endif 758 #endif
760 759
761 /* Expand the densely-packed integer, right to left */ 760 /* Expand the densely-packed integer, right to left */
762 for (n=declets-1; n>=0; n--) { /* count down declets of 10 bits */ 761 for (n=declets-1; n>=0; n--) { /* count down declets of 10 bits */
763 dpd=*uin>>uoff; 762 dpd=*uin>>uoff;
764 uoff+=10; 763 uoff+=10;
765 if (uoff>32) { /* crossed uInt boundary */ 764 if (uoff>32) { /* crossed uInt boundary */
766 uin++; 765 uin++;
767 uoff-=32; 766 uoff-=32;
768 dpd|=*uin<<(10-uoff); /* get waiting bits */ 767 dpd|=*uin<<(10-uoff); /* get waiting bits */
769 } 768 }
770 dpd&=0x3ff;»» » /* clear uninteresting bits */ 769 dpd&=0x3ff; » » /* clear uninteresting bits */
771 770
772 #if DECDPUN==3 771 #if DECDPUN==3
773 if (dpd==0) *uout=0; 772 if (dpd==0) *uout=0;
774 else { 773 else {
775 *uout=DPD2BIN[dpd]; /* convert 10 bits to binary 0-999 */ 774 *uout=DPD2BIN[dpd]; /* convert 10 bits to binary 0-999 */
776 last=uout; /* record most significant unit */ 775 last=uout; /* record most significant unit */
777 } 776 }
778 uout++; 777 uout++;
779 } /* n */ 778 } /* n */
780 779
(...skipping 29 matching lines...) Expand all
810 if (nibble) out=(Unit)(out+nibble*DECPOWERS[cut]); 809 if (nibble) out=(Unit)(out+nibble*DECPOWERS[cut]);
811 cut++; 810 cut++;
812 if (cut==DECDPUN) {*uout=out; if (out) {last=uout; out=0;} uout++; cut=0;} 811 if (cut==DECDPUN) {*uout=out; if (out) {last=uout; out=0;} uout++; cut=0;}
813 bcd>>=4; 812 bcd>>=4;
814 813
815 nibble=bcd & 0x00f; 814 nibble=bcd & 0x00f;
816 if (nibble) out=(Unit)(out+nibble*DECPOWERS[cut]); 815 if (nibble) out=(Unit)(out+nibble*DECPOWERS[cut]);
817 cut++; 816 cut++;
818 if (cut==DECDPUN) {*uout=out; if (out) {last=uout; out=0;} uout++; cut=0;} 817 if (cut==DECDPUN) {*uout=out; if (out) {last=uout; out=0;} uout++; cut=0;}
819 } /* n */ 818 } /* n */
820 if (cut!=0) {»» » » /* some more left over */ 819 if (cut!=0) { » » » /* some more left over */
821 *uout=out; /* write out final unit */ 820 *uout=out; /* write out final unit */
822 if (out) last=uout;»» » /* and note if non-zero */ 821 if (out) last=uout; » » /* and note if non-zero */
823 } 822 }
824 #endif 823 #endif
825 824
826 /* here, last points to the most significant unit with digits; */ 825 /* here, last points to the most significant unit with digits; */
827 /* inspect it to get the final digits count -- this is essentially */ 826 /* inspect it to get the final digits count -- this is essentially */
828 /* the same code as decGetDigits in decNumber.c */ 827 /* the same code as decGetDigits in decNumber.c */
829 dn->digits=(last-dn->lsu)*DECDPUN+1; /* floor of digits, plus */ 828 dn->digits=(last-dn->lsu)*DECDPUN+1; /* floor of digits, plus */
830 /* must be at least 1 digit */ 829 /* must be at least 1 digit */
831 #if DECDPUN>1 830 #if DECDPUN>1
832 if (*last<10) return;»» » /* common odd digit or 0 */ 831 if (*last<10) return; » » /* common odd digit or 0 */
833 dn->digits++;»» » » /* must be 2 at least */ 832 dn->digits++; » » » /* must be 2 at least */
834 #if DECDPUN>2 833 #if DECDPUN>2
835 if (*last<100) return; /* 10-99 */ 834 if (*last<100) return; /* 10-99 */
836 dn->digits++;»» » » /* must be 3 at least */ 835 dn->digits++; » » » /* must be 3 at least */
837 #if DECDPUN>3 836 #if DECDPUN>3
838 if (*last<1000) return; /* 100-999 */ 837 if (*last<1000) return; /* 100-999 */
839 dn->digits++;»» » » /* must be 4 at least */ 838 dn->digits++; » » » /* must be 4 at least */
840 #if DECDPUN>4 839 #if DECDPUN>4
841 for (pow=&DECPOWERS[4]; *last>=*pow; pow++) dn->digits++; 840 for (pow=&DECPOWERS[4]; *last>=*pow; pow++) dn->digits++;
842 #endif 841 #endif
843 #endif 842 #endif
844 #endif 843 #endif
845 #endif 844 #endif
846 return; 845 return;
847 } /*decDigitsFromDPD */ 846 } /*decDigitsFromDPD */
OLDNEW
« no previous file with comments | « gcc/libdecnumber/dpd/decimal32.c ('k') | gcc/libgcc/Makefile.in » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698