Mercurial > hg > CbC > CbC_gcc
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 } |