254 255 // At this point the first count digits match. If decimalAt is less 256 // than count, then the remaining digits are zero, and we return true. 257 if (count < decimalAt) return true; 258 259 // Now we have a representation of Long.MIN_VALUE, without the leading 260 // negative sign. If this represents a positive value, then it does 261 // not fit; otherwise it fits. 262 return !isPositive; 263 } 264 265 /** 266 * Set the digit list to a representation of the given double value. 267 * This method supports fixed-point notation. 268 * @param isNegative Boolean value indicating whether the number is negative. 269 * @param source Value to be converted; must not be Inf, -Inf, Nan, 270 * or a value <= 0. 271 * @param maximumFractionDigits The most fractional digits which should 272 * be converted. 273 */ 274 public final void set(boolean isNegative, double source, int maximumFractionDigits) { 275 set(isNegative, source, maximumFractionDigits, true); 276 } 277 278 /** 279 * Set the digit list to a representation of the given double value. 280 * This method supports both fixed-point and exponential notation. 281 * @param isNegative Boolean value indicating whether the number is negative. 282 * @param source Value to be converted; must not be Inf, -Inf, Nan, 283 * or a value <= 0. 284 * @param maximumDigits The most fractional or total digits which should 285 * be converted. 286 * @param fixedPoint If true, then maximumDigits is the maximum 287 * fractional digits to be converted. If false, total digits. 288 */ 289 final void set(boolean isNegative, double source, int maximumDigits, boolean fixedPoint) { 290 291 FloatingDecimal fd = new FloatingDecimal(source); 292 boolean hasBeenRoundedUp = fd.digitsRoundedUp(); 293 boolean allDecimalDigits = fd.decimalDigitsExact(); 294 String digitsString = fd.toJavaFormatString(); 295 296 set(isNegative, digitsString, 297 hasBeenRoundedUp, allDecimalDigits, 298 maximumDigits, fixedPoint); 299 } 300 301 /** 302 * Generate a representation of the form DDDDD, DDDDD.DDDDD, or 303 * DDDDDE+/-DDDDD. 304 * @param roundedUp Boolean value indicating if the s digits were rounded-up. 305 * @param allDecimalDigits Boolean value indicating if the digits in s are 306 * an exact decimal representation of the double that was passed. 307 */ 308 final void set(boolean isNegative, String s, 309 boolean roundedUp, boolean allDecimalDigits, 310 int maximumDigits, boolean fixedPoint) { 311 this.isNegative = isNegative; 312 int len = s.length(); 313 char[] source = getDataChars(len); 314 s.getChars(0, len, source, 0); 315 316 decimalAt = -1; 317 count = 0; 318 int exponent = 0; 319 // Number of zeros between decimal point and first non-zero digit after 320 // decimal point, for numbers < 1. 321 int leadingZerosAfterDecimal = 0; 322 boolean nonZeroDigitSeen = false; 323 324 for (int i = 0; i < len; ) { 325 char c = source[i++]; 326 if (c == '.') { 327 decimalAt = count; 328 } else if (c == 'e' || c == 'E') { 590 } 591 break; 592 case UNNECESSARY: 593 for (int i=maximumDigits; i<count; ++i) { 594 if (digits[i] != '0') { 595 throw new ArithmeticException( 596 "Rounding needed with the rounding mode being set to RoundingMode.UNNECESSARY"); 597 } 598 } 599 break; 600 default: 601 assert false; 602 } 603 } 604 return false; 605 } 606 607 /** 608 * Utility routine to set the value of the digit list from a long 609 */ 610 public final void set(boolean isNegative, long source) { 611 set(isNegative, source, 0); 612 } 613 614 /** 615 * Set the digit list to a representation of the given long value. 616 * @param isNegative Boolean value indicating whether the number is negative. 617 * @param source Value to be converted; must be >= 0 or == 618 * Long.MIN_VALUE. 619 * @param maximumDigits The most digits which should be converted. 620 * If maximumDigits is lower than the number of significant digits 621 * in source, the representation will be rounded. Ignored if <= 0. 622 */ 623 public final void set(boolean isNegative, long source, int maximumDigits) { 624 this.isNegative = isNegative; 625 626 // This method does not expect a negative number. However, 627 // "source" can be a Long.MIN_VALUE (-9223372036854775808), 628 // if the number being formatted is a Long.MIN_VALUE. In that 629 // case, it will be formatted as -Long.MIN_VALUE, a number 630 // which is outside the legal range of a long, but which can 631 // be represented by DigitList. 632 if (source <= 0) { 633 if (source == Long.MIN_VALUE) { 634 decimalAt = count = MAX_COUNT; 635 System.arraycopy(LONG_MIN_REP, 0, digits, 0, count); 636 } else { 637 decimalAt = count = 0; // Values <= 0 format as zero 638 } 639 } else { 640 // Rewritten to improve performance. I used to call 641 // Long.toString(), which was about 4x slower than this code. 642 int left = MAX_COUNT; 643 int right; | 254 255 // At this point the first count digits match. If decimalAt is less 256 // than count, then the remaining digits are zero, and we return true. 257 if (count < decimalAt) return true; 258 259 // Now we have a representation of Long.MIN_VALUE, without the leading 260 // negative sign. If this represents a positive value, then it does 261 // not fit; otherwise it fits. 262 return !isPositive; 263 } 264 265 /** 266 * Set the digit list to a representation of the given double value. 267 * This method supports fixed-point notation. 268 * @param isNegative Boolean value indicating whether the number is negative. 269 * @param source Value to be converted; must not be Inf, -Inf, Nan, 270 * or a value <= 0. 271 * @param maximumFractionDigits The most fractional digits which should 272 * be converted. 273 */ 274 final void set(boolean isNegative, double source, int maximumFractionDigits) { 275 set(isNegative, source, maximumFractionDigits, true); 276 } 277 278 /** 279 * Set the digit list to a representation of the given double value. 280 * This method supports both fixed-point and exponential notation. 281 * @param isNegative Boolean value indicating whether the number is negative. 282 * @param source Value to be converted; must not be Inf, -Inf, Nan, 283 * or a value <= 0. 284 * @param maximumDigits The most fractional or total digits which should 285 * be converted. 286 * @param fixedPoint If true, then maximumDigits is the maximum 287 * fractional digits to be converted. If false, total digits. 288 */ 289 final void set(boolean isNegative, double source, int maximumDigits, boolean fixedPoint) { 290 291 FloatingDecimal.BinaryToASCIIConverter fdConverter = FloatingDecimal.getBinaryToASCIIConverter(source); 292 boolean hasBeenRoundedUp = fdConverter.digitsRoundedUp(); 293 boolean allDecimalDigits = fdConverter.decimalDigitsExact(); 294 assert !fdConverter.isExceptional(); 295 String digitsString = fdConverter.toJavaFormatString(); 296 297 set(isNegative, digitsString, 298 hasBeenRoundedUp, allDecimalDigits, 299 maximumDigits, fixedPoint); 300 } 301 302 /** 303 * Generate a representation of the form DDDDD, DDDDD.DDDDD, or 304 * DDDDDE+/-DDDDD. 305 * @param roundedUp Boolean value indicating if the s digits were rounded-up. 306 * @param allDecimalDigits Boolean value indicating if the digits in s are 307 * an exact decimal representation of the double that was passed. 308 */ 309 private void set(boolean isNegative, String s, 310 boolean roundedUp, boolean allDecimalDigits, 311 int maximumDigits, boolean fixedPoint) { 312 this.isNegative = isNegative; 313 int len = s.length(); 314 char[] source = getDataChars(len); 315 s.getChars(0, len, source, 0); 316 317 decimalAt = -1; 318 count = 0; 319 int exponent = 0; 320 // Number of zeros between decimal point and first non-zero digit after 321 // decimal point, for numbers < 1. 322 int leadingZerosAfterDecimal = 0; 323 boolean nonZeroDigitSeen = false; 324 325 for (int i = 0; i < len; ) { 326 char c = source[i++]; 327 if (c == '.') { 328 decimalAt = count; 329 } else if (c == 'e' || c == 'E') { 591 } 592 break; 593 case UNNECESSARY: 594 for (int i=maximumDigits; i<count; ++i) { 595 if (digits[i] != '0') { 596 throw new ArithmeticException( 597 "Rounding needed with the rounding mode being set to RoundingMode.UNNECESSARY"); 598 } 599 } 600 break; 601 default: 602 assert false; 603 } 604 } 605 return false; 606 } 607 608 /** 609 * Utility routine to set the value of the digit list from a long 610 */ 611 final void set(boolean isNegative, long source) { 612 set(isNegative, source, 0); 613 } 614 615 /** 616 * Set the digit list to a representation of the given long value. 617 * @param isNegative Boolean value indicating whether the number is negative. 618 * @param source Value to be converted; must be >= 0 or == 619 * Long.MIN_VALUE. 620 * @param maximumDigits The most digits which should be converted. 621 * If maximumDigits is lower than the number of significant digits 622 * in source, the representation will be rounded. Ignored if <= 0. 623 */ 624 final void set(boolean isNegative, long source, int maximumDigits) { 625 this.isNegative = isNegative; 626 627 // This method does not expect a negative number. However, 628 // "source" can be a Long.MIN_VALUE (-9223372036854775808), 629 // if the number being formatted is a Long.MIN_VALUE. In that 630 // case, it will be formatted as -Long.MIN_VALUE, a number 631 // which is outside the legal range of a long, but which can 632 // be represented by DigitList. 633 if (source <= 0) { 634 if (source == Long.MIN_VALUE) { 635 decimalAt = count = MAX_COUNT; 636 System.arraycopy(LONG_MIN_REP, 0, digits, 0, count); 637 } else { 638 decimalAt = count = 0; // Values <= 0 format as zero 639 } 640 } else { 641 // Rewritten to improve performance. I used to call 642 // Long.toString(), which was about 4x slower than this code. 643 int left = MAX_COUNT; 644 int right; |