1 32 package net.sf.retrotranslator.runtime.format; 33 34 37 class HexadecimalExponentialConversion extends NumericConversion { 38 39 public void format(FormatContext context) { 40 context.checkFlags(); 41 context.assertNoFlag('('); 42 context.assertNoFlag(','); 43 Object argument = context.getArgument(); 44 if (argument instanceof Double ) { 45 printf(context, (Double ) argument); 46 } else if (argument instanceof Float ) { 47 printf(context, (Float ) 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 toHex(FormatContext context, double argument) { 62 StringBuilder builder = new StringBuilder (); 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 builder, long bits, int precision) { 96 String 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 |