JDK-4917089 : sqe-lib : prototype :Tiger java.math.BigDecimal divideToIntegralValue(divisor,m
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.math
  • Affected Version: 5.0
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2003-09-04
  • Updated: 2006-09-22
  • Resolved: 2003-09-12
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
5.0 tigerFixed
Related Reports
Relates :  
Relates :  
Description
Tiger java.math.BigDecimal  platform :win2000
divideToIntegralValue(divisorBD,mc)

for the following data point and MathContext
String dividend = "123456789000";
String divisor = "1";
MathContext mc = new MathContext(9,RoundingMode.DOWN);

I am getting the Exception.

java.lang.ArithmeticException: Division impossible

I am expecting the output as: 123456789000 with a scale of -3.

The java prototype version used is:
(build 1.5.0-internal-darcy_18_aug_2003_12_29)

The Test program is:
-------------------

import java.math.*;
public class Test  {
    public static void main(String args[]) throws Exception {
        String dividend = "123456789000";
        String divisor = "1";
        BigDecimal dividendBD = new BigDecimal(dividend);
        BigDecimal divisorBD  = new BigDecimal(divisor);
        MathContext mc = new MathContext(9,RoundingMode.DOWN);
        BigDecimal quotientDivideInteger = dividendBD.divideToIntegralValue(divisorBD,mc);
        System.out.println("quotientDivideInteger " + quotientDivideInteger.longValue() + " scale = " + quotientDivideInteger.scale());
     }
 }

---------------The output is----and java version used-------------

D:\testing>java Test
Exception in thread "main" java.lang.ArithmeticException: Division impossible
        at java.math.BigDecimal.divideToIntegralValue(BigDecimal.java:1464)
        at Test.main(Test.java:9)

D:\testing>java -version
java version "1.5.0-internal"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-internal-darcy_18_
aug_2003_12_29)
Java HotSpot(TM) Client VM (build 1.5.0-beta-b15, mixed mode)

---------expected output is:

I am expecting the output as: 123456789000 with a scale of -3.

###@###.### 2003-09-03

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: tiger FIXED IN: tiger INTEGRATED IN: tiger tiger-b20
14-06-2004

SUGGESTED FIX src/share/classes/java/math>sccs sccsdiff -r1.45 -r1.46 BigDecimal.java ------- BigDecimal.java ------- 152c152 < * For example, for result of the <tt>pow</tt> method using the --- > * For example, the result of the <tt>pow</tt> method using the 154,155c154,155 < * occasionally differ from the rounded mathematical result off by one < * unit in the last place (one <i>ulp</i>). --- > * occasionally differ from the rounded mathematical result by more > * than one unit in the last place, one <i>{@linkplain #ulp() ulp}</i>. 179,180c179,183 < * are interpreted similarly. < * --- > * are interpreted similarly. Square brackets are used to represent > * the particular <tt>BigInteger</tt> and scale pair defining a > * <tt>BigDecimal</tt> value; for example [19, 2] is the > * <tt>BigDecimal</tt> numerically equal to 0.19 having a scale of 2. > * 931c934 < * If either number is zero and the precision setting is non-zero then --- > * If either number is zero and the precision setting is nonzero then 1389,1392c1392,1399 < * of <tt>(this / divisor)</tt>, with rounding according to the < * context settings. The < * preferred scale of the result is <code>(this.scale() - < * divisor.scale())</code>. --- > * of <tt>(this / divisor)</tt>. Since the integer part of the > * exact quotient does not depend on the rounding mode, the > * rounding mode does not affect the values returned by this > * method. The preferred scale of the result is > * <code>(this.scale() - divisor.scale())</code>. An > * <tt>ArithmeticException</tt> is thrown if the integer part of > * the exact quotient needs more than <tt>mc.precision</tt> > * digits. 1394d1400 < * 1401a1408 > * @author Joseph D. Darcy 1404c1411,1412 < if (mc.precision == 0) --- > if (mc.precision == 0 || // exact result > (this.abs().compareTo(divisor.abs()) < 0) ) // zero result 1406c1414,1417 < BigDecimal lhs=this; --- > > // Calculate preferred scale > int preferredScale = (int)Math.max(Math.min((long)this.scale() - divisor.scale(), > Integer.MAX_VALUE), Integer.MIN_VALUE); 1408,1417c1419,1437 < // fastpath wild cases < if (((this.precision() - 1 - this.scale) - < (divisor.precision() - 1 - divisor.scale) - 1) > mc.precision) < throw new ArithmeticException("Division impossible"); < BigDecimal result = lhs.divideToIntegralValue(divisor); < int precisionDiff = result.precision() - mc.precision; < if (precisionDiff > 0 ) { < // Try stripping off trailing zeros to reduce the precision < result.stripZerosToMatchScale((long)result.scale() - precisionDiff); < if (result.precision() > mc.precision) --- > /* > * Perform a normal divide to mc.precision digits. If the > * remainder has absolute value less than the divisor, the > * integer portion of the quotient fits into mc.precision > * digits. Next, remove any fractional digits from the > * quotient and adjust the scale to the preferred value. > */ > BigDecimal result = this.divide(divisor, new MathContext(mc.precision, > RoundingMode.DOWN)); > int resultScale = result.scale(); > > if (result.scale() < 0) { > /* > * Result is an integer. See if quotient represents the > * full integer portion of the exact quotient; if it does, > * the computed remainder will be less than the divisor. > */ > BigDecimal product = result.multiply(divisor); > if (this.subtract(product).abs().compareTo(divisor.abs()) > 0) { 1418a1439,1446 > } > } else if (result.scale() > 0) { > /* > * Integer portion of quotient will fit into precision > * digits; recompute quotient to scale 0 to avoid double > * rounding and then try to adjust, if necessary. > */ > result = result.setScale(0, RoundingMode.DOWN); 1420c1448,1456 < return result; --- > // else result.scale() == 0; > > int precisionDiff; > if ((preferredScale > result.scale()) && > (precisionDiff = mc.precision - result.precision()) > 0 ) { > return result.setScale(result.scale() + > Math.min(precisionDiff, preferredScale - result.scale) ); > } else > return result.stripZerosToMatchScale(preferredScale); 1547a1584,1586 > * Note that future releases may expand the allowable exponent > * range of this method. > * 1556c1595,1598 < return new BigDecimal(intVal.pow(n), scale * n); --- > // No need to calculate pow(n) if result will over/underflow. > // Don't attempt to support "supernormal" numbers. > int newScale = checkScale((long)scale * n); > return new BigDecimal(intVal.pow(n), newScale); 1562,1564c1604,1610 < * <tt>(this<sup>n</sup>)</tt>, computed using the algorithm < * defined in ANSI standard X3.274-1996 with rounding according to < * the context settings. The X3.274-1996 algorithm is: --- > * <tt>(this<sup>n</sup>)</tt>. The current implementation uses > * the core algorithm defined in ANSI standard X3.274-1996 with > * rounding according to the context settings. In general, the > * returned numerical value is within two ulps of the exact > * numerical value for the chosen precision. Note that future > * releases may use a different algorithm with a decreased > * allowable error bound and increased allowable exponent range. 1565a1612,1613 > * <p>The X3.274-1996 algorithm is: > * 1793c1841 < * digit prior to a non-zero discarded fraction. Note that this rounding --- > * digit prior to a nonzero discarded fraction. Note that this rounding 2307,2308c2355,2356 < * <p>Returns a string that represents the <tt>BigDecimal</tt>, as < * described in the {@link #toString} method, except that if --- > * <p>Returns a string that represents the <tt>BigDecimal</tt> as > * described in the {@link #toString()} method, except that if 2315c2363 < * unlike the output of {@link toString}, the output of this --- > * unlike the output of {@link #toString()}, the output of this 2319c2367 < * #toString string constructor}. The result of this method meets --- > * #BigDecimal(String) string constructor}. The result of this method meets 2321c2369 < * result from applying the string constructor. --- > * result from applying the string constructor to the method's output. 2371,2372c2419,2420 < * checking for lost information. An exception is thrown if the < * decimal part (if any) is non-zero. --- > * checking for lost information. An exception is thrown if this > * <tt>BigDecimal</tt> has a nonzero fractional part. 2375,2376c2423,2424 < * @throws ArithmeticException if <tt>this</tt> has a non-zero < * decimal part. --- > * @throws ArithmeticException if <tt>this</tt> has a nonzero > * fractional part. 2396c2444 < * overall magnitude and precision of the <tt>BigDecimal</tt> value as well --- > * overall magnitude and precision of this <tt>BigDecimal</tt> value as well 2407,2408c2455,2456 < * for lost information. If the <tt>BigDecimal</tt> has a < * non-zero decimal part or is out of the possible range for a --- > * for lost information. If this <tt>BigDecimal</tt> has a > * nonzero fractional part or is out of the possible range for a 2413,2414c2461,2462 < * @throws ArithmeticException if <tt>this</tt> has a non-zero < * decimal part, or will not fit in a <tt>long</tt>. --- > * @throws ArithmeticException if <tt>this</tt> has a nonzero > * fractional part, or will not fit in a <tt>long</tt>. 2458c2506 < * overall magnitude and precision of the <tt>BigDecimal</tt> --- > * overall magnitude and precision of this <tt>BigDecimal</tt> 2469,2470c2517,2518 < * for lost information. If the <tt>BigDecimal</tt> has a < * non-zero decimal part or is out of the possible range for an --- > * for lost information. If this <tt>BigDecimal</tt> has a > * nonzero fractional part or is out of the possible range for an 2475,2476c2523,2524 < * @throws ArithmeticException if <tt>this</tt> has a non-zero < * decimal part, or will not fit in an <tt>int</tt>. --- > * @throws ArithmeticException if <tt>this</tt> has a nonzero > * fractional part, or will not fit in an <tt>int</tt>. 2489,2490c2537,2538 < * for lost information. If the <tt>BigDecimal</tt> has a < * non-zero decimal part or is out of the possible range for a --- > * for lost information. If this <tt>BigDecimal</tt> has a > * nonzero fractional part or is out of the possible range for a 2495,2496c2543,2544 < * @throws ArithmeticException if <tt>this</tt> has a non-zero < * decimal part, or will not fit in a <tt>short</tt>. --- > * @throws ArithmeticException if <tt>this</tt> has a nonzero > * fractional part, or will not fit in a <tt>short</tt>. 2509,2510c2557,2558 < * for lost information. If the <tt>BigDecimal</tt> has a < * non-zero decimal part or is out of the possible range for a --- > * for lost information. If this <tt>BigDecimal</tt> has a > * nonzero fractional part or is out of the possible range for a 2515,2516c2563,2564 < * @throws ArithmeticException if <tt>this</tt> has a non-zero < * decimal part, or will not fit in a <tt>byte</tt>. --- > * @throws ArithmeticException if <tt>this</tt> has a nonzero > * fractional part, or will not fit in a <tt>byte</tt>. 2572,2577c2620,2628 < * Returns the size of an ulp of this <tt>BigDecimal</tt>. An ulp < * of a <tt>BigDecimal</tt> value is the positive distance between < * this value and the <tt>BigDecimal</tt> value next larger in < * magnitude with the same number of digits. The result is stored < * with the same scale as <code>this</code> so the result is < * represented as <code>[1, this.scale()]</code>. --- > * Returns the size of an ulp, a unit in the last place, of this > * <tt>BigDecimal</tt>. An ulp of a nonzero <tt>BigDecimal</tt> > * value is the positive distance between this value and the > * <tt>BigDecimal</tt> value next larger in magnitude with the > * same number of digits. An ulp of a zero value is numerically > * equal to 1 with the scale of <tt>this</tt>. The result is > * stored with the same scale as <code>this</code> so the result > * for zero and nonzero values is equal to <code>[1, > * this.scale()]</code>. 2579,2584d2629 < * <p>Special Cases: < * <ul> < * <li> If the argument is zero, then the result is < * one, represented as 1 with a scale of 0. < * </ul> < * 2768c2813 < // we have a non-zero magnitude --- > // we have a nonzero magnitude 2779c2824 < // down to a simple non-zero integer --- > // down to a simple nonzero integer ###@###.### 2003-09-08
08-09-2003

EVALUATION A valid bug. ###@###.### 2003-09-05
05-09-2003