src/share/classes/java/math/BigDecimal.java

Print this page
rev 7924 : 6378503: In java.math.BigDecimal, division by one returns zero
6446965: Using BigDecimal.divideToIntegralValue with extreme scales can lead to an incorrect result
Summary: Fix overflow of ints and ensure appropriate values passed to checkScaleNonZero()
Reviewed-by: darcy, martin
Contributed-by: Brian Burkhalter <brian.burkhalter@oracle.com>


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);