summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony Balkissoon <abalkiss@redhat.com>2006-03-01 20:14:48 +0000
committerAnthony Balkissoon <abalkiss@redhat.com>2006-03-01 20:14:48 +0000
commit789bb86a1bfe9953bfeb6b5d9b08aaf58fd6e108 (patch)
tree1e2888eb4729a31d94525a3da747c5ac19e567a7
parented8896b057bb22611510e9da693cf4f8d4833bdb (diff)
downloadclasspath-789bb86a1bfe9953bfeb6b5d9b08aaf58fd6e108.tar.gz
2006-03-01 Anthony Balkissoon <abalkiss@redhat.com>
* java/math/BigDecimal.java: (precision): Fixed overflow problem with large numbers. (longValueExact): New method. (intValueExact): Likewise. (byteValueExact): Likewise. (shortValueExact): Likewise.
-rw-r--r--ChangeLog9
-rw-r--r--java/math/BigDecimal.java87
2 files changed, 89 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index ef3339737..5490624c1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,15 @@
2006-03-01 Anthony Balkissoon <abalkiss@redhat.com>
* java/math/BigDecimal.java:
+ (precision): Fixed overflow problem with large numbers.
+ (longValueExact): New method.
+ (intValueExact): Likewise.
+ (byteValueExact): Likewise.
+ (shortValueExact): Likewise.
+
+2006-03-01 Anthony Balkissoon <abalkiss@redhat.com>
+
+ * java/math/BigDecimal.java:
(remainder(BigDecimal)): New method.
(divideAndRemainder(BigDecimal)): Likewise.
(divideToIntegralValue(BigDecimal)): Likewise.
diff --git a/java/math/BigDecimal.java b/java/math/BigDecimal.java
index 834f7f058..2726cdf87 100644
--- a/java/math/BigDecimal.java
+++ b/java/math/BigDecimal.java
@@ -1023,13 +1023,11 @@ public class BigDecimal extends Number implements Comparable<BigDecimal>
{
if (precision == 0)
{
- precision = numDigitsInLong(intVal.longValue());
- // If numDigitsInLong returns 19 then we use numDigitsInBigInteger
- // to determine if there are actually more than 19 digits in intVal.
- if (precision == 19)
+ if (intVal.compareTo(BigInteger.TEN.pow(18)) == 1)
precision = numDigitsInBigInteger(intVal);
- }
-
+ else
+ precision = numDigitsInLong(intVal.longValue());
+ }
return precision;
}
@@ -1051,7 +1049,7 @@ public class BigDecimal extends Number implements Comparable<BigDecimal>
/**
* This method determines the number of digits in the long value l.
- * @param l the long value
+ * @param l1 the long value
* @return the number of digits in l
*/
private static int numDigitsInLong(long l1)
@@ -1536,4 +1534,79 @@ public class BigDecimal extends Number implements Comparable<BigDecimal>
{
return new BigDecimal(BigInteger.ONE, scale);
}
+
+ /**
+ * Converts this BigDecimal to a long value.
+ * @return the long value
+ * @throws ArithmeticException if rounding occurs or if overflow occurs
+ * @since 1.5
+ */
+ public long longValueExact()
+ {
+ // Set scale will throw an exception if rounding occurs.
+ BigDecimal temp = setScale(0, ROUND_UNNECESSARY);
+ BigInteger tempVal = temp.intVal;
+ // Check for overflow.
+ long result = intVal.longValue();
+ if (tempVal.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 1
+ || (result < 0 && signum() == 1) || (result > 0 && signum() == -1))
+ throw new ArithmeticException("this BigDecimal is too " +
+ "large to fit into the return type");
+
+ return intVal.longValue();
+ }
+
+ /**
+ * Converts this BigDecimal into an int by first calling longValueExact
+ * and then checking that the <code>long</code> returned from that
+ * method fits into an <code>int</code>.
+ * @return an int whose value is <code>this</code>
+ * @throws ArithmeticException if this BigDecimal has a fractional part
+ * or is too large to fit into an int.
+ * @since 1.5
+ */
+ public int intValueExact()
+ {
+ long temp = longValueExact();
+ int result = (int)temp;
+ if (result != temp)
+ throw new ArithmeticException ("this BigDecimal cannot fit into an int");
+ return result;
+ }
+
+ /**
+ * Converts this BigDecimal into a byte by first calling longValueExact
+ * and then checking that the <code>long</code> returned from that
+ * method fits into a <code>byte</code>.
+ * @return a byte whose value is <code>this</code>
+ * @throws ArithmeticException if this BigDecimal has a fractional part
+ * or is too large to fit into a byte.
+ * @since 1.5
+ */
+ public byte byteValueExact()
+ {
+ long temp = longValueExact();
+ byte result = (byte)temp;
+ if (result != temp)
+ throw new ArithmeticException ("this BigDecimal cannot fit into a byte");
+ return result;
+ }
+
+ /**
+ * Converts this BigDecimal into a short by first calling longValueExact
+ * and then checking that the <code>long</code> returned from that
+ * method fits into a <code>short</code>.
+ * @return a short whose value is <code>this</code>
+ * @throws ArithmeticException if this BigDecimal has a fractional part
+ * or is too large to fit into a short.
+ * @since 1.5
+ */
+ public short shortValueExact()
+ {
+ long temp = longValueExact();
+ short result = (short)temp;
+ if (result != temp)
+ throw new ArithmeticException ("this BigDecimal cannot fit into a short");
+ return result;
+ }
}