1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package java.lang; 19 20 import libcore.math.MathUtils; 21 22 final class RealToString { 23 private static final ThreadLocal<RealToString> INSTANCE = new ThreadLocal<RealToString>() { 24 @Override protected RealToString initialValue() { 25 return new RealToString(); 26 } 27 }; 28 29 private static final double invLogOfTenBaseTwo = Math.log(2.0) / Math.log(10.0); 30 31 private int firstK; 32 33 /** 34 * An array of decimal digits, filled by longDigitGenerator or bigIntDigitGenerator. 35 */ 36 private final int[] digits = new int[64]; 37 38 /** 39 * Number of valid entries in 'digits'. 40 */ 41 private int digitCount; 42 43 private RealToString() { 44 } 45 46 public static RealToString getInstance() { 47 return INSTANCE.get(); 48 } 49 50 private static String resultOrSideEffect(AbstractStringBuilder sb, String s) { 51 if (sb != null) { 52 sb.append0(s); 53 return null; 54 } 55 return s; 56 } 57 58 public String doubleToString(double d) { 59 return convertDouble(null, d); 60 } 61 62 public void appendDouble(AbstractStringBuilder sb, double d) { 63 convertDouble(sb, d); 64 } 65 66 private String convertDouble(AbstractStringBuilder sb, double inputNumber) { 67 long inputNumberBits = Double.doubleToRawLongBits(inputNumber); 68 boolean positive = (inputNumberBits & Double.SIGN_MASK) == 0; 69 int e = (int) ((inputNumberBits & Double.EXPONENT_MASK) >> Double.MANTISSA_BITS); 70 long f = inputNumberBits & Double.MANTISSA_MASK; 71 boolean mantissaIsZero = f == 0; 72 73 String quickResult = null; 74 if (e == 2047) { 75 if (mantissaIsZero) { 76 quickResult = positive ? "Infinity" : "-Infinity"; 77 } else { 78 quickResult = "NaN"; 79 } 80 } else if (e == 0) { 81 if (mantissaIsZero) { 82 quickResult = positive ? "0.0" : "-0.0"; 83 } else if (f == 1) { 84 // special case to increase precision even though 2 * Double.MIN_VALUE is 1.0e-323 85 quickResult = positive ? "4.9E-324" : "-4.9E-324"; 86 } 87 } 88 if (quickResult != null) { 89 return resultOrSideEffect(sb, quickResult); 90 } 91 92 int p = Double.EXPONENT_BIAS + Double.MANTISSA_BITS; // the power offset (precision) 93 int pow; 94 int numBits = Double.MANTISSA_BITS; 95 if (e == 0) { 96 pow = 1 - p; // a denormalized number 97 long ff = f; 98 while ((ff & 0x0010000000000000L) == 0) { 99 ff = ff << 1; 100 numBits--; 101 } 102 } else { 103 // 0 < e < 2047 104 // a "normalized" number 105 f = f | 0x0010000000000000L; 106 pow = e - p; 107 } 108 109 firstK = digitCount = 0; 110 if (-59 < pow && pow < 6 || (pow == -59 && !mantissaIsZero)) { 111 longDigitGenerator(f, pow, e == 0, mantissaIsZero, numBits); 112 } else { 113 bigIntDigitGenerator(f, pow, e == 0, numBits); 114 } 115 AbstractStringBuilder dst = (sb != null) ? sb : new StringBuilder(26); 116 if (inputNumber >= 1e7D || inputNumber <= -1e7D 117 || (inputNumber > -1e-3D && inputNumber < 1e-3D)) { 118 freeFormatExponential(dst, positive); 119 } else { 120 freeFormat(dst, positive); 121 } 122 return (sb != null) ? null : dst.toString(); 123 } 124 125 public String floatToString(float f) { 126 return convertFloat(null, f); 127 } 128 129 public void appendFloat(AbstractStringBuilder sb, float f) { 130 convertFloat(sb, f); 131 } 132 133 public String convertFloat(AbstractStringBuilder sb, float inputNumber) { 134 int inputNumberBits = Float.floatToRawIntBits(inputNumber); 135 boolean positive = (inputNumberBits & Float.SIGN_MASK) == 0; 136 int e = (inputNumberBits & Float.EXPONENT_MASK) >> Float.MANTISSA_BITS; 137 int f = inputNumberBits & Float.MANTISSA_MASK; 138 boolean mantissaIsZero = f == 0; 139 140 String quickResult = null; 141 if (e == 255) { 142 if (mantissaIsZero) { 143 quickResult = positive ? "Infinity" : "-Infinity"; 144 } else { 145 quickResult = "NaN"; 146 } 147 } else if (e == 0 && mantissaIsZero) { 148 quickResult = positive ? "0.0" : "-0.0"; 149 } 150 if (quickResult != null) { 151 return resultOrSideEffect(sb, quickResult); 152 } 153 154 int p = Float.EXPONENT_BIAS + Float.MANTISSA_BITS; // the power offset (precision) 155 int pow; 156 int numBits = Float.MANTISSA_BITS; 157 if (e == 0) { 158 pow = 1 - p; // a denormalized number 159 if (f < 8) { // want more precision with smallest values 160 f = f << 2; 161 pow -= 2; 162 } 163 int ff = f; 164 while ((ff & 0x00800000) == 0) { 165 ff = ff << 1; 166 numBits--; 167 } 168 } else { 169 // 0 < e < 255 170 // a "normalized" number 171 f = f | 0x00800000; 172 pow = e - p; 173 } 174 175 firstK = digitCount = 0; 176 if (-59 < pow && pow < 35 || (pow == -59 && !mantissaIsZero)) { 177 longDigitGenerator(f, pow, e == 0, mantissaIsZero, numBits); 178 } else { 179 bigIntDigitGenerator(f, pow, e == 0, numBits); 180 } 181 AbstractStringBuilder dst = (sb != null) ? sb : new StringBuilder(26); 182 if (inputNumber >= 1e7f || inputNumber <= -1e7f 183 || (inputNumber > -1e-3f && inputNumber < 1e-3f)) { 184 freeFormatExponential(dst, positive); 185 } else { 186 freeFormat(dst, positive); 187 } 188 return (sb != null) ? null : dst.toString(); 189 } 190 191 private void freeFormatExponential(AbstractStringBuilder sb, boolean positive) { 192 int digitIndex = 0; 193 if (!positive) { 194 sb.append0('-'); 195 } 196 sb.append0((char) ('0' + digits[digitIndex++])); 197 sb.append0('.'); 198 199 int k = firstK; 200 int exponent = k; 201 while (true) { 202 k--; 203 if (digitIndex >= digitCount) { 204 break; 205 } 206 sb.append0((char) ('0' + digits[digitIndex++])); 207 } 208 209 if (k == exponent - 1) { 210 sb.append0('0'); 211 } 212 sb.append0('E'); 213 IntegralToString.appendInt(sb, exponent); 214 } 215 216 private void freeFormat(AbstractStringBuilder sb, boolean positive) { 217 int digitIndex = 0; 218 if (!positive) { 219 sb.append0('-'); 220 } 221 int k = firstK; 222 if (k < 0) { 223 sb.append0('0'); 224 sb.append0('.'); 225 for (int i = k + 1; i < 0; ++i) { 226 sb.append0('0'); 227 } 228 } 229 int U = digits[digitIndex++]; 230 do { 231 if (U != -1) { 232 sb.append0((char) ('0' + U)); 233 } else if (k >= -1) { 234 sb.append0('0'); 235 } 236 if (k == 0) { 237 sb.append0('.'); 238 } 239 k--; 240 U = digitIndex < digitCount ? digits[digitIndex++] : -1; 241 } while (U != -1 || k >= -1); 242 } 243 244 private native void bigIntDigitGenerator(long f, int e, boolean isDenormalized, int p); 245 246 private void longDigitGenerator(long f, int e, boolean isDenormalized, 247 boolean mantissaIsZero, int p) { 248 long R, S, M; 249 if (e >= 0) { 250 M = 1l << e; 251 if (!mantissaIsZero) { 252 R = f << (e + 1); 253 S = 2; 254 } else { 255 R = f << (e + 2); 256 S = 4; 257 } 258 } else { 259 M = 1; 260 if (isDenormalized || !mantissaIsZero) { 261 R = f << 1; 262 S = 1l << (1 - e); 263 } else { 264 R = f << 2; 265 S = 1l << (2 - e); 266 } 267 } 268 269 int k = (int) Math.ceil((e + p - 1) * invLogOfTenBaseTwo - 1e-10); 270 271 if (k > 0) { 272 S = S * MathUtils.LONG_POWERS_OF_TEN[k]; 273 } else if (k < 0) { 274 long scale = MathUtils.LONG_POWERS_OF_TEN[-k]; 275 R = R * scale; 276 M = M == 1 ? scale : M * scale; 277 } 278 279 if (R + M > S) { // was M_plus 280 firstK = k; 281 } else { 282 firstK = k - 1; 283 R = R * 10; 284 M = M * 10; 285 } 286 287 boolean low, high; 288 int U; 289 while (true) { 290 // Set U to floor(R/S) and R to the remainder, using *unsigned* 64-bit division 291 U = 0; 292 for (int i = 3; i >= 0; i--) { 293 long remainder = R - (S << i); 294 if (remainder >= 0) { 295 R = remainder; 296 U += 1 << i; 297 } 298 } 299 300 low = R < M; // was M_minus 301 high = R + M > S; // was M_plus 302 303 if (low || high) { 304 break; 305 } 306 R = R * 10; 307 M = M * 10; 308 digits[digitCount++] = U; 309 } 310 if (low && !high) { 311 digits[digitCount++] = U; 312 } else if (high && !low) { 313 digits[digitCount++] = U + 1; 314 } else if ((R << 1) < S) { 315 digits[digitCount++] = U; 316 } else { 317 digits[digitCount++] = U + 1; 318 } 319 } 320 } 321