added -J option to preserve unmodified files in preexisting jarfile
[org.ibex.tool.git] / src / org / eclipse / jdt / internal / compiler / util / FloatUtil.java
1 /*******************************************************************************
2  * Copyright (c) 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package org.eclipse.jdt.internal.compiler.util;
12
13 /**
14  * Internal utility for declaing with hexadecimal double and float literals.
15  * 
16  * @since 3.1
17  */
18 public class FloatUtil {
19
20         private static final int DOUBLE_FRACTION_WIDTH = 52;
21
22         private static final int DOUBLE_PRECISION = 53;
23
24         private static final int MAX_DOUBLE_EXPONENT = +1023;
25         
26         private static final int MIN_NORMALIZED_DOUBLE_EXPONENT = -1022;
27
28         private static final int MIN_UNNORMALIZED_DOUBLE_EXPONENT = MIN_NORMALIZED_DOUBLE_EXPONENT
29                         - DOUBLE_PRECISION;
30
31         private static final int DOUBLE_EXPONENT_BIAS = +1023;
32
33         private static final int DOUBLE_EXPONENT_SHIFT = 52;
34
35         private static final int SINGLE_FRACTION_WIDTH = 23;
36
37         private static final int SINGLE_PRECISION = 24;
38
39         private static final int MAX_SINGLE_EXPONENT = +127;
40
41         private static final int MIN_NORMALIZED_SINGLE_EXPONENT = -126;
42
43         private static final int MIN_UNNORMALIZED_SINGLE_EXPONENT = MIN_NORMALIZED_SINGLE_EXPONENT
44                         - SINGLE_PRECISION;
45
46         private static final int SINGLE_EXPONENT_BIAS = +127;
47
48         private static final int SINGLE_EXPONENT_SHIFT = 23;
49
50         /**
51          * Returns the float value corresponding to the given 
52          * hexadecimal floating-point single precision literal.
53          * The literal must be syntactially correct, and must be
54          * a float literal (end in a 'f' or 'F'). It must not
55          * include either leading or trailing whitespace or
56          * a sign.
57          * <p>
58          * This method returns the same answer as
59          * Float.parseFloat(new String(source)) does in JDK 1.5,
60          * except that this method returns Floal.NaN if it
61          * would underflow to 0 (parseFloat just returns 0).
62          * The method handles all the tricky cases, including 
63          * fraction rounding to 24 bits and gradual underflow.
64          * </p>
65          * 
66          * @param source source string containing single precision
67          * hexadecimal floating-point literal
68          * @return the float value, including Float.POSITIVE_INFINITY
69          * if the non-zero value is too large to be represented, and
70          * Float.NaN if the non-zero value is too small to be represented
71          */
72         public static float valueOfHexFloatLiteral(char[] source) {
73                 long bits = convertHexFloatingPointLiteralToBits(source);
74                 return Float.intBitsToFloat((int) bits);
75         }
76
77         /**
78          * Returns the double value corresponding to the given 
79          * hexadecimal floating-point double precision literal.
80          * The literal must be syntactially correct, and must be
81          * a double literal (end in an optional 'd' or 'D').
82          * It must not include either leading or trailing whitespace or
83          * a sign.
84          * <p>
85          * This method returns the same answer as
86          * Double.parseDouble(new String(source)) does in JDK 1.5,
87          * except that this method throw NumberFormatException in
88          * the case of overflow to infinity or underflow to 0.
89          * The method handles all the tricky cases, including 
90          * fraction rounding to 53 bits and gradual underflow.
91          * </p>
92          * 
93          * @param source source string containing double precision
94          * hexadecimal floating-point literal
95          * @return the double value, including Double.POSITIVE_INFINITY
96          * if the non-zero value is too large to be represented, and
97          * Double.NaN if the non-zero value is too small to be represented
98          */
99         public static double valueOfHexDoubleLiteral(char[] source) {
100                 long bits = convertHexFloatingPointLiteralToBits(source);
101                 return Double.longBitsToDouble(bits);
102         }
103
104         /**
105          * Returns the given hexadecimal floating-point literal as
106          * the bits for a single-precision  (float) or a
107          * double-precision (double) IEEE floating point number.
108          * The literal must be syntactially correct.  It must not
109          * include either leading or trailing whitespace or a sign.
110          * 
111          * @param source source string containing hexadecimal floating-point literal
112          * @return for double precision literals, bits suitable 
113          * for passing to Double.longBitsToDouble; for single precision literals,
114          * bits suitable for passing to Single.intBitsToDouble in the bottom
115          * 32 bits of the result
116          * @throws NumberFormatException if the number cannot be parsed
117          */
118         private static long convertHexFloatingPointLiteralToBits(char[] source) {
119                 int length = source.length;
120                 long mantissa = 0;
121
122                 // Step 1: process the '0x' lead-in
123                 int next = 0;
124                 char nextChar = source[next];
125                 nextChar = source[next];
126                 if (nextChar == '0') {
127                         next++;
128                 } else {
129                         throw new NumberFormatException();
130                 }
131                 nextChar = source[next];
132                 if (nextChar == 'X' || nextChar == 'x') {
133                         next++;
134                 } else {
135                         throw new NumberFormatException();
136                 }
137
138                 // Step 2: process leading '0's either before or after the '.'
139                 int binaryPointPosition = -1;
140                 loop: while (true) {
141                         nextChar = source[next];
142                         switch (nextChar) {
143                         case '0':
144                                 next++;
145                                 continue loop;
146                         case '.':
147                                 binaryPointPosition = next;
148                                 next++;
149                                 continue loop;
150                         default:
151                                 break loop;
152                         }
153                 }
154
155                 // Step 3: process the mantissa
156                 // leading zeros have been trimmed
157                 int mantissaBits = 0;
158                 int leadingDigitPosition = -1;
159                 loop: while (true) {
160                         nextChar = source[next];
161                         int hexdigit;
162                         switch (nextChar) {
163                         case '0':
164                         case '1':
165                         case '2':
166                         case '3':
167                         case '4':
168                         case '5':
169                         case '6':
170                         case '7':
171                         case '8':
172                         case '9':
173                                 hexdigit = nextChar - '0';
174                                 break;
175                         case 'a':
176                         case 'b':
177                         case 'c':
178                         case 'd':
179                         case 'e':
180                         case 'f':
181                                 hexdigit = (nextChar - 'a') + 10;
182                                 break;
183                         case 'A':
184                         case 'B':
185                         case 'C':
186                         case 'D':
187                         case 'E':
188                         case 'F':
189                                 hexdigit = (nextChar - 'A') + 10;
190                                 break;
191                         case '.':
192                                 binaryPointPosition = next;
193                                 next++;
194                                 continue loop;
195                         default:
196                                 if (binaryPointPosition < 0) {
197                                         // record virtual '.' as being to right of all digits
198                                         binaryPointPosition = next;
199                                 }
200                                 break loop;
201                         }
202                         if (mantissaBits == 0) {
203                                 // this is the first non-zero hex digit
204                                 // ignore leading binary 0's in hex digit
205                                 leadingDigitPosition = next;
206                                 mantissa = hexdigit;
207                                 mantissaBits = 4;
208                         } else if (mantissaBits < 60) {
209                                 // middle hex digits
210                                 mantissa <<= 4;
211                                 mantissa |= hexdigit;
212                                 mantissaBits += 4;
213                         } else {
214                                 // more mantissa bits than we can handle
215                                 // drop this hex digit on the ground
216                         }
217                         next++;
218                         continue loop;
219                 }
220
221                 // Step 4: process the 'P'
222                 nextChar = source[next];
223                 if (nextChar == 'P' || nextChar == 'p') {
224                         next++;
225                 } else {
226                         throw new NumberFormatException();
227                 }
228
229                 // Step 5: process the exponent
230                 int exponent = 0;
231                 int exponentSign = +1;
232                 loop: while (next < length) {
233                         nextChar = source[next];
234                         switch (nextChar) {
235                         case '+':
236                                 exponentSign = +1;
237                                 next++;
238                                 continue loop;
239                         case '-':
240                                 exponentSign = -1;
241                                 next++;
242                                 continue loop;
243                         case '0':
244                         case '1':
245                         case '2':
246                         case '3':
247                         case '4':
248                         case '5':
249                         case '6':
250                         case '7':
251                         case '8':
252                         case '9':
253                                 int digit = nextChar - '0';
254                                 exponent = (exponent * 10) + digit;
255                                 next++;
256                                 continue loop;
257                         default:
258                                 break loop;
259                         }
260                 }
261
262                 // Step 6: process the optional 'f' or 'd'
263                 boolean doublePrecision = true;
264                 if (next < length) {
265                         nextChar = source[next];
266                         switch (nextChar) {
267                         case 'f':
268                         case 'F':
269                                 doublePrecision = false;
270                                 next++;
271                                 break;
272                         case 'd':
273                         case 'D':
274                                 doublePrecision = true;
275                                 next++;
276                                 break;
277                         default:
278                                 throw new NumberFormatException();
279                         }
280                 }
281
282                 // at this point, all the parsing is done
283                 // Step 7: handle mantissa of zero
284                 if (mantissa == 0) {
285                         return 0L;
286                 }
287
288                 // Step 8: normalize non-zero mantissa
289                 // mantissa is in right-hand mantissaBits
290                 // ensure that top bit (as opposed to hex digit) is 1
291                 int scaleFactorCompensation = 0;
292                 long top = (mantissa >>> (mantissaBits - 4));
293                 if ((top & 0x8) == 0) {
294                         mantissaBits--;
295                         scaleFactorCompensation++;
296                         if ((top & 0x4) == 0) {
297                                 mantissaBits--;
298                                 scaleFactorCompensation++;
299                                 if ((top & 0x2) == 0) {
300                                         mantissaBits--;
301                                         scaleFactorCompensation++;
302                                 }
303                         }
304                 }
305                 
306                 // Step 9: convert double literals to IEEE double
307                 long result = 0L;
308                 if (doublePrecision) {
309                         long fraction;
310                         if (mantissaBits > DOUBLE_PRECISION) {
311                                 // more bits than we can keep
312                                 int extraBits = mantissaBits - DOUBLE_PRECISION;
313                                 // round to DOUBLE_PRECISION bits
314                                 fraction = mantissa >>> (extraBits - 1);
315                                 long lowBit = fraction & 0x1;
316                                 fraction += lowBit;
317                                 fraction = fraction >>> 1;
318                                 if ((fraction & (1L << DOUBLE_PRECISION)) != 0) {
319                                         fraction = fraction >>> 1;
320                                         scaleFactorCompensation -= 1;
321                                 }
322                         } else {
323                                 // less bits than the faction can hold - pad on right with 0s
324                                 fraction = mantissa << (DOUBLE_PRECISION - mantissaBits);
325                         }
326
327                         int scaleFactor = 0; // how many bits to move '.' to before leading hex digit
328                         if (mantissaBits > 0) {
329                                 if (leadingDigitPosition < binaryPointPosition) {
330                                         // e.g., 0x80.0p0 has scaleFactor == +8 
331                                         scaleFactor = 4 * (binaryPointPosition - leadingDigitPosition);
332                                         // e.g., 0x10.0p0 has scaleFactorCompensation == +3 
333                                         scaleFactor -= scaleFactorCompensation;
334                                 } else {
335                                         // e.g., 0x0.08p0 has scaleFactor == -4 
336                                         scaleFactor = -4
337                                                         * (leadingDigitPosition - binaryPointPosition - 1);
338                                         // e.g., 0x0.01p0 has scaleFactorCompensation == +3 
339                                         scaleFactor -= scaleFactorCompensation;
340                                 }
341                         }
342
343                         int e = (exponentSign * exponent) + scaleFactor;
344                         if (e - 1 > MAX_DOUBLE_EXPONENT) {
345                                 // overflow to +infinity
346                                 result = Double.doubleToLongBits(Double.POSITIVE_INFINITY);
347                         } else if (e - 1 >= MIN_NORMALIZED_DOUBLE_EXPONENT) {
348                                 // can be represented as a normalized double
349                                 // the left most bit must be discarded (it's always a 1)
350                                 long biasedExponent = e - 1 + DOUBLE_EXPONENT_BIAS;
351                                 result = fraction & ~(1L << DOUBLE_FRACTION_WIDTH);
352                                 result |= (biasedExponent << DOUBLE_EXPONENT_SHIFT);
353                         } else if (e - 1 > MIN_UNNORMALIZED_DOUBLE_EXPONENT) {
354                                 // can be represented as an unnormalized double
355                                 long biasedExponent = 0;
356                                 result = fraction >>> (MIN_NORMALIZED_DOUBLE_EXPONENT - e + 1);
357                                 result |= (biasedExponent << DOUBLE_EXPONENT_SHIFT);
358                         } else {
359                                 // underflow - return Double.NaN
360                                 result = Double.doubleToLongBits(Double.NaN);
361                         }
362                         return result;
363                 }
364
365                 // Step 10: convert float literals to IEEE single
366                 long fraction;
367                 if (mantissaBits > SINGLE_PRECISION) {
368                         // more bits than we can keep
369                         int extraBits = mantissaBits - SINGLE_PRECISION;
370                         // round to DOUBLE_PRECISION bits
371                         fraction = mantissa >>> (extraBits - 1);
372                         long lowBit = fraction & 0x1;
373                         fraction += lowBit;
374                         fraction = fraction >>> 1;
375                         if ((fraction & (1L << SINGLE_PRECISION)) != 0) {
376                                 fraction = fraction >>> 1;
377                                 scaleFactorCompensation -= 1;
378                         }
379                 } else {
380                         // less bits than the faction can hold - pad on right with 0s
381                         fraction = mantissa << (SINGLE_PRECISION - mantissaBits);
382                 }
383
384                 int scaleFactor = 0; // how many bits to move '.' to before leading hex digit
385                 if (mantissaBits > 0) {
386                         if (leadingDigitPosition < binaryPointPosition) {
387                                 // e.g., 0x80.0p0 has scaleFactor == +8 
388                                 scaleFactor = 4 * (binaryPointPosition - leadingDigitPosition);
389                                 // e.g., 0x10.0p0 has scaleFactorCompensation == +3 
390                                 scaleFactor -= scaleFactorCompensation;
391                         } else {
392                                 // e.g., 0x0.08p0 has scaleFactor == -4 
393                                 scaleFactor = -4
394                                                 * (leadingDigitPosition - binaryPointPosition - 1);
395                                 // e.g., 0x0.01p0 has scaleFactorCompensation == +3 
396                                 scaleFactor -= scaleFactorCompensation;
397                         }
398                 }
399
400                 int e = (exponentSign * exponent) + scaleFactor;
401                 if (e - 1 > MAX_SINGLE_EXPONENT) {
402                         // overflow to +infinity
403                         result = Float.floatToIntBits(Float.POSITIVE_INFINITY);
404                 } else if (e - 1 >= MIN_NORMALIZED_SINGLE_EXPONENT) {
405                         // can be represented as a normalized single
406                         // the left most bit must be discarded (it's always a 1)
407                         long biasedExponent = e - 1 + SINGLE_EXPONENT_BIAS;
408                         result = fraction & ~(1L << SINGLE_FRACTION_WIDTH);
409                         result |= (biasedExponent << SINGLE_EXPONENT_SHIFT);
410                 } else if (e - 1 > MIN_UNNORMALIZED_SINGLE_EXPONENT) {
411                         // can be represented as an unnormalized single
412                         long biasedExponent = 0;
413                         result = fraction >>> (MIN_NORMALIZED_SINGLE_EXPONENT - e + 1);
414                         result |= (biasedExponent << SINGLE_EXPONENT_SHIFT);
415                 } else {
416                         // underflow - return Float.NaN
417                         result = Float.floatToIntBits(Float.NaN);
418                 }
419                 return result;
420         }
421 }