comparison libdecnumber/decPacked.c @ 55:77e2b8dfacca gcc-4.4.5

update it from 4.4.3 to 4.5.0
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Fri, 12 Feb 2010 23:39:51 +0900
parents a06113de4d67
children 04ced10e8804
comparison
equal deleted inserted replaced
52:c156f1bd5cd9 55:77e2b8dfacca
24 <http://www.gnu.org/licenses/>. */ 24 <http://www.gnu.org/licenses/>. */
25 25
26 /* ------------------------------------------------------------------ */ 26 /* ------------------------------------------------------------------ */
27 /* Packed Decimal conversion module */ 27 /* Packed Decimal conversion module */
28 /* ------------------------------------------------------------------ */ 28 /* ------------------------------------------------------------------ */
29 /* This module comprises the routines for Packed Decimal format */ 29 /* This module comprises the routines for Packed Decimal format */
30 /* numbers. Conversions are supplied to and from decNumber, which in */ 30 /* numbers. Conversions are supplied to and from decNumber, which in */
31 /* turn supports: */ 31 /* turn supports: */
32 /* conversions to and from string */ 32 /* conversions to and from string */
33 /* arithmetic routines */ 33 /* arithmetic routines */
34 /* utilities. */ 34 /* utilities. */
35 /* Conversions from decNumber to and from densely packed decimal */ 35 /* Conversions from decNumber to and from densely packed decimal */
36 /* formats are provided by the decimal32 through decimal128 modules. */ 36 /* formats are provided by the decimal32 through decimal128 modules. */
37 /* ------------------------------------------------------------------ */ 37 /* ------------------------------------------------------------------ */
38 38
39 #include <string.h> /* for NULL */ 39 #include <string.h> /* for NULL */
44 /* ------------------------------------------------------------------ */ 44 /* ------------------------------------------------------------------ */
45 /* decPackedFromNumber -- convert decNumber to BCD Packed Decimal */ 45 /* decPackedFromNumber -- convert decNumber to BCD Packed Decimal */
46 /* */ 46 /* */
47 /* bcd is the BCD bytes */ 47 /* bcd is the BCD bytes */
48 /* length is the length of the BCD array */ 48 /* length is the length of the BCD array */
49 /* scale is the scale result */ 49 /* scale is the scale result */
50 /* dn is the decNumber */ 50 /* dn is the decNumber */
51 /* returns bcd, or NULL if error */ 51 /* returns bcd, or NULL if error */
52 /* */ 52 /* */
53 /* The number is converted to a BCD packed decimal byte array, */ 53 /* The number is converted to a BCD packed decimal byte array, */
54 /* right aligned in the bcd array, whose length is indicated by the */ 54 /* right aligned in the bcd array, whose length is indicated by the */
55 /* second parameter. The final 4-bit nibble in the array will be a */ 55 /* second parameter. The final 4-bit nibble in the array will be a */
60 /* negated). To force the number to a specified scale, first use the */ 60 /* negated). To force the number to a specified scale, first use the */
61 /* decNumberRescale routine, which will round and change the exponent */ 61 /* decNumberRescale routine, which will round and change the exponent */
62 /* as necessary. */ 62 /* as necessary. */
63 /* */ 63 /* */
64 /* If there is an error (that is, the decNumber has too many digits */ 64 /* If there is an error (that is, the decNumber has too many digits */
65 /* to fit in length bytes, or it is a NaN or Infinity), NULL is */ 65 /* to fit in length bytes, or it is a NaN or Infinity), NULL is */
66 /* returned and the bcd and scale results are unchanged. Otherwise */ 66 /* returned and the bcd and scale results are unchanged. Otherwise */
67 /* bcd is returned. */ 67 /* bcd is returned. */
68 /* ------------------------------------------------------------------ */ 68 /* ------------------------------------------------------------------ */
69 uByte * decPackedFromNumber(uByte *bcd, Int length, Int *scale, 69 uByte * decPackedFromNumber(uByte *bcd, Int length, Int *scale,
70 const decNumber *dn) { 70 const decNumber *dn) {
79 #endif 79 #endif
80 80
81 if (dn->digits>length*2-1 /* too long .. */ 81 if (dn->digits>length*2-1 /* too long .. */
82 ||(dn->bits & DECSPECIAL)) return NULL; /* .. or special -- hopeless */ 82 ||(dn->bits & DECSPECIAL)) return NULL; /* .. or special -- hopeless */
83 83
84 if (dn->bits&DECNEG) obyte=DECPMINUS; /* set the sign .. */ 84 if (dn->bits&DECNEG) obyte=DECPMINUS; /* set the sign .. */
85 else obyte=DECPPLUS; 85 else obyte=DECPPLUS;
86 *scale=-dn->exponent; /* .. and scale */ 86 *scale=-dn->exponent; /* .. and scale */
87 87
88 /* loop from lowest (rightmost) byte */ 88 /* loop from lowest (rightmost) byte */
89 out=bcd+length-1; /* -> final byte */ 89 out=bcd+length-1; /* -> final byte */
90 for (; out>=bcd; out--) { 90 for (; out>=bcd; out--) {
91 if (indigs>0) { 91 if (indigs>0) {
134 /* decPackedToNumber -- convert BCD Packed Decimal to a decNumber */ 134 /* decPackedToNumber -- convert BCD Packed Decimal to a decNumber */
135 /* */ 135 /* */
136 /* bcd is the BCD bytes */ 136 /* bcd is the BCD bytes */
137 /* length is the length of the BCD array */ 137 /* length is the length of the BCD array */
138 /* scale is the scale associated with the BCD integer */ 138 /* scale is the scale associated with the BCD integer */
139 /* dn is the decNumber [with space for length*2 digits] */ 139 /* dn is the decNumber [with space for length*2 digits] */
140 /* returns dn, or NULL if error */ 140 /* returns dn, or NULL if error */
141 /* */ 141 /* */
142 /* The BCD packed decimal byte array, together with an associated */ 142 /* The BCD packed decimal byte array, together with an associated */
143 /* scale, is converted to a decNumber. The BCD array is assumed full */ 143 /* scale, is converted to a decNumber. The BCD array is assumed full */
144 /* of digits, and must be ended by a 4-bit sign nibble in the least */ 144 /* of digits, and must be ended by a 4-bit sign nibble in the least */
150 /* The decNumber structure is assumed to have sufficient space to */ 150 /* The decNumber structure is assumed to have sufficient space to */
151 /* hold the converted number (that is, up to length*2-1 digits), so */ 151 /* hold the converted number (that is, up to length*2-1 digits), so */
152 /* no error is possible unless the adjusted exponent is out of range, */ 152 /* no error is possible unless the adjusted exponent is out of range, */
153 /* no sign nibble was found, or a sign nibble was found before the */ 153 /* no sign nibble was found, or a sign nibble was found before the */
154 /* final nibble. In these error cases, NULL is returned and the */ 154 /* final nibble. In these error cases, NULL is returned and the */
155 /* decNumber will be 0. */ 155 /* decNumber will be 0. */
156 /* ------------------------------------------------------------------ */ 156 /* ------------------------------------------------------------------ */
157 decNumber * decPackedToNumber(const uByte *bcd, Int length, 157 decNumber * decPackedToNumber(const uByte *bcd, Int length,
158 const Int *scale, decNumber *dn) { 158 const Int *scale, decNumber *dn) {
159 const uByte *last=bcd+length-1; /* -> last byte */ 159 const uByte *last=bcd+length-1; /* -> last byte */
160 const uByte *first; /* -> first non-zero byte */ 160 const uByte *first; /* -> first non-zero byte */
161 uInt nib; /* work nibble */ 161 uInt nib; /* work nibble */
162 Unit *up=dn->lsu; /* output pointer */ 162 Unit *up=dn->lsu; /* output pointer */
163 Int digits; /* digits count */ 163 Int digits; /* digits count */
164 Int cut=0; /* phase of output */ 164 Int cut=0; /* phase of output */
165 165
166 decNumberZero(dn); /* default result */ 166 decNumberZero(dn); /* default result */
167 last=&bcd[length-1]; 167 last=&bcd[length-1];
168 nib=*last & 0x0f; /* get the sign */ 168 nib=*last & 0x0f; /* get the sign */
175 if ((*first & 0xf0)==0) digits--; /* adjust for leading zero nibble */ 175 if ((*first & 0xf0)==0) digits--; /* adjust for leading zero nibble */
176 if (digits!=0) dn->digits=digits; /* count of actual digits [if 0, */ 176 if (digits!=0) dn->digits=digits; /* count of actual digits [if 0, */
177 /* leave as 1] */ 177 /* leave as 1] */
178 178
179 /* check the adjusted exponent; note that scale could be unbounded */ 179 /* check the adjusted exponent; note that scale could be unbounded */
180 dn->exponent=-*scale; /* set the exponent */ 180 dn->exponent=-*scale; /* set the exponent */
181 if (*scale>=0) { /* usual case */ 181 if (*scale>=0) { /* usual case */
182 if ((dn->digits-*scale-1)<-DECNUMMAXE) { /* underflow */ 182 if ((dn->digits-*scale-1)<-DECNUMMAXE) { /* underflow */
183 decNumberZero(dn); 183 decNumberZero(dn);
184 return NULL;} 184 return NULL;}
185 } 185 }