323 assert lvalue > 0L : lvalue; // lvalue <= 0 |
323 assert lvalue > 0L : lvalue; // lvalue <= 0 |
324 // even easier subcase! |
324 // even easier subcase! |
325 // can do int arithmetic rather than long! |
325 // can do int arithmetic rather than long! |
326 int ivalue = (int)lvalue; |
326 int ivalue = (int)lvalue; |
327 ndigits = 10; |
327 ndigits = 10; |
328 digits = (char[])(perThreadBuffer.get()); |
328 digits = perThreadBuffer.get(); |
329 digitno = ndigits-1; |
329 digitno = ndigits-1; |
330 c = ivalue%10; |
330 c = ivalue%10; |
331 ivalue /= 10; |
331 ivalue /= 10; |
332 while ( c == 0 ){ |
332 while ( c == 0 ){ |
333 decExponent++; |
333 decExponent++; |
343 digits[digitno] = (char)(c+'0'); |
343 digits[digitno] = (char)(c+'0'); |
344 } else { |
344 } else { |
345 // same algorithm as above (same bugs, too ) |
345 // same algorithm as above (same bugs, too ) |
346 // but using long arithmetic. |
346 // but using long arithmetic. |
347 ndigits = 20; |
347 ndigits = 20; |
348 digits = (char[])(perThreadBuffer.get()); |
348 digits = perThreadBuffer.get(); |
349 digitno = ndigits-1; |
349 digitno = ndigits-1; |
350 c = (int)(lvalue%10L); |
350 c = (int)(lvalue%10L); |
351 lvalue /= 10L; |
351 lvalue /= 10L; |
352 while ( c == 0 ){ |
352 while ( c == 0 ){ |
353 decExponent++; |
353 decExponent++; |
475 } else { |
475 } else { |
476 isNegative = false; |
476 isNegative = false; |
477 } |
477 } |
478 // Begin to unpack |
478 // Begin to unpack |
479 // Discover obvious special cases of NaN and Infinity. |
479 // Discover obvious special cases of NaN and Infinity. |
480 binExp = (int)( (fBits&singleExpMask) >> singleExpShift ); |
480 binExp = (fBits&singleExpMask) >> singleExpShift; |
481 fractBits = fBits&singleFractMask; |
481 fractBits = fBits&singleFractMask; |
482 if ( binExp == (int)(singleExpMask>>singleExpShift) ) { |
482 if ( binExp == (singleExpMask>>singleExpShift) ) { |
483 isExceptional = true; |
483 isExceptional = true; |
484 if ( fractBits == 0L ){ |
484 if ( fractBits == 0L ){ |
485 digits = infinity; |
485 digits = infinity; |
486 } else { |
486 } else { |
487 digits = notANumber; |
487 digits = notANumber; |
898 } |
898 } |
899 return new String(result); |
899 return new String(result); |
900 } |
900 } |
901 |
901 |
902 public String toJavaFormatString() { |
902 public String toJavaFormatString() { |
903 char result[] = (char[])(perThreadBuffer.get()); |
903 char result[] = perThreadBuffer.get(); |
904 int i = getChars(result); |
904 int i = getChars(result); |
905 return new String(result, 0, i); |
905 return new String(result, 0, i); |
906 } |
906 } |
907 |
907 |
908 private int getChars(char[] result) { |
908 private int getChars(char[] result) { |
976 } |
976 } |
977 return i; |
977 return i; |
978 } |
978 } |
979 |
979 |
980 // Per-thread buffer for string/stringbuffer conversion |
980 // Per-thread buffer for string/stringbuffer conversion |
981 private static ThreadLocal perThreadBuffer = new ThreadLocal() { |
981 private static ThreadLocal<char[]> perThreadBuffer = new ThreadLocal<char[]>() { |
982 protected synchronized Object initialValue() { |
982 protected synchronized char[] initialValue() { |
983 return new char[26]; |
983 return new char[26]; |
984 } |
984 } |
985 }; |
985 }; |
986 |
986 |
987 public void appendTo(Appendable buf) { |
987 public void appendTo(Appendable buf) { |
988 char result[] = (char[])(perThreadBuffer.get()); |
988 char result[] = perThreadBuffer.get(); |
989 int i = getChars(result); |
989 int i = getChars(result); |
990 if (buf instanceof StringBuilder) |
990 if (buf instanceof StringBuilder) |
991 ((StringBuilder) buf).append(result, 0, i); |
991 ((StringBuilder) buf).append(result, 0, i); |
992 else if (buf instanceof StringBuffer) |
992 else if (buf instanceof StringBuffer) |
993 ((StringBuffer) buf).append(result, 0, i); |
993 ((StringBuffer) buf).append(result, 0, i); |
994 else |
994 else |
995 assert false; |
995 assert false; |
996 } |
996 } |
997 |
997 |
|
998 @SuppressWarnings("fallthrough") |
998 public static FloatingDecimal |
999 public static FloatingDecimal |
999 readJavaFormatString( String in ) throws NumberFormatException { |
1000 readJavaFormatString( String in ) throws NumberFormatException { |
1000 boolean isNegative = false; |
1001 boolean isNegative = false; |
1001 boolean signSeen = false; |
1002 boolean signSeen = false; |
1002 int decExp; |
1003 int decExp; |
2207 // significand is incremented and overflows from |
2208 // significand is incremented and overflows from |
2208 // rounding, this combination will update the |
2209 // rounding, this combination will update the |
2209 // exponent correctly, even in the case of |
2210 // exponent correctly, even in the case of |
2210 // Double.MAX_VALUE overflowing to infinity. |
2211 // Double.MAX_VALUE overflowing to infinity. |
2211 |
2212 |
2212 significand = (( ((long)exponent + |
2213 significand = (( (exponent + |
2213 (long)DoubleConsts.EXP_BIAS) << |
2214 (long)DoubleConsts.EXP_BIAS) << |
2214 (DoubleConsts.SIGNIFICAND_WIDTH-1)) |
2215 (DoubleConsts.SIGNIFICAND_WIDTH-1)) |
2215 & DoubleConsts.EXP_BIT_MASK) | |
2216 & DoubleConsts.EXP_BIT_MASK) | |
2216 (DoubleConsts.SIGNIF_BIT_MASK & significand); |
2217 (DoubleConsts.SIGNIF_BIT_MASK & significand); |
2217 |
2218 |