2642 if (xsign != ysign)
2643 return (xsign > ysign) ? 1 : -1;
2644 if (xsign == 0)
2645 return 0;
2646 int cmp = compareMagnitude(val);
2647 return (xsign > 0) ? cmp : -cmp;
2648 }
2649
2650 /**
2651 * Version of compareTo that ignores sign.
2652 */
2653 private int compareMagnitude(BigDecimal val) {
2654 // Match scales, avoid unnecessary inflation
2655 long ys = val.intCompact;
2656 long xs = this.intCompact;
2657 if (xs == 0)
2658 return (ys == 0) ? 0 : -1;
2659 if (ys == 0)
2660 return 1;
2661
2662 int sdiff = this.scale - val.scale;
2663 if (sdiff != 0) {
2664 // Avoid matching scales if the (adjusted) exponents differ
2665 int xae = this.precision() - this.scale; // [-1]
2666 int yae = val.precision() - val.scale; // [-1]
2667 if (xae < yae)
2668 return -1;
2669 if (xae > yae)
2670 return 1;
2671 BigInteger rb = null;
2672 if (sdiff < 0) {
2673 if ( (xs == INFLATED ||
2674 (xs = longMultiplyPowerTen(xs, -sdiff)) == INFLATED) &&
2675 ys == INFLATED) {
2676 rb = bigMultiplyPowerTen(-sdiff);
2677 return rb.compareMagnitude(val.intVal);
2678 }
2679 } else { // sdiff > 0
2680 if ( (ys == INFLATED ||
2681 (ys = longMultiplyPowerTen(ys, sdiff)) == INFLATED) &&
2682 xs == INFLATED) {
2683 rb = val.bigMultiplyPowerTen(sdiff);
2684 return this.intVal.compareMagnitude(rb);
2685 }
2686 }
2687 }
2688 if (xs != INFLATED)
2689 return (ys != INFLATED) ? longCompareMagnitude(xs, ys) : -1;
2690 else if (ys != INFLATED)
2691 return 1;
2692 else
2693 return this.intVal.compareMagnitude(val.intVal);
2694 }
2695
2696 /**
2697 * Compares this {@code BigDecimal} with the specified
2698 * {@code Object} for equality. Unlike {@link
2699 * #compareTo(BigDecimal) compareTo}, this method considers two
2700 * {@code BigDecimal} objects equal only if they are equal in
2701 * value and scale (thus 2.0 is not equal to 2.00 when compared by
2702 * this method).
2703 *
4528 *
4529 * Fast path - used only when (xscale <= yscale && yscale < 18
4530 * && mc.presision<18) {
4531 */
4532 private static BigDecimal divideSmallFastPath(final long xs, int xscale,
4533 final long ys, int yscale,
4534 long preferredScale, MathContext mc) {
4535 int mcp = mc.precision;
4536 int roundingMode = mc.roundingMode.oldMode;
4537
4538 assert (xscale <= yscale) && (yscale < 18) && (mcp < 18);
4539 int xraise = yscale - xscale; // xraise >=0
4540 long scaledX = (xraise==0) ? xs :
4541 longMultiplyPowerTen(xs, xraise); // can't overflow here!
4542 BigDecimal quotient;
4543
4544 int cmp = longCompareMagnitude(scaledX, ys);
4545 if(cmp > 0) { // satisfy constraint (b)
4546 yscale -= 1; // [that is, divisor *= 10]
4547 int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
4548 if (checkScaleNonZero((long) mcp + yscale) > xscale) {
4549 // assert newScale >= xscale
4550 int raise = checkScaleNonZero((long) mcp + yscale - xscale);
4551 long scaledXs;
4552 if ((scaledXs = longMultiplyPowerTen(xs, raise)) == INFLATED) {
4553 quotient = null;
4554 if((mcp-1) >=0 && (mcp-1)<LONG_TEN_POWERS_TABLE.length) {
4555 quotient = multiplyDivideAndRound(LONG_TEN_POWERS_TABLE[mcp-1], scaledX, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
4556 }
4557 if(quotient==null) {
4558 BigInteger rb = bigMultiplyPowerTen(scaledX,mcp-1);
4559 quotient = divideAndRound(rb, ys,
4560 scl, roundingMode, checkScaleNonZero(preferredScale));
4561 }
4562 } else {
4563 quotient = divideAndRound(scaledXs, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
4564 }
4565 } else {
4566 int newScale = checkScaleNonZero((long) xscale - mcp);
4567 // assert newScale >= yscale
4568 if (newScale == yscale) { // easy case
4609 }
4610
4611 /**
4612 * Returns a {@code BigDecimal} whose value is {@code (xs /
4613 * ys)}, with rounding according to the context settings.
4614 */
4615 private static BigDecimal divide(final long xs, int xscale, final long ys, int yscale, long preferredScale, MathContext mc) {
4616 int mcp = mc.precision;
4617 if(xscale <= yscale && yscale < 18 && mcp<18) {
4618 return divideSmallFastPath(xs, xscale, ys, yscale, preferredScale, mc);
4619 }
4620 if (compareMagnitudeNormalized(xs, xscale, ys, yscale) > 0) {// satisfy constraint (b)
4621 yscale -= 1; // [that is, divisor *= 10]
4622 }
4623 int roundingMode = mc.roundingMode.oldMode;
4624 // In order to find out whether the divide generates the exact result,
4625 // we avoid calling the above divide method. 'quotient' holds the
4626 // return BigDecimal object whose scale will be set to 'scl'.
4627 int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
4628 BigDecimal quotient;
4629 if (checkScaleNonZero((long) mcp + yscale) > xscale) {
4630 int raise = checkScaleNonZero((long) mcp + yscale - xscale);
4631 long scaledXs;
4632 if ((scaledXs = longMultiplyPowerTen(xs, raise)) == INFLATED) {
4633 BigInteger rb = bigMultiplyPowerTen(xs,raise);
4634 quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
4635 } else {
4636 quotient = divideAndRound(scaledXs, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
4637 }
4638 } else {
4639 int newScale = checkScaleNonZero((long) xscale - mcp);
4640 // assert newScale >= yscale
4641 if (newScale == yscale) { // easy case
4642 quotient = divideAndRound(xs, ys, scl, roundingMode,checkScaleNonZero(preferredScale));
4643 } else {
4644 int raise = checkScaleNonZero((long) newScale - yscale);
4645 long scaledYs;
4646 if ((scaledYs = longMultiplyPowerTen(ys, raise)) == INFLATED) {
4647 BigInteger rb = bigMultiplyPowerTen(ys,raise);
4648 quotient = divideAndRound(BigInteger.valueOf(xs),
4649 rb, scl, roundingMode,checkScaleNonZero(preferredScale));
4656 return doRound(quotient,mc);
4657 }
4658
4659 /**
4660 * Returns a {@code BigDecimal} whose value is {@code (xs /
4661 * ys)}, with rounding according to the context settings.
4662 */
4663 private static BigDecimal divide(BigInteger xs, int xscale, long ys, int yscale, long preferredScale, MathContext mc) {
4664 // Normalize dividend & divisor so that both fall into [0.1, 0.999...]
4665 if ((-compareMagnitudeNormalized(ys, yscale, xs, xscale)) > 0) {// satisfy constraint (b)
4666 yscale -= 1; // [that is, divisor *= 10]
4667 }
4668 int mcp = mc.precision;
4669 int roundingMode = mc.roundingMode.oldMode;
4670
4671 // In order to find out whether the divide generates the exact result,
4672 // we avoid calling the above divide method. 'quotient' holds the
4673 // return BigDecimal object whose scale will be set to 'scl'.
4674 BigDecimal quotient;
4675 int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
4676 if (checkScaleNonZero((long) mcp + yscale) > xscale) {
4677 int raise = checkScaleNonZero((long) mcp + yscale - xscale);
4678 BigInteger rb = bigMultiplyPowerTen(xs,raise);
4679 quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
4680 } else {
4681 int newScale = checkScaleNonZero((long) xscale - mcp);
4682 // assert newScale >= yscale
4683 if (newScale == yscale) { // easy case
4684 quotient = divideAndRound(xs, ys, scl, roundingMode,checkScaleNonZero(preferredScale));
4685 } else {
4686 int raise = checkScaleNonZero((long) newScale - yscale);
4687 long scaledYs;
4688 if ((scaledYs = longMultiplyPowerTen(ys, raise)) == INFLATED) {
4689 BigInteger rb = bigMultiplyPowerTen(ys,raise);
4690 quotient = divideAndRound(xs, rb, scl, roundingMode,checkScaleNonZero(preferredScale));
4691 } else {
4692 quotient = divideAndRound(xs, scaledYs, scl, roundingMode,checkScaleNonZero(preferredScale));
4693 }
4694 }
4695 }
4696 // doRound, here, only affects 1000000000 case.
4697 return doRound(quotient, mc);
4698 }
4699
4700 /**
4701 * Returns a {@code BigDecimal} whose value is {@code (xs /
4702 * ys)}, with rounding according to the context settings.
4703 */
4704 private static BigDecimal divide(long xs, int xscale, BigInteger ys, int yscale, long preferredScale, MathContext mc) {
4705 // Normalize dividend & divisor so that both fall into [0.1, 0.999...]
4706 if (compareMagnitudeNormalized(xs, xscale, ys, yscale) > 0) {// satisfy constraint (b)
4707 yscale -= 1; // [that is, divisor *= 10]
4708 }
4709 int mcp = mc.precision;
4710 int roundingMode = mc.roundingMode.oldMode;
4711
4712 // In order to find out whether the divide generates the exact result,
4713 // we avoid calling the above divide method. 'quotient' holds the
4714 // return BigDecimal object whose scale will be set to 'scl'.
4715 BigDecimal quotient;
4716 int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
4717 if (checkScaleNonZero((long) mcp + yscale) > xscale) {
4718 int raise = checkScaleNonZero((long) mcp + yscale - xscale);
4719 BigInteger rb = bigMultiplyPowerTen(xs,raise);
4720 quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
4721 } else {
4722 int newScale = checkScaleNonZero((long) xscale - mcp);
4723 int raise = checkScaleNonZero((long) newScale - yscale);
4724 BigInteger rb = bigMultiplyPowerTen(ys,raise);
4725 quotient = divideAndRound(BigInteger.valueOf(xs), rb, scl, roundingMode,checkScaleNonZero(preferredScale));
4726 }
4727 // doRound, here, only affects 1000000000 case.
4728 return doRound(quotient, mc);
4729 }
4730
4731 /**
4732 * Returns a {@code BigDecimal} whose value is {@code (xs /
4733 * ys)}, with rounding according to the context settings.
4734 */
4735 private static BigDecimal divide(BigInteger xs, int xscale, BigInteger ys, int yscale, long preferredScale, MathContext mc) {
4736 // Normalize dividend & divisor so that both fall into [0.1, 0.999...]
4737 if (compareMagnitudeNormalized(xs, xscale, ys, yscale) > 0) {// satisfy constraint (b)
4738 yscale -= 1; // [that is, divisor *= 10]
4739 }
4740 int mcp = mc.precision;
4741 int roundingMode = mc.roundingMode.oldMode;
4742
4743 // In order to find out whether the divide generates the exact result,
4744 // we avoid calling the above divide method. 'quotient' holds the
4745 // return BigDecimal object whose scale will be set to 'scl'.
4746 BigDecimal quotient;
4747 int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
4748 if (checkScaleNonZero((long) mcp + yscale) > xscale) {
4749 int raise = checkScaleNonZero((long) mcp + yscale - xscale);
4750 BigInteger rb = bigMultiplyPowerTen(xs,raise);
4751 quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
4752 } else {
4753 int newScale = checkScaleNonZero((long) xscale - mcp);
4754 int raise = checkScaleNonZero((long) newScale - yscale);
4755 BigInteger rb = bigMultiplyPowerTen(ys,raise);
4756 quotient = divideAndRound(xs, rb, scl, roundingMode,checkScaleNonZero(preferredScale));
4757 }
4758 // doRound, here, only affects 1000000000 case.
4759 return doRound(quotient, mc);
4760 }
4761
4762 /*
4763 * performs divideAndRound for (dividend0*dividend1, divisor)
4764 * returns null if quotient can't fit into long value;
4765 */
4766 private static BigDecimal multiplyDivideAndRound(long dividend0, long dividend1, long divisor, int scale, int roundingMode,
4767 int preferredScale) {
4768 int qsign = Long.signum(dividend0)*Long.signum(dividend1)*Long.signum(divisor);
|
2642 if (xsign != ysign)
2643 return (xsign > ysign) ? 1 : -1;
2644 if (xsign == 0)
2645 return 0;
2646 int cmp = compareMagnitude(val);
2647 return (xsign > 0) ? cmp : -cmp;
2648 }
2649
2650 /**
2651 * Version of compareTo that ignores sign.
2652 */
2653 private int compareMagnitude(BigDecimal val) {
2654 // Match scales, avoid unnecessary inflation
2655 long ys = val.intCompact;
2656 long xs = this.intCompact;
2657 if (xs == 0)
2658 return (ys == 0) ? 0 : -1;
2659 if (ys == 0)
2660 return 1;
2661
2662 long sdiff = (long)this.scale - val.scale;
2663 if (sdiff != 0) {
2664 // Avoid matching scales if the (adjusted) exponents differ
2665 long xae = (long)this.precision() - this.scale; // [-1]
2666 long yae = (long)val.precision() - val.scale; // [-1]
2667 if (xae < yae)
2668 return -1;
2669 if (xae > yae)
2670 return 1;
2671 BigInteger rb = null;
2672 if (sdiff < 0) {
2673 // The cases sdiff <= Integer.MIN_VALUE intentionally fall through.
2674 if ( sdiff > Integer.MIN_VALUE &&
2675 (xs == INFLATED ||
2676 (xs = longMultiplyPowerTen(xs, (int)-sdiff)) == INFLATED) &&
2677 ys == INFLATED) {
2678 rb = bigMultiplyPowerTen((int)-sdiff);
2679 return rb.compareMagnitude(val.intVal);
2680 }
2681 } else { // sdiff > 0
2682 // The cases sdiff > Integer.MAX_VALUE intentionally fall through.
2683 if ( sdiff <= Integer.MAX_VALUE &&
2684 (ys == INFLATED ||
2685 (ys = longMultiplyPowerTen(ys, (int)sdiff)) == INFLATED) &&
2686 xs == INFLATED) {
2687 rb = val.bigMultiplyPowerTen((int)sdiff);
2688 return this.intVal.compareMagnitude(rb);
2689 }
2690 }
2691 }
2692 if (xs != INFLATED)
2693 return (ys != INFLATED) ? longCompareMagnitude(xs, ys) : -1;
2694 else if (ys != INFLATED)
2695 return 1;
2696 else
2697 return this.intVal.compareMagnitude(val.intVal);
2698 }
2699
2700 /**
2701 * Compares this {@code BigDecimal} with the specified
2702 * {@code Object} for equality. Unlike {@link
2703 * #compareTo(BigDecimal) compareTo}, this method considers two
2704 * {@code BigDecimal} objects equal only if they are equal in
2705 * value and scale (thus 2.0 is not equal to 2.00 when compared by
2706 * this method).
2707 *
4532 *
4533 * Fast path - used only when (xscale <= yscale && yscale < 18
4534 * && mc.presision<18) {
4535 */
4536 private static BigDecimal divideSmallFastPath(final long xs, int xscale,
4537 final long ys, int yscale,
4538 long preferredScale, MathContext mc) {
4539 int mcp = mc.precision;
4540 int roundingMode = mc.roundingMode.oldMode;
4541
4542 assert (xscale <= yscale) && (yscale < 18) && (mcp < 18);
4543 int xraise = yscale - xscale; // xraise >=0
4544 long scaledX = (xraise==0) ? xs :
4545 longMultiplyPowerTen(xs, xraise); // can't overflow here!
4546 BigDecimal quotient;
4547
4548 int cmp = longCompareMagnitude(scaledX, ys);
4549 if(cmp > 0) { // satisfy constraint (b)
4550 yscale -= 1; // [that is, divisor *= 10]
4551 int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
4552 if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) {
4553 // assert newScale >= xscale
4554 int raise = checkScaleNonZero((long) mcp + yscale - xscale);
4555 long scaledXs;
4556 if ((scaledXs = longMultiplyPowerTen(xs, raise)) == INFLATED) {
4557 quotient = null;
4558 if((mcp-1) >=0 && (mcp-1)<LONG_TEN_POWERS_TABLE.length) {
4559 quotient = multiplyDivideAndRound(LONG_TEN_POWERS_TABLE[mcp-1], scaledX, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
4560 }
4561 if(quotient==null) {
4562 BigInteger rb = bigMultiplyPowerTen(scaledX,mcp-1);
4563 quotient = divideAndRound(rb, ys,
4564 scl, roundingMode, checkScaleNonZero(preferredScale));
4565 }
4566 } else {
4567 quotient = divideAndRound(scaledXs, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
4568 }
4569 } else {
4570 int newScale = checkScaleNonZero((long) xscale - mcp);
4571 // assert newScale >= yscale
4572 if (newScale == yscale) { // easy case
4613 }
4614
4615 /**
4616 * Returns a {@code BigDecimal} whose value is {@code (xs /
4617 * ys)}, with rounding according to the context settings.
4618 */
4619 private static BigDecimal divide(final long xs, int xscale, final long ys, int yscale, long preferredScale, MathContext mc) {
4620 int mcp = mc.precision;
4621 if(xscale <= yscale && yscale < 18 && mcp<18) {
4622 return divideSmallFastPath(xs, xscale, ys, yscale, preferredScale, mc);
4623 }
4624 if (compareMagnitudeNormalized(xs, xscale, ys, yscale) > 0) {// satisfy constraint (b)
4625 yscale -= 1; // [that is, divisor *= 10]
4626 }
4627 int roundingMode = mc.roundingMode.oldMode;
4628 // In order to find out whether the divide generates the exact result,
4629 // we avoid calling the above divide method. 'quotient' holds the
4630 // return BigDecimal object whose scale will be set to 'scl'.
4631 int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
4632 BigDecimal quotient;
4633 if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) {
4634 int raise = checkScaleNonZero((long) mcp + yscale - xscale);
4635 long scaledXs;
4636 if ((scaledXs = longMultiplyPowerTen(xs, raise)) == INFLATED) {
4637 BigInteger rb = bigMultiplyPowerTen(xs,raise);
4638 quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
4639 } else {
4640 quotient = divideAndRound(scaledXs, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
4641 }
4642 } else {
4643 int newScale = checkScaleNonZero((long) xscale - mcp);
4644 // assert newScale >= yscale
4645 if (newScale == yscale) { // easy case
4646 quotient = divideAndRound(xs, ys, scl, roundingMode,checkScaleNonZero(preferredScale));
4647 } else {
4648 int raise = checkScaleNonZero((long) newScale - yscale);
4649 long scaledYs;
4650 if ((scaledYs = longMultiplyPowerTen(ys, raise)) == INFLATED) {
4651 BigInteger rb = bigMultiplyPowerTen(ys,raise);
4652 quotient = divideAndRound(BigInteger.valueOf(xs),
4653 rb, scl, roundingMode,checkScaleNonZero(preferredScale));
4660 return doRound(quotient,mc);
4661 }
4662
4663 /**
4664 * Returns a {@code BigDecimal} whose value is {@code (xs /
4665 * ys)}, with rounding according to the context settings.
4666 */
4667 private static BigDecimal divide(BigInteger xs, int xscale, long ys, int yscale, long preferredScale, MathContext mc) {
4668 // Normalize dividend & divisor so that both fall into [0.1, 0.999...]
4669 if ((-compareMagnitudeNormalized(ys, yscale, xs, xscale)) > 0) {// satisfy constraint (b)
4670 yscale -= 1; // [that is, divisor *= 10]
4671 }
4672 int mcp = mc.precision;
4673 int roundingMode = mc.roundingMode.oldMode;
4674
4675 // In order to find out whether the divide generates the exact result,
4676 // we avoid calling the above divide method. 'quotient' holds the
4677 // return BigDecimal object whose scale will be set to 'scl'.
4678 BigDecimal quotient;
4679 int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
4680 if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) {
4681 int raise = checkScaleNonZero((long) mcp + yscale - xscale);
4682 BigInteger rb = bigMultiplyPowerTen(xs,raise);
4683 quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
4684 } else {
4685 int newScale = checkScaleNonZero((long) xscale - mcp);
4686 // assert newScale >= yscale
4687 if (newScale == yscale) { // easy case
4688 quotient = divideAndRound(xs, ys, scl, roundingMode,checkScaleNonZero(preferredScale));
4689 } else {
4690 int raise = checkScaleNonZero((long) newScale - yscale);
4691 long scaledYs;
4692 if ((scaledYs = longMultiplyPowerTen(ys, raise)) == INFLATED) {
4693 BigInteger rb = bigMultiplyPowerTen(ys,raise);
4694 quotient = divideAndRound(xs, rb, scl, roundingMode,checkScaleNonZero(preferredScale));
4695 } else {
4696 quotient = divideAndRound(xs, scaledYs, scl, roundingMode,checkScaleNonZero(preferredScale));
4697 }
4698 }
4699 }
4700 // doRound, here, only affects 1000000000 case.
4701 return doRound(quotient, mc);
4702 }
4703
4704 /**
4705 * Returns a {@code BigDecimal} whose value is {@code (xs /
4706 * ys)}, with rounding according to the context settings.
4707 */
4708 private static BigDecimal divide(long xs, int xscale, BigInteger ys, int yscale, long preferredScale, MathContext mc) {
4709 // Normalize dividend & divisor so that both fall into [0.1, 0.999...]
4710 if (compareMagnitudeNormalized(xs, xscale, ys, yscale) > 0) {// satisfy constraint (b)
4711 yscale -= 1; // [that is, divisor *= 10]
4712 }
4713 int mcp = mc.precision;
4714 int roundingMode = mc.roundingMode.oldMode;
4715
4716 // In order to find out whether the divide generates the exact result,
4717 // we avoid calling the above divide method. 'quotient' holds the
4718 // return BigDecimal object whose scale will be set to 'scl'.
4719 BigDecimal quotient;
4720 int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
4721 if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) {
4722 int raise = checkScaleNonZero((long) mcp + yscale - xscale);
4723 BigInteger rb = bigMultiplyPowerTen(xs,raise);
4724 quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
4725 } else {
4726 int newScale = checkScaleNonZero((long) xscale - mcp);
4727 int raise = checkScaleNonZero((long) newScale - yscale);
4728 BigInteger rb = bigMultiplyPowerTen(ys,raise);
4729 quotient = divideAndRound(BigInteger.valueOf(xs), rb, scl, roundingMode,checkScaleNonZero(preferredScale));
4730 }
4731 // doRound, here, only affects 1000000000 case.
4732 return doRound(quotient, mc);
4733 }
4734
4735 /**
4736 * Returns a {@code BigDecimal} whose value is {@code (xs /
4737 * ys)}, with rounding according to the context settings.
4738 */
4739 private static BigDecimal divide(BigInteger xs, int xscale, BigInteger ys, int yscale, long preferredScale, MathContext mc) {
4740 // Normalize dividend & divisor so that both fall into [0.1, 0.999...]
4741 if (compareMagnitudeNormalized(xs, xscale, ys, yscale) > 0) {// satisfy constraint (b)
4742 yscale -= 1; // [that is, divisor *= 10]
4743 }
4744 int mcp = mc.precision;
4745 int roundingMode = mc.roundingMode.oldMode;
4746
4747 // In order to find out whether the divide generates the exact result,
4748 // we avoid calling the above divide method. 'quotient' holds the
4749 // return BigDecimal object whose scale will be set to 'scl'.
4750 BigDecimal quotient;
4751 int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
4752 if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) {
4753 int raise = checkScaleNonZero((long) mcp + yscale - xscale);
4754 BigInteger rb = bigMultiplyPowerTen(xs,raise);
4755 quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
4756 } else {
4757 int newScale = checkScaleNonZero((long) xscale - mcp);
4758 int raise = checkScaleNonZero((long) newScale - yscale);
4759 BigInteger rb = bigMultiplyPowerTen(ys,raise);
4760 quotient = divideAndRound(xs, rb, scl, roundingMode,checkScaleNonZero(preferredScale));
4761 }
4762 // doRound, here, only affects 1000000000 case.
4763 return doRound(quotient, mc);
4764 }
4765
4766 /*
4767 * performs divideAndRound for (dividend0*dividend1, divisor)
4768 * returns null if quotient can't fit into long value;
4769 */
4770 private static BigDecimal multiplyDivideAndRound(long dividend0, long dividend1, long divisor, int scale, int roundingMode,
4771 int preferredScale) {
4772 int qsign = Long.signum(dividend0)*Long.signum(dividend1)*Long.signum(divisor);
|