KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > retrotranslator > runtime > format > HexadecimalExponentialConversion


1 /***
2  * Retrotranslator: a Java bytecode transformer that translates Java classes
3  * compiled with JDK 5.0 into classes that can be run on JVM 1.4.
4  *
5  * Copyright (c) 2005 - 2007 Taras Puchko
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the copyright holders nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30  * THE POSSIBILITY OF SUCH DAMAGE.
31  */

32 package net.sf.retrotranslator.runtime.format;
33
34 /**
35  * @author Taras Puchko
36  */

37 class HexadecimalExponentialConversion extends NumericConversion {
38
39     public void format(FormatContext context) {
40         context.checkFlags();
41         context.assertNoFlag('(');
42         context.assertNoFlag(',');
43         Object JavaDoc argument = context.getArgument();
44         if (argument instanceof Double JavaDoc) {
45             printf(context, (Double JavaDoc) argument);
46         } else if (argument instanceof Float JavaDoc) {
47             printf(context, (Float JavaDoc) argument);
48         } else if (argument == null) {
49             context.writeRestricted(String.valueOf(argument));
50         } else {
51             throw context.getConversionException();
52         }
53     }
54
55     private static void printf(FormatContext context, double argument) {
56         if (!printSpecialNumber(context, argument)) {
57             context.writePadded(toHex(context, argument));
58         }
59     }
60
61     private static String JavaDoc toHex(FormatContext context, double argument) {
62         StringBuilder JavaDoc builder = new StringBuilder JavaDoc();
63         long bits = Double.doubleToLongBits(argument);
64         if (bits < 0) {
65             builder.append('-');
66         } else if (context.isFlag('+')) {
67             builder.append('+');
68         }
69         int exponent = getExponent(bits);
70         int precision = context.getPrecision();
71         if (argument != 0 && precision >= 0 && precision <= 12) {
72             if (exponent == 0) {
73                 bits = Double.doubleToLongBits(argument * (1L << 52));
74                 exponent = getExponent(bits) - 52;
75             }
76             double value = Double.longBitsToDouble(getSignificand(bits));
77             double factor = 1L << (52 - 4 * Math.max(precision, 1));
78             bits = Double.doubleToLongBits(value / factor * factor);
79             exponent += getExponent(bits) - 1;
80         }
81         builder.append(exponent == 0 ? "0x0." : "0x1.");
82         appendSignificand(builder, bits, precision);
83         return builder.append('p').append(argument == 0 ? 0 :
84                 exponent == 0 ? -1022 : exponent - 1023).toString();
85     }
86
87     private static int getExponent(long bits) {
88         return (int) (bits << 1 >>> 53);
89     }
90
91     private static long getSignificand(long bits) {
92         return bits & ((1L << 52) - 1) | 1L << 52;
93     }
94
95     private static void appendSignificand(StringBuilder JavaDoc builder, long bits, int precision) {
96         String JavaDoc s = Long.toHexString(getSignificand(bits));
97         int endIndex = s.length();
98         while (endIndex > 2 && s.charAt(endIndex - 1) == '0') {
99             endIndex--;
100         }
101         builder.append(s.substring(1, endIndex));
102         for (int i = endIndex; i <= precision; i++) {
103             builder.append('0');
104         }
105     }
106
107 }
108
Popular Tags