1 19 package jcckit.util; 20 21 26 class FormatElement { 27 28 static final String DESCRIPTORS = "doxfeEgG"; 29 private static final String INT_DESCRIPTORS = "dox"; 30 private static final int INT_DESCRIPTOR = 0; 31 private static final int FLOAT_DESCRIPTOR = 1; 32 38 private static final double power(double x, int n) { 39 return n < 0 ? 1.0 / power2(x, -n) : power2(x, n); 40 } 41 42 43 private static final double power2(double x, int n) { 44 switch (n) { 45 case 0: return 1; 46 case 1: return x; 47 default: 48 double p = power2(x, n / 2); 49 return p * p * power2(x, n % 2); 50 } 51 } 52 53 private final char _descriptor; 54 private final int _descriptorType; 55 private final double _tenToPrecision; 56 private boolean _decimalPoint; 57 private boolean _flushLeft; 58 private boolean _leadingZeros; 59 private boolean _alwaysSign; 60 private int _width; 61 private int _precision; 62 63 64 FormatElement(String formatString) { 65 int len = formatString.length() - 1; 66 _descriptor = formatString.charAt(len); 67 if (DESCRIPTORS.indexOf(_descriptor) < 0) { 68 throw new IllegalArgumentException ("Format element '" + formatString 69 + "' does not ends with one of the following characters: " 70 + DESCRIPTORS); 71 } 72 _descriptorType = INT_DESCRIPTORS.indexOf(_descriptor) >= 0 73 ? INT_DESCRIPTOR : FLOAT_DESCRIPTOR; 74 if (formatString.length() > 1) { 75 switch (formatString.charAt(0)) { 76 case '-': 77 _flushLeft = true; 78 formatString = formatString.substring(1); 79 break; 80 case '0': 81 _leadingZeros = true; 82 formatString = formatString.substring(1); 83 break; 84 case '+': 85 _alwaysSign = true; 86 formatString = formatString.substring(1); 87 break; 88 } 89 len = formatString.length() - 1; 90 int index = formatString.indexOf('.'); 91 _decimalPoint = index >= 0; 92 int last = _decimalPoint ? index : len; 93 if (last > 0) { 94 _width = Integer.parseInt(formatString.substring(0, last)); 95 } 96 if (_decimalPoint) { 97 index++; 98 if (index < len) { 99 _precision = Integer.parseInt(formatString.substring(index, len)); 100 } 101 } 102 } 103 _tenToPrecision = power(10, _precision); 104 } 105 106 112 public void form(StringBuffer buffer, long number) { 113 if (_descriptorType == FLOAT_DESCRIPTOR) { 114 form(buffer, (double) number); 115 } else { 116 buffer.append(form(number < 0, 118 Long.toString(Math.abs(number), 119 _descriptor == 'o' ? 8 120 : (_descriptor == 'x' ? 16 : 10)), 121 "")); 122 } 123 } 124 125 131 public void form(StringBuffer buffer, double number) { 132 if (_descriptorType == INT_DESCRIPTOR) { 133 form(buffer, (long) Math.floor(number + 0.5)); 134 } else if (_descriptor == 'f') { 135 buffer.append(formF(number)); 136 } else if (_descriptor == 'e' || _descriptor == 'E') { 137 buffer.append(formE(number)); 138 } else if (_descriptor == 'g' || _descriptor == 'G') { 139 String formF = formF(number); 140 String formE = formE(number); 141 buffer.append(formF.length() > formE.length() ? formE : formF); 142 } 143 } 144 145 private String form(boolean negativeValue, String intPart, String fracPart) { 146 int len = intPart.length() + fracPart.length(); 147 148 StringBuffer result = new StringBuffer (); 150 int count = 0; 151 152 if (_alwaysSign || negativeValue) { 154 result.append(negativeValue ? '-' : '+'); 155 count++; 156 } 157 158 if (_leadingZeros) { 160 for (int i = count + len; i < _width; i++) { 161 result.append('0'); 162 count++; 163 } 164 } 165 166 result.append(intPart).append(fracPart); 168 count += len; 169 170 if (_flushLeft) { 172 for (; count < _width; count++) { 173 result.append(' '); 174 } 175 } else { 176 for (; count < _width; count++) { 177 result.insert(0, ' '); 178 } 179 } 180 181 return new String (result); 182 } 183 184 185 private String formE(double number) { 186 int exponent = 0; 188 String zeros = "00000000000000000000000".substring(0, _precision + 1); 189 if (number != 0) { 190 exponent = (int) Math.floor(Math.log(Math.abs(number)) / Math.log(10)); 191 double mantisse = Math.floor(Math.abs(number * power(10.0, 192 _precision - exponent)) + 0.5); 193 if (mantisse >= 10 * _tenToPrecision) { 194 exponent++; 195 mantisse = Math.floor(Math.abs(number * power(10.0, 196 _precision - exponent)) + 0.5); 197 } 198 zeros = Long.toString((long) mantisse); 199 } 200 201 StringBuffer fracPart = new StringBuffer (); 203 if (_decimalPoint) { 204 fracPart.append('.').append(zeros.substring(1)); 205 } 206 207 fracPart.append(Character.isLowerCase(_descriptor) ? 'e': 'E') 209 .append(exponent < 0 ? '-' : '+'); 210 exponent = Math.abs(exponent); 211 for (int i = 0, n = fracPart.length(); i < 3; i++) { 212 fracPart.insert(n, Character.forDigit(exponent % 10, 10)); 213 exponent /= 10; 214 } 215 216 return form(number < 0, zeros.substring(0, 1), new String (fracPart)); 217 } 218 219 220 private String formF(double number) { 221 double multiplier = number < 0 ? - _tenToPrecision : _tenToPrecision; 223 String digits 224 = Long.toString((long) Math.floor(number * multiplier + 0.5)); 225 String intPart = digits; 226 StringBuffer fracPart = new StringBuffer (); 227 if (_decimalPoint) { 228 int len = digits.length() - _precision; 229 fracPart.append('.').append(digits.substring(Math.max(0, len))); 230 if (len > 0) { 231 intPart = digits.substring(0, len); 232 } else { 233 intPart = "0"; 234 for (; len < 0; len++) { 235 fracPart.insert(1, '0'); 236 } 237 } 238 } 239 240 return form(number < 0, intPart, new String (fracPart)); 241 } 242 } 243 | Popular Tags |