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

Side by Side Diff: gcc/libdecnumber/dpd/decimal32.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/decimal128.c ('k') | gcc/libdecnumber/dpd/decimal64.c » ('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 32-bit format module for the decNumber C Library. 1 /* Decimal 32-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 32-bit format module»» » » » */ 27 /* Decimal 32-bit format module » » » » */
28 /* ------------------------------------------------------------------ */ 28 /* ------------------------------------------------------------------ */
29 /* This module comprises the routines for decimal32 format numbers. */ 29 /* This module comprises the routines for decimal32 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 7 /* make decNumbers with space for 7 */ 41 #define DECNUMDIGITS 7 /* make decNumbers with space for 7 */
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 "decimal32.h" /* our primary include */ 44 #include "decimal32.h" /* our primary include */
45 45
46 /* Utility tables and routines [in decimal64.c] */ 46 /* Utility tables and routines [in decimal64.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
52 extern void decDigitsToDPD(const decNumber *, uInt *, Int); 52 extern void decDigitsToDPD(const decNumber *, uInt *, Int);
53 extern void decDigitsFromDPD(decNumber *, const uInt *, Int); 53 extern void decDigitsFromDPD(decNumber *, const uInt *, Int);
54 54
55 #if DECTRACE || DECCHECK 55 #if DECTRACE || DECCHECK
56 void decimal32Show(const decimal32 *); /* for debug */ 56 void decimal32Show(const decimal32 *); /* for debug */
57 extern void decNumberShow(const decNumber *); /* .. */ 57 extern void decNumberShow(const decNumber *); /* .. */
58 #endif 58 #endif
59 59
60 /* Useful macro */ 60 /* Useful macro */
61 /* Clear a structure (e.g., a decNumber) */ 61 /* Clear a structure (e.g., a decNumber) */
62 #define DEC_clear(d) memset(d, 0, sizeof(*d)) 62 #define DEC_clear(d) memset(d, 0, sizeof(*d))
63 63
64 /* ------------------------------------------------------------------ */ 64 /* ------------------------------------------------------------------ */
65 /* decimal32FromNumber -- convert decNumber to decimal32 */ 65 /* decimal32FromNumber -- convert decNumber to decimal32 */
66 /* */ 66 /* */
67 /* ds is the target decimal32»» » » » */ 67 /* ds is the target decimal32 » » » » */
68 /* dn is the source number (assumed valid) */ 68 /* dn is the source number (assumed valid) */
69 /* set is the context, used only for reporting errors»» */ 69 /* set is the context, used only for reporting errors » */
70 /* */ 70 /* */
71 /* The set argument is used only for status reporting and for the */ 71 /* The set argument is used only for status reporting and for the */
72 /* rounding mode (used if the coefficient is more than DECIMAL32_Pmax */ 72 /* rounding mode (used if the coefficient is more than DECIMAL32_Pmax */
73 /* digits or an overflow is detected). If the exponent is out of the */ 73 /* digits or an overflow is detected). If the exponent is out of the */
74 /* valid range then Overflow or Underflow will be raised. */ 74 /* valid range then Overflow or Underflow will be raised. */
75 /* After Underflow a subnormal result is possible. */ 75 /* After Underflow a subnormal result is possible. */
76 /* */ 76 /* */
77 /* DEC_Clamped is set if the number has to be 'folded down' to fit, */ 77 /* DEC_Clamped is set if the number has to be 'folded down' to fit, */
78 /* by reducing its exponent and multiplying the coefficient by a */ 78 /* by reducing its exponent and multiplying the coefficient by a */
79 /* power of ten, or if the exponent on a zero had to be clamped. */ 79 /* power of ten, or if the exponent on a zero had to be clamped. */
80 /* ------------------------------------------------------------------ */ 80 /* ------------------------------------------------------------------ */
81 decimal32 * decimal32FromNumber(decimal32 *d32, const decNumber *dn, 81 decimal32 * decimal32FromNumber(decimal32 *d32, const decNumber *dn,
82 decContext *set) { 82 decContext *set) {
83 uInt status=0; /* status accumulator */ 83 uInt status=0; /* status accumulator */
84 Int ae; /* adjusted exponent */ 84 Int ae; /* adjusted exponent */
85 decNumber dw; /* work */ 85 decNumber dw; /* work */
86 decContext dc; /* .. */ 86 decContext dc; /* .. */
87 uInt *pu; /* .. */
88 uInt comb, exp; /* .. */ 87 uInt comb, exp; /* .. */
88 uInt uiwork; /* for macros */
89 uInt targ=0; /* target 32-bit */ 89 uInt targ=0; /* target 32-bit */
90 90
91 /* If the number has too many digits, or the exponent could be */ 91 /* If the number has too many digits, or the exponent could be */
92 /* out of range then reduce the number under the appropriate */ 92 /* out of range then reduce the number under the appropriate */
93 /* constraints. This could push the number to Infinity or zero, */ 93 /* constraints. This could push the number to Infinity or zero, */
94 /* so this check and rounding must be done before generating the */ 94 /* so this check and rounding must be done before generating the */
95 /* decimal32] */ 95 /* decimal32] */
96 ae=dn->exponent+dn->digits-1;»» /* [0 if special] */ 96 ae=dn->exponent+dn->digits-1; » /* [0 if special] */
97 if (dn->digits>DECIMAL32_Pmax»» /* too many digits */ 97 if (dn->digits>DECIMAL32_Pmax » /* too many digits */
98 || ae>DECIMAL32_Emax»» » /* likely overflow */ 98 || ae>DECIMAL32_Emax » » /* likely overflow */
99 || ae<DECIMAL32_Emin) { /* likely underflow */ 99 || ae<DECIMAL32_Emin) { /* likely underflow */
100 decContextDefault(&dc, DEC_INIT_DECIMAL32); /* [no traps] */ 100 decContextDefault(&dc, DEC_INIT_DECIMAL32); /* [no traps] */
101 dc.round=set->round; /* use supplied rounding */ 101 dc.round=set->round; /* use supplied rounding */
102 decNumberPlus(&dw, dn, &dc); /* (round and check) */ 102 decNumberPlus(&dw, dn, &dc); /* (round and check) */
103 /* [this changes -0 to 0, so enforce the sign...] */ 103 /* [this changes -0 to 0, so enforce the sign...] */
104 dw.bits|=dn->bits&DECNEG; 104 dw.bits|=dn->bits&DECNEG;
105 status=dc.status; /* save status */ 105 status=dc.status; /* save status */
106 dn=&dw; /* use the work number */ 106 dn=&dw; /* use the work number */
107 } /* maybe out of range */ 107 } /* maybe out of range */
108 108
109 if (dn->bits&DECSPECIAL) { /* a special value */ 109 if (dn->bits&DECSPECIAL) { /* a special value */
110 if (dn->bits&DECINF) targ=DECIMAL_Inf<<24; 110 if (dn->bits&DECINF) targ=DECIMAL_Inf<<24;
111 else { /* sNaN or qNaN */ 111 else { /* sNaN or qNaN */
112 if ((*dn->lsu!=0 || dn->digits>1)»» /* non-zero coefficient */ 112 if ((*dn->lsu!=0 || dn->digits>1) » /* non-zero coefficient */
113 && (dn->digits<DECIMAL32_Pmax)) { /* coefficient fits */ 113 && (dn->digits<DECIMAL32_Pmax)) { /* coefficient fits */
114 decDigitsToDPD(dn, &targ, 0); 114 decDigitsToDPD(dn, &targ, 0);
115 } 115 }
116 if (dn->bits&DECNAN) targ|=DECIMAL_NaN<<24; 116 if (dn->bits&DECNAN) targ|=DECIMAL_NaN<<24;
117 else targ|=DECIMAL_sNaN<<24; 117 else targ|=DECIMAL_sNaN<<24;
118 } /* a NaN */ 118 } /* a NaN */
119 } /* special */ 119 } /* special */
120 120
121 else { /* is finite */ 121 else { /* is finite */
122 if (decNumberIsZero(dn)) { /* is a zero */ 122 if (decNumberIsZero(dn)) { /* is a zero */
123 /* set and clamp exponent */ 123 /* set and clamp exponent */
124 if (dn->exponent<-DECIMAL32_Bias) { 124 if (dn->exponent<-DECIMAL32_Bias) {
125 exp=0; /* low clamp */ 125 exp=0; /* low clamp */
126 status|=DEC_Clamped; 126 status|=DEC_Clamped;
127 } 127 }
128 else { 128 else {
129 exp=dn->exponent+DECIMAL32_Bias; /* bias exponent */ 129 exp=dn->exponent+DECIMAL32_Bias; /* bias exponent */
130 if (exp>DECIMAL32_Ehigh) { /* top clamp */ 130 if (exp>DECIMAL32_Ehigh) { /* top clamp */
131 exp=DECIMAL32_Ehigh; 131 exp=DECIMAL32_Ehigh;
132 status|=DEC_Clamped; 132 status|=DEC_Clamped;
133 } 133 }
134 } 134 }
135 comb=(exp>>3) & 0x18; /* msd=0, exp top 2 bits .. */ 135 comb=(exp>>3) & 0x18; /* msd=0, exp top 2 bits .. */
136 } 136 }
137 else { /* non-zero finite number */ 137 else { /* non-zero finite number */
138 uInt msd;»» » » /* work */ 138 uInt msd; » » » /* work */
139 Int pad=0; /* coefficient pad digits */ 139 Int pad=0; /* coefficient pad digits */
140 140
141 /* the dn is known to fit, but it may need to be padded */ 141 /* the dn is known to fit, but it may need to be padded */
142 exp=(uInt)(dn->exponent+DECIMAL32_Bias); /* bias exponent */ 142 exp=(uInt)(dn->exponent+DECIMAL32_Bias); /* bias exponent */
143 if (exp>DECIMAL32_Ehigh) { /* fold-down case */ 143 if (exp>DECIMAL32_Ehigh) { /* fold-down case */
144 pad=exp-DECIMAL32_Ehigh; 144 pad=exp-DECIMAL32_Ehigh;
145 exp=DECIMAL32_Ehigh; /* [to maximum] */ 145 exp=DECIMAL32_Ehigh; /* [to maximum] */
146 status|=DEC_Clamped; 146 status|=DEC_Clamped;
147 } 147 }
148 148
(...skipping 14 matching lines...) Expand all
163 if (msd>=8) comb=0x18 | ((exp>>5) & 0x06) | (msd & 0x01); 163 if (msd>=8) comb=0x18 | ((exp>>5) & 0x06) | (msd & 0x01);
164 else comb=((exp>>3) & 0x18) | msd; 164 else comb=((exp>>3) & 0x18) | msd;
165 } 165 }
166 targ|=comb<<26; /* add combination field .. */ 166 targ|=comb<<26; /* add combination field .. */
167 targ|=(exp&0x3f)<<20; /* .. and exponent continuation */ 167 targ|=(exp&0x3f)<<20; /* .. and exponent continuation */
168 } /* finite */ 168 } /* finite */
169 169
170 if (dn->bits&DECNEG) targ|=0x80000000; /* add sign bit */ 170 if (dn->bits&DECNEG) targ|=0x80000000; /* add sign bit */
171 171
172 /* now write to storage; this is endian */ 172 /* now write to storage; this is endian */
173 pu=(uInt *)d32->bytes;» /* overlay */ 173 UBFROMUI(d32->bytes, targ);» /* directly store the int */
174 *pu=targ;» » » /* directly store the int */
175 174
176 if (status!=0) decContextSetStatus(set, status); /* pass on status */ 175 if (status!=0) decContextSetStatus(set, status); /* pass on status */
177 /* decimal32Show(d32); */ 176 /* decimal32Show(d32); */
178 return d32; 177 return d32;
179 } /* decimal32FromNumber */ 178 } /* decimal32FromNumber */
180 179
181 /* ------------------------------------------------------------------ */ 180 /* ------------------------------------------------------------------ */
182 /* decimal32ToNumber -- convert decimal32 to decNumber */ 181 /* decimal32ToNumber -- convert decimal32 to decNumber */
183 /* d32 is the source decimal32 */ 182 /* d32 is the source decimal32 */
184 /* dn is the target number, with appropriate space */ 183 /* dn is the target number, with appropriate space */
185 /* No error is possible. */ 184 /* No error is possible. */
186 /* ------------------------------------------------------------------ */ 185 /* ------------------------------------------------------------------ */
187 decNumber * decimal32ToNumber(const decimal32 *d32, decNumber *dn) { 186 decNumber * decimal32ToNumber(const decimal32 *d32, decNumber *dn) {
188 uInt msd; /* coefficient MSD */ 187 uInt msd; /* coefficient MSD */
189 uInt exp; /* exponent top two bits */ 188 uInt exp; /* exponent top two bits */
190 uInt comb; /* combination field */ 189 uInt comb; /* combination field */
191 uInt sour; /* source 32-bit */ 190 uInt sour; /* source 32-bit */
192 const uInt *pu;» » /* work */ 191 uInt uiwork;» » » /* for macros */
193 192
194 /* load source from storage; this is endian */ 193 /* load source from storage; this is endian */
195 pu=(const uInt *)d32->bytes;» /* overlay */ 194 sour=UBTOUI(d32->bytes);» /* directly load the int */
196 sour=*pu;» » » /* directly load the int */
197 195
198 comb=(sour>>26)&0x1f;»» /* combination field */ 196 comb=(sour>>26)&0x1f; » /* combination field */
199 197
200 decNumberZero(dn); /* clean number */ 198 decNumberZero(dn); /* clean number */
201 if (sour&0x80000000) dn->bits=DECNEG; /* set sign if negative */ 199 if (sour&0x80000000) dn->bits=DECNEG; /* set sign if negative */
202 200
203 msd=COMBMSD[comb]; /* decode the combination field */ 201 msd=COMBMSD[comb]; /* decode the combination field */
204 exp=COMBEXP[comb]; /* .. */ 202 exp=COMBEXP[comb]; /* .. */
205 203
206 if (exp==3) {»» » /* is a special */ 204 if (exp==3) { » » /* is a special */
207 if (msd==0) { 205 if (msd==0) {
208 dn->bits|=DECINF; 206 dn->bits|=DECINF;
209 return dn; /* no coefficient needed */ 207 return dn; /* no coefficient needed */
210 } 208 }
211 else if (sour&0x02000000) dn->bits|=DECSNAN; 209 else if (sour&0x02000000) dn->bits|=DECSNAN;
212 else dn->bits|=DECNAN; 210 else dn->bits|=DECNAN;
213 msd=0; /* no top digit */ 211 msd=0; /* no top digit */
214 } 212 }
215 else { /* is a finite number */ 213 else { /* is a finite number */
216 dn->exponent=(exp<<6)+((sour>>20)&0x3f)-DECIMAL32_Bias; /* unbiased */ 214 dn->exponent=(exp<<6)+((sour>>20)&0x3f)-DECIMAL32_Bias; /* unbiased */
217 } 215 }
218 216
219 /* get the coefficient */ 217 /* get the coefficient */
220 sour&=0x000fffff; /* clean coefficient continuation */ 218 sour&=0x000fffff; /* clean coefficient continuation */
221 if (msd) { /* non-zero msd */ 219 if (msd) { /* non-zero msd */
222 sour|=msd<<20; /* prefix to coefficient */ 220 sour|=msd<<20; /* prefix to coefficient */
223 decDigitsFromDPD(dn, &sour, 3); /* process 3 declets */ 221 decDigitsFromDPD(dn, &sour, 3); /* process 3 declets */
224 return dn; 222 return dn;
225 } 223 }
226 /* msd=0 */ 224 /* msd=0 */
227 if (!sour) return dn;»» /* easy: coefficient is 0 */ 225 if (!sour) return dn; » /* easy: coefficient is 0 */
228 if (sour&0x000ffc00) /* need 2 declets? */ 226 if (sour&0x000ffc00) /* need 2 declets? */
229 decDigitsFromDPD(dn, &sour, 2); /* process 2 declets */ 227 decDigitsFromDPD(dn, &sour, 2); /* process 2 declets */
230 else 228 else
231 decDigitsFromDPD(dn, &sour, 1); /* process 1 declet */ 229 decDigitsFromDPD(dn, &sour, 1); /* process 1 declet */
232 return dn; 230 return dn;
233 } /* decimal32ToNumber */ 231 } /* decimal32ToNumber */
234 232
235 /* ------------------------------------------------------------------ */ 233 /* ------------------------------------------------------------------ */
236 /* to-scientific-string -- conversion to numeric string»» */ 234 /* to-scientific-string -- conversion to numeric string » */
237 /* to-engineering-string -- conversion to numeric string */ 235 /* to-engineering-string -- conversion to numeric string */
238 /* */ 236 /* */
239 /* decimal32ToString(d32, string); */ 237 /* decimal32ToString(d32, string); */
240 /* decimal32ToEngString(d32, string);»» » » */ 238 /* decimal32ToEngString(d32, string); » » » */
241 /* */ 239 /* */
242 /* d32 is the decimal32 format number to convert */ 240 /* d32 is the decimal32 format number to convert */
243 /* string is the string where the result will be laid out */ 241 /* string is the string where the result will be laid out */
244 /* */ 242 /* */
245 /* string must be at least 24 characters */ 243 /* string must be at least 24 characters */
246 /* */ 244 /* */
247 /* No error is possible, and no status can be set. */ 245 /* No error is possible, and no status can be set. */
248 /* ------------------------------------------------------------------ */ 246 /* ------------------------------------------------------------------ */
249 char * decimal32ToEngString(const decimal32 *d32, char *string){ 247 char * decimal32ToEngString(const decimal32 *d32, char *string){
250 decNumber dn;»» » » /* work */ 248 decNumber dn; » » » /* work */
251 decimal32ToNumber(d32, &dn); 249 decimal32ToNumber(d32, &dn);
252 decNumberToEngString(&dn, string); 250 decNumberToEngString(&dn, string);
253 return string; 251 return string;
254 } /* decimal32ToEngString */ 252 } /* decimal32ToEngString */
255 253
256 char * decimal32ToString(const decimal32 *d32, char *string){ 254 char * decimal32ToString(const decimal32 *d32, char *string){
257 uInt msd; /* coefficient MSD */ 255 uInt msd; /* coefficient MSD */
258 Int exp; /* exponent top two bits or full */ 256 Int exp; /* exponent top two bits or full */
259 uInt comb; /* combination field */ 257 uInt comb; /* combination field */
260 char *cstart;»» » /* coefficient start */ 258 char *cstart; » » /* coefficient start */
261 char *c; /* output pointer in string */ 259 char *c; /* output pointer in string */
262 const uInt *pu;» » /* work */ 260 const uByte *u;» » /* work */
263 const uByte *u;» » /* .. */
264 char *s, *t; /* .. (source, target) */ 261 char *s, *t; /* .. (source, target) */
265 Int dpd; /* .. */ 262 Int dpd; /* .. */
266 Int pre, e; /* .. */ 263 Int pre, e; /* .. */
264 uInt uiwork; /* for macros */
267 uInt sour; /* source 32-bit */ 265 uInt sour; /* source 32-bit */
268 266
269 /* load source from storage; this is endian */ 267 /* load source from storage; this is endian */
270 pu=(const uInt *)d32->bytes;» /* overlay */ 268 sour=UBTOUI(d32->bytes);» /* directly load the int */
271 sour=*pu;» » » /* directly load the int */
272 269
273 c=string; /* where result will go */ 270 c=string; /* where result will go */
274 if (((Int)sour)<0) *c++='-'; /* handle sign */ 271 if (((Int)sour)<0) *c++='-'; /* handle sign */
275 272
276 comb=(sour>>26)&0x1f;»» /* combination field */ 273 comb=(sour>>26)&0x1f; » /* combination field */
277 msd=COMBMSD[comb]; /* decode the combination field */ 274 msd=COMBMSD[comb]; /* decode the combination field */
278 exp=COMBEXP[comb]; /* .. */ 275 exp=COMBEXP[comb]; /* .. */
279 276
280 if (exp==3) { 277 if (exp==3) {
281 if (msd==0) { /* infinity */ 278 if (msd==0) { /* infinity */
282 strcpy(c,» "Inf"); 279 strcpy(c, "Inf");
283 strcpy(c+3, "inity"); 280 strcpy(c+3, "inity");
284 return string; /* easy */ 281 return string; /* easy */
285 } 282 }
286 if (sour&0x02000000) *c++='s'; /* sNaN */ 283 if (sour&0x02000000) *c++='s'; /* sNaN */
287 strcpy(c, "NaN"); /* complete word */ 284 strcpy(c, "NaN"); /* complete word */
288 c+=3; /* step past */ 285 c+=3; /* step past */
289 if ((sour&0x000fffff)==0) return string; /* zero payload */ 286 if ((sour&0x000fffff)==0) return string; /* zero payload */
290 /* otherwise drop through to add integer; set correct exp */ 287 /* otherwise drop through to add integer; set correct exp */
291 exp=0; msd=0; /* setup for following code */ 288 exp=0; msd=0; /* setup for following code */
292 } 289 }
293 else exp=(exp<<6)+((sour>>20)&0x3f)-DECIMAL32_Bias; /* unbiased */ 290 else exp=(exp<<6)+((sour>>20)&0x3f)-DECIMAL32_Bias; /* unbiased */
294 291
295 /* convert 7 digits of significand to characters */ 292 /* convert 7 digits of significand to characters */
296 cstart=c; /* save start of coefficient */ 293 cstart=c; /* save start of coefficient */
297 if (msd) *c++='0'+(char)msd; /* non-zero most significant digit */ 294 if (msd) *c++='0'+(char)msd; /* non-zero most significant digit */
298 295
299 /* Now decode the declets. After extracting each one, it is */ 296 /* Now decode the declets. After extracting each one, it is */
300 /* decoded to binary and then to a 4-char sequence by table lookup; */ 297 /* decoded to binary and then to a 4-char sequence by table lookup; */
301 /* the 4-chars are a 1-char length (significant digits, except 000 */ 298 /* the 4-chars are a 1-char length (significant digits, except 000 */
302 /* has length 0). This allows us to left-align the first declet */ 299 /* has length 0). This allows us to left-align the first declet */
303 /* with non-zero content, then remaining ones are full 3-char */ 300 /* with non-zero content, then remaining ones are full 3-char */
304 /* length. We use fixed-length memcpys because variable-length */ 301 /* length. We use fixed-length memcpys because variable-length */
305 /* causes a subroutine call in GCC. (These are length 4 for speed */ 302 /* causes a subroutine call in GCC. (These are length 4 for speed */
306 /* and are safe because the array has an extra terminator byte.) */ 303 /* and are safe because the array has an extra terminator byte.) */
307 #define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4];»» » \ 304 #define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; » » \
308 if (c!=cstart) {memcpy(c, u+1, 4); c+=3;} \ 305 if (c!=cstart) {memcpy(c, u+1, 4); c+=3;} \
309 else if (*u) {memcpy(c, u+4-*u, 4); c+=*u;} 306 else if (*u) {memcpy(c, u+4-*u, 4); c+=*u;}
310 307
311 dpd=(sour>>10)&0x3ff;»» /* declet 1 */ 308 dpd=(sour>>10)&0x3ff; » /* declet 1 */
312 dpd2char; 309 dpd2char;
313 dpd=(sour)&0x3ff; /* declet 2 */ 310 dpd=(sour)&0x3ff; /* declet 2 */
314 dpd2char; 311 dpd2char;
315 312
316 if (c==cstart) *c++='0'; /* all zeros -- make 0 */ 313 if (c==cstart) *c++='0'; /* all zeros -- make 0 */
317 314
318 if (exp==0) {»» » /* integer or NaN case -- easy */ 315 if (exp==0) { » » /* integer or NaN case -- easy */
319 *c='\0'; /* terminate */ 316 *c='\0'; /* terminate */
320 return string; 317 return string;
321 } 318 }
322 319
323 /* non-0 exponent */ 320 /* non-0 exponent */
324 e=0; /* assume no E */ 321 e=0; /* assume no E */
325 pre=c-cstart+exp; 322 pre=c-cstart+exp;
326 /* [here, pre-exp is the digits count (==1 for zero)] */ 323 /* [here, pre-exp is the digits count (==1 for zero)] */
327 if (exp>0 || pre<-5) { /* need exponential form */ 324 if (exp>0 || pre<-5) { /* need exponential form */
328 e=pre-1; /* calculate E value */ 325 e=pre-1; /* calculate E value */
329 pre=1; /* assume one digit before '.' */ 326 pre=1; /* assume one digit before '.' */
330 } /* exponential form */ 327 } /* exponential form */
331 328
332 /* modify the coefficient, adding 0s, '.', and E+nn as needed */ 329 /* modify the coefficient, adding 0s, '.', and E+nn as needed */
333 s=c-1; /* source (LSD) */ 330 s=c-1; /* source (LSD) */
334 if (pre>0) { /* ddd.ddd (plain), perhaps with E */ 331 if (pre>0) { /* ddd.ddd (plain), perhaps with E */
335 char *dotat=cstart+pre; 332 char *dotat=cstart+pre;
336 if (dotat<c) { /* if embedded dot needed... */ 333 if (dotat<c) { /* if embedded dot needed... */
337 t=c; /* target */ 334 t=c; /* target */
338 for (; s>=dotat; s--, t--) *t=*s; /* open the gap; leave t at gap */ 335 for (; s>=dotat; s--, t--) *t=*s; /* open the gap; leave t at gap */
339 *t='.'; /* insert the dot */ 336 *t='.'; /* insert the dot */
340 c++; /* length increased by one */ 337 c++; /* length increased by one */
341 } 338 }
342 339
343 /* finally add the E-part, if needed; it will never be 0, and has */ 340 /* finally add the E-part, if needed; it will never be 0, and has */
344 /* a maximum length of 3 digits (E-101 case) */ 341 /* a maximum length of 3 digits (E-101 case) */
345 if (e!=0) { 342 if (e!=0) {
346 *c++='E';»» » /* starts with E */ 343 *c++='E'; » » /* starts with E */
347 *c++='+';»» » /* assume positive */ 344 *c++='+'; » » /* assume positive */
348 if (e<0) { 345 if (e<0) {
349 *(c-1)='-'; /* oops, need '-' */ 346 *(c-1)='-'; /* oops, need '-' */
350 e=-e; /* uInt, please */ 347 e=-e; /* uInt, please */
351 } 348 }
352 u=&BIN2CHAR[e*4];»» /* -> length byte */ 349 u=&BIN2CHAR[e*4]; » /* -> length byte */
353 memcpy(c, u+4-*u, 4); /* copy fixed 4 characters [is safe] */ 350 memcpy(c, u+4-*u, 4); /* copy fixed 4 characters [is safe] */
354 c+=*u; /* bump pointer appropriately */ 351 c+=*u; /* bump pointer appropriately */
355 } 352 }
356 *c='\0'; /* add terminator */ 353 *c='\0'; /* add terminator */
357 /*printf("res %s\n", string); */ 354 /*printf("res %s\n", string); */
358 return string; 355 return string;
359 } /* pre>0 */ 356 } /* pre>0 */
360 357
361 /* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (can never have E) */ 358 /* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (can never have E) */
362 t=c+1-pre; 359 t=c+1-pre;
363 *(t+1)='\0'; /* can add terminator now */ 360 *(t+1)='\0'; /* can add terminator now */
364 for (; s>=cstart; s--, t--) *t=*s; /* shift whole coefficient right */ 361 for (; s>=cstart; s--, t--) *t=*s; /* shift whole coefficient right */
365 c=cstart; 362 c=cstart;
366 *c++='0'; /* always starts with 0. */ 363 *c++='0'; /* always starts with 0. */
367 *c++='.'; 364 *c++='.';
368 for (; pre<0; pre++) *c++='0'; /* add any 0's after '.' */ 365 for (; pre<0; pre++) *c++='0'; /* add any 0's after '.' */
369 /*printf("res %s\n", string); */ 366 /*printf("res %s\n", string); */
370 return string; 367 return string;
371 } /* decimal32ToString */ 368 } /* decimal32ToString */
372 369
373 /* ------------------------------------------------------------------ */ 370 /* ------------------------------------------------------------------ */
374 /* to-number -- conversion from numeric string */ 371 /* to-number -- conversion from numeric string */
375 /* */ 372 /* */
376 /* decimal32FromString(result, string, set); */ 373 /* decimal32FromString(result, string, set); */
377 /* */ 374 /* */
378 /* result is the decimal32 format number which gets the result of */ 375 /* result is the decimal32 format number which gets the result of */
379 /* the conversion */ 376 /* the conversion */
380 /* *string is the character string which should contain a valid */ 377 /* *string is the character string which should contain a valid */
381 /* number (which may be a special value) */ 378 /* number (which may be a special value) */
382 /* set» is the context» » » » » */ 379 /* set is the context» » » » » */
383 /* */ 380 /* */
384 /* The context is supplied to this routine is used for error handling */ 381 /* The context is supplied to this routine is used for error handling */
385 /* (setting of status and traps) and for the rounding mode, only. */ 382 /* (setting of status and traps) and for the rounding mode, only. */
386 /* If an error occurs, the result will be a valid decimal32 NaN. */ 383 /* If an error occurs, the result will be a valid decimal32 NaN. */
387 /* ------------------------------------------------------------------ */ 384 /* ------------------------------------------------------------------ */
388 decimal32 * decimal32FromString(decimal32 *result, const char *string, 385 decimal32 * decimal32FromString(decimal32 *result, const char *string,
389 decContext *set) { 386 decContext *set) {
390 decContext dc; /* work */ 387 decContext dc; /* work */
391 decNumber dn;»» » » /* .. */ 388 decNumber dn; » » » /* .. */
392 389
393 decContextDefault(&dc, DEC_INIT_DECIMAL32); /* no traps, please */ 390 decContextDefault(&dc, DEC_INIT_DECIMAL32); /* no traps, please */
394 dc.round=set->round; /* use supplied rounding */ 391 dc.round=set->round; /* use supplied rounding */
395 392
396 decNumberFromString(&dn, string, &dc); /* will round if needed */ 393 decNumberFromString(&dn, string, &dc); /* will round if needed */
397 decimal32FromNumber(result, &dn, &dc); 394 decimal32FromNumber(result, &dn, &dc);
398 if (dc.status!=0) { /* something happened */ 395 if (dc.status!=0) { /* something happened */
399 decContextSetStatus(set, dc.status); /* .. pass it on */ 396 decContextSetStatus(set, dc.status); /* .. pass it on */
400 } 397 }
401 return result; 398 return result;
402 } /* decimal32FromString */ 399 } /* decimal32FromString */
403 400
404 /* ------------------------------------------------------------------ */ 401 /* ------------------------------------------------------------------ */
405 /* decimal32IsCanonical -- test whether encoding is canonical */ 402 /* decimal32IsCanonical -- test whether encoding is canonical */
406 /* d32 is the source decimal32 */ 403 /* d32 is the source decimal32 */
407 /* returns 1 if the encoding of d32 is canonical, 0 otherwise» */ 404 /* returns 1 if the encoding of d32 is canonical, 0 otherwise */
408 /* No error is possible. */ 405 /* No error is possible. */
409 /* ------------------------------------------------------------------ */ 406 /* ------------------------------------------------------------------ */
410 uint32_t decimal32IsCanonical(const decimal32 *d32) { 407 uInt decimal32IsCanonical(const decimal32 *d32) {
411 decNumber dn;»» » » /* work */ 408 decNumber dn; » » » /* work */
412 decimal32 canon; /* .. */ 409 decimal32 canon; /* .. */
413 decContext dc; /* .. */ 410 decContext dc; /* .. */
414 decContextDefault(&dc, DEC_INIT_DECIMAL32); 411 decContextDefault(&dc, DEC_INIT_DECIMAL32);
415 decimal32ToNumber(d32, &dn); 412 decimal32ToNumber(d32, &dn);
416 decimal32FromNumber(&canon, &dn, &dc);/* canon will now be canonical */ 413 decimal32FromNumber(&canon, &dn, &dc);/* canon will now be canonical */
417 return memcmp(d32, &canon, DECIMAL32_Bytes)==0; 414 return memcmp(d32, &canon, DECIMAL32_Bytes)==0;
418 } /* decimal32IsCanonical */ 415 } /* decimal32IsCanonical */
419 416
420 /* ------------------------------------------------------------------ */ 417 /* ------------------------------------------------------------------ */
421 /* decimal32Canonical -- copy an encoding, ensuring it is canonical */ 418 /* decimal32Canonical -- copy an encoding, ensuring it is canonical */
422 /* d32 is the source decimal32 */ 419 /* d32 is the source decimal32 */
423 /* result is the target (may be the same decimal32) */ 420 /* result is the target (may be the same decimal32) */
424 /* returns result */ 421 /* returns result */
425 /* No error is possible. */ 422 /* No error is possible. */
426 /* ------------------------------------------------------------------ */ 423 /* ------------------------------------------------------------------ */
427 decimal32 * decimal32Canonical(decimal32 *result, const decimal32 *d32) { 424 decimal32 * decimal32Canonical(decimal32 *result, const decimal32 *d32) {
428 decNumber dn;»» » » /* work */ 425 decNumber dn; » » » /* work */
429 decContext dc; /* .. */ 426 decContext dc; /* .. */
430 decContextDefault(&dc, DEC_INIT_DECIMAL32); 427 decContextDefault(&dc, DEC_INIT_DECIMAL32);
431 decimal32ToNumber(d32, &dn); 428 decimal32ToNumber(d32, &dn);
432 decimal32FromNumber(result, &dn, &dc);/* result will now be canonical */ 429 decimal32FromNumber(result, &dn, &dc);/* result will now be canonical */
433 return result; 430 return result;
434 } /* decimal32Canonical */ 431 } /* decimal32Canonical */
435 432
436 #if DECTRACE || DECCHECK 433 #if DECTRACE || DECCHECK
437 /* Macros for accessing decimal32 fields. These assume the argument 434 /* Macros for accessing decimal32 fields. These assume the argument
438 is a reference (pointer) to the decimal32 structure, and the 435 is a reference (pointer) to the decimal32 structure, and the
439 decimal32 is in network byte order (big-endian) */ 436 decimal32 is in network byte order (big-endian) */
440 /* Get sign */ 437 /* Get sign */
441 #define decimal32Sign(d) ((unsigned)(d)->bytes[0]>>7) 438 #define decimal32Sign(d) ((unsigned)(d)->bytes[0]>>7)
442 439
443 /* Get combination field */ 440 /* Get combination field */
444 #define decimal32Comb(d) (((d)->bytes[0] & 0x7c)>>2) 441 #define decimal32Comb(d) (((d)->bytes[0] & 0x7c)>>2)
445 442
446 /* Get exponent continuation [does not remove bias] */ 443 /* Get exponent continuation [does not remove bias] */
447 #define decimal32ExpCon(d) ((((d)->bytes[0] & 0x03)<<4) \ 444 #define decimal32ExpCon(d) ((((d)->bytes[0] & 0x03)<<4) \
448 | ((unsigned)(d)->bytes[1]>>4)) 445 | ((unsigned)(d)->bytes[1]>>4))
449 446
450 /* Set sign [this assumes sign previously 0] */ 447 /* Set sign [this assumes sign previously 0] */
451 #define decimal32SetSign(d, b) { \ 448 #define decimal32SetSign(d, b) { \
452 (d)->bytes[0]|=((unsigned)(b)<<7);} 449 (d)->bytes[0]|=((unsigned)(b)<<7);}
453 450
454 /* Set exponent continuation [does not apply bias] */ 451 /* Set exponent continuation [does not apply bias] */
455 /* This assumes range has been checked and exponent previously 0; */ 452 /* This assumes range has been checked and exponent previously 0; */
456 /* type of exponent must be unsigned */ 453 /* type of exponent must be unsigned */
457 #define decimal32SetExpCon(d, e) { \ 454 #define decimal32SetExpCon(d, e) { \
458 (d)->bytes[0]|=(uint8_t)((e)>>4);» » » » \ 455 (d)->bytes[0]|=(uByte)((e)>>4);» » » » \
459 (d)->bytes[1]|=(uint8_t)(((e)&0x0F)<<4);} 456 (d)->bytes[1]|=(uByte)(((e)&0x0F)<<4);}
460 457
461 /* ------------------------------------------------------------------ */ 458 /* ------------------------------------------------------------------ */
462 /* decimal32Show -- display a decimal32 in hexadecimal [debug aid] */ 459 /* decimal32Show -- display a decimal32 in hexadecimal [debug aid] */
463 /* d32 -- the number to show */ 460 /* d32 -- the number to show */
464 /* ------------------------------------------------------------------ */ 461 /* ------------------------------------------------------------------ */
465 /* Also shows sign/cob/expconfields extracted - valid bigendian only */ 462 /* Also shows sign/cob/expconfields extracted - valid bigendian only */
466 void decimal32Show(const decimal32 *d32) { 463 void decimal32Show(const decimal32 *d32) {
467 char buf[DECIMAL32_Bytes*2+1]; 464 char buf[DECIMAL32_Bytes*2+1];
468 Int i, j=0; 465 Int i, j=0;
469 466
470 if (DECLITEND) { 467 if (DECLITEND) {
471 for (i=0; i<DECIMAL32_Bytes; i++, j+=2) { 468 for (i=0; i<DECIMAL32_Bytes; i++, j+=2) {
472 sprintf(&buf[j], "%02x", d32->bytes[3-i]); 469 sprintf(&buf[j], "%02x", d32->bytes[3-i]);
473 } 470 }
474 printf(" D32> %s [S:%d Cb:%02x Ec:%02x] LittleEndian\n", buf, 471 printf(" D32> %s [S:%d Cb:%02x Ec:%02x] LittleEndian\n", buf,
475 d32->bytes[3]>>7, (d32->bytes[3]>>2)&0x1f, 472 d32->bytes[3]>>7, (d32->bytes[3]>>2)&0x1f,
476 ((d32->bytes[3]&0x3)<<4)| (d32->bytes[2]>>4)); 473 ((d32->bytes[3]&0x3)<<4)| (d32->bytes[2]>>4));
477 } 474 }
478 else { 475 else {
479 for (i=0; i<DECIMAL32_Bytes; i++, j+=2) { 476 for (i=0; i<DECIMAL32_Bytes; i++, j+=2) {
480 sprintf(&buf[j], "%02x", d32->bytes[i]); 477 sprintf(&buf[j], "%02x", d32->bytes[i]);
481 } 478 }
482 printf(" D32> %s [S:%d Cb:%02x Ec:%02x] BigEndian\n", buf, 479 printf(" D32> %s [S:%d Cb:%02x Ec:%02x] BigEndian\n", buf,
483 decimal32Sign(d32), decimal32Comb(d32), decimal32ExpCon(d32)); 480 decimal32Sign(d32), decimal32Comb(d32), decimal32ExpCon(d32));
484 } 481 }
485 } /* decimal32Show */ 482 } /* decimal32Show */
486 #endif 483 #endif
OLDNEW
« no previous file with comments | « gcc/libdecnumber/dpd/decimal128.c ('k') | gcc/libdecnumber/dpd/decimal64.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698