summaryrefslogtreecommitdiff
path: root/libjava/classpath/java/math
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/java/math')
-rw-r--r--libjava/classpath/java/math/BigDecimal.java67
-rw-r--r--libjava/classpath/java/math/BigInteger.java78
-rw-r--r--libjava/classpath/java/math/MathContext.java64
-rw-r--r--libjava/classpath/java/math/RoundingMode.java89
-rw-r--r--libjava/classpath/java/math/class-dependencies.conf58
5 files changed, 309 insertions, 47 deletions
diff --git a/libjava/classpath/java/math/BigDecimal.java b/libjava/classpath/java/math/BigDecimal.java
index bca9b12c28b..28c4d45d3eb 100644
--- a/libjava/classpath/java/math/BigDecimal.java
+++ b/libjava/classpath/java/math/BigDecimal.java
@@ -37,7 +37,7 @@ exception statement from your version. */
package java.math;
-public class BigDecimal extends Number implements Comparable
+public class BigDecimal extends Number implements Comparable<BigDecimal>
{
private BigInteger intVal;
private int scale;
@@ -672,7 +672,38 @@ public class BigDecimal extends Number implements Comparable
{
return divide (val, scale, roundingMode);
}
-
+
+ /**
+ * Returns a BigDecimal whose value is (this / val), with the specified scale
+ * and rounding according to the RoundingMode
+ * @param val the divisor
+ * @param scale the scale of the BigDecimal returned
+ * @param roundingMode the rounding mode to use
+ * @return a BigDecimal whose value is approximately (this / val)
+ * @throws ArithmeticException if divisor is zero or the rounding mode is
+ * UNNECESSARY but the specified scale cannot represent the value exactly
+ * @since 1.5
+ */
+ public BigDecimal divide(BigDecimal val,
+ int scale, RoundingMode roundingMode)
+ {
+ return divide (val, scale, roundingMode.ordinal());
+ }
+
+ /**
+ * Returns a BigDecimal whose value is (this / val) rounded according to the
+ * RoundingMode
+ * @param val the divisor
+ * @param roundingMode the rounding mode to use
+ * @return a BigDecimal whose value is approximately (this / val)
+ * @throws ArithmeticException if divisor is zero or the rounding mode is
+ * UNNECESSARY but the specified scale cannot represent the value exactly
+ */
+ public BigDecimal divide (BigDecimal val, RoundingMode roundingMode)
+ {
+ return divide (val, scale, roundingMode.ordinal());
+ }
+
public BigDecimal divide(BigDecimal val, int newScale, int roundingMode)
throws ArithmeticException, IllegalArgumentException
{
@@ -823,12 +854,7 @@ public class BigDecimal extends Number implements Comparable
return this;
}
- public int compareTo (Object obj)
- {
- return compareTo((BigDecimal) obj);
- }
-
- public int compareTo (BigDecimal val)
+ public int compareTo (BigDecimal val)
{
if (scale == val.scale)
return intVal.compareTo (val.intVal);
@@ -973,7 +999,7 @@ public class BigDecimal extends Number implements Comparable
{
return round(mc);
}
-
+
/**
* Returns a BigDecimal which is this BigDecimal rounded according to the
* MathContext rounding settings.
@@ -993,12 +1019,12 @@ public class BigDecimal extends Number implements Comparable
// Make a new BigDecimal which is the correct power of 10 to chop off
// the required number of digits and then call divide.
BigDecimal div = new BigDecimal(BigInteger.TEN.pow(numToChop));
- BigDecimal rounded = divide(div, scale, 4);
+ BigDecimal rounded = divide(div, scale, mc.getRoundingMode().ordinal());
rounded.scale -= numToChop;
rounded.precision = mcPrecision;
return rounded;
}
-
+
/**
* Returns the precision of this BigDecimal (the number of digits in the
* unscaled value). The precision of a zero value is 1.
@@ -1350,7 +1376,24 @@ public class BigDecimal extends Number implements Comparable
if( scale < 0 ) throw new ArithmeticException("Scale parameter < 0.");
return divide (ONE, scale, roundingMode);
}
-
+
+ /**
+ * Returns a BigDecimal whose value is the same as this BigDecimal but whose
+ * representation has a scale of <code>newScale</code>. If the scale is
+ * reduced then rounding may occur, according to the RoundingMode.
+ * @param newScale
+ * @param roundingMode
+ * @return a BigDecimal whose scale is as given, whose value is
+ * <code>this</code> with possible rounding
+ * @throws ArithmeticException if the rounding mode is UNNECESSARY but
+ * rounding is required
+ * @since 1.5
+ */
+ public BigDecimal setScale(int newScale, RoundingMode roundingMode)
+ {
+ return setScale(newScale, roundingMode.ordinal());
+ }
+
/**
* Returns a new BigDecimal constructed from the BigDecimal(String)
* constructor using the Double.toString(double) method to obtain
diff --git a/libjava/classpath/java/math/BigInteger.java b/libjava/classpath/java/math/BigInteger.java
index b57cf607e34..c897d8bf48d 100644
--- a/libjava/classpath/java/math/BigInteger.java
+++ b/libjava/classpath/java/math/BigInteger.java
@@ -1,5 +1,5 @@
/* java.math.BigInteger -- Arbitary precision integers
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -57,7 +57,7 @@ import java.util.Random;
* @date December 20, 1999.
* @status believed complete and correct.
*/
-public class BigInteger extends Number implements Comparable
+public class BigInteger extends Number implements Comparable<BigInteger>
{
/** All integers are stored in 2's-complement form.
* If words == null, the ival is the value of this BigInteger.
@@ -83,7 +83,8 @@ public class BigInteger extends Number implements Comparable
private static final int numFixNum = maxFixNum-minFixNum+1;
private static final BigInteger[] smallFixNums = new BigInteger[numFixNum];
- static {
+ static
+ {
for (int i = numFixNum; --i >= 0; )
smallFixNums[i] = new BigInteger(i + minFixNum);
}
@@ -92,14 +93,14 @@ public class BigInteger extends Number implements Comparable
* The constant zero as a BigInteger.
* @since 1.2
*/
- public static final BigInteger ZERO = smallFixNums[-minFixNum];
+ public static final BigInteger ZERO = smallFixNums[0 - minFixNum];
/**
* The constant one as a BigInteger.
* @since 1.2
*/
public static final BigInteger ONE = smallFixNums[1 - minFixNum];
-
+
/**
* The constant ten as a BigInteger.
* @since 1.5
@@ -197,8 +198,20 @@ public class BigInteger extends Number implements Comparable
private void init(int numBits, Random rnd)
{
int highbits = numBits & 31;
+ // minimum number of bytes to store the above number of bits
+ int highBitByteCount = (highbits + 7) / 8;
+ // number of bits to discard from the last byte
+ int discardedBitCount = highbits % 8;
+ if (discardedBitCount != 0)
+ discardedBitCount = 8 - discardedBitCount;
+ byte[] highBitBytes = new byte[highBitByteCount];
if (highbits > 0)
- highbits = rnd.nextInt() >>> (32 - highbits);
+ {
+ rnd.nextBytes(highBitBytes);
+ highbits = (highBitBytes[highBitByteCount - 1] & 0xFF) >>> discardedBitCount;
+ for (int i = highBitByteCount - 2; i >= 0; i--)
+ highbits = (highbits << 8) | (highBitBytes[i] & 0xFF);
+ }
int nwords = numBits / 32;
while (highbits == 0 && nwords > 0)
@@ -225,8 +238,13 @@ public class BigInteger extends Number implements Comparable
this(bitLength, rnd);
// Keep going until we find a probable prime.
+ BigInteger result;
while (true)
{
+ // ...but first ensure that BI has bitLength bits
+ result = setBit(bitLength - 1);
+ this.ival = result.ival;
+ this.words = result.words;
if (isProbablePrime(certainty))
return;
@@ -377,14 +395,7 @@ public class BigInteger extends Number implements Comparable
return MPN.cmp(x.words, y.words, x_len);
}
- // JDK1.2
- public int compareTo(Object obj)
- {
- if (obj instanceof BigInteger)
- return compareTo(this, (BigInteger) obj);
- throw new ClassCastException();
- }
-
+ /** @since 1.2 */
public int compareTo(BigInteger val)
{
return compareTo(this, val);
@@ -1589,24 +1600,31 @@ public class BigInteger extends Number implements Comparable
// but slightly more expensive, for little practical gain.
if (len <= 15 && radix <= 16)
return valueOf(Long.parseLong(s, radix));
-
+
+ int i, digit;
+ boolean negative;
+ byte[] bytes;
+ char ch = s.charAt(0);
+ if (ch == '-')
+ {
+ negative = true;
+ i = 1;
+ bytes = new byte[len - 1];
+ }
+ else
+ {
+ negative = false;
+ i = 0;
+ bytes = new byte[len];
+ }
int byte_len = 0;
- byte[] bytes = new byte[len];
- boolean negative = false;
- for (int i = 0; i < len; i++)
+ for ( ; i < len; i++)
{
- char ch = s.charAt(i);
- if (ch == '-')
- negative = true;
- else if (ch == '_' || (byte_len == 0 && (ch == ' ' || ch == '\t')))
- continue;
- else
- {
- int digit = Character.digit(ch, radix);
- if (digit < 0)
- break;
- bytes[byte_len++] = (byte) digit;
- }
+ ch = s.charAt(i);
+ digit = Character.digit(ch, radix);
+ if (digit < 0)
+ throw new NumberFormatException();
+ bytes[byte_len++] = (byte) digit;
}
return valueOf(bytes, byte_len, negative, radix);
}
diff --git a/libjava/classpath/java/math/MathContext.java b/libjava/classpath/java/math/MathContext.java
index 417d9c2e270..533ab13acf3 100644
--- a/libjava/classpath/java/math/MathContext.java
+++ b/libjava/classpath/java/math/MathContext.java
@@ -48,6 +48,30 @@ import java.io.Serializable;
*/
public final class MathContext implements Serializable
{
+ /** A MathContext for unlimited precision arithmetic * */
+ public static final MathContext UNLIMITED =
+ new MathContext(0, RoundingMode.HALF_UP);
+
+ /**
+ * A MathContext for the IEEE 754R Decimal32 format - 7 digit preicision and
+ * HALF_EVEN rounding.
+ */
+ public static final MathContext DECIMAL32 =
+ new MathContext(7, RoundingMode.HALF_EVEN);
+
+ /**
+ * A MathContext for the IEEE 754R Decimal64 format - 16 digit preicision and
+ * HALF_EVEN rounding.
+ */
+ public static final MathContext DECIMAL64 =
+ new MathContext(16, RoundingMode.HALF_EVEN);
+
+ /**
+ * A MathContext for the IEEE 754R Decimal128 format - 34 digit preicision and
+ * HALF_EVEN rounding.
+ */
+ public static final MathContext DECIMAL128 =
+ new MathContext(34, RoundingMode.HALF_EVEN);
/**
* This is the serialVersionUID reported here:
@@ -56,7 +80,9 @@ public final class MathContext implements Serializable
private static final long serialVersionUID = 5579720004786848255L;
private int precision;
-
+
+ private RoundingMode roundMode;
+
/**
* Constructs a new MathContext with the specified precision and with HALF_UP
* rounding.
@@ -66,11 +92,25 @@ public final class MathContext implements Serializable
*/
public MathContext(int setPrecision)
{
+ this(setPrecision, RoundingMode.HALF_UP);
+ }
+
+ /**
+ * Constructs a new MathContext with the specified precision and rounding
+ * mode.
+ * @param setPrecision the precision
+ * @param setRoundingMode the rounding mode
+ *
+ * @throws IllegalArgumentException if precision is < 0.
+ */
+ public MathContext(int setPrecision, RoundingMode setRoundingMode)
+ {
if (setPrecision < 0)
throw new IllegalArgumentException("Precision cannot be less than zero.");
precision = setPrecision;
+ roundMode = setRoundingMode;
}
-
+
/**
* Constructs a MathContext from a String that has the same form as one
* produced by the toString() method.
@@ -85,6 +125,7 @@ public final class MathContext implements Serializable
{
int roundingModeIndex = val.indexOf("roundingMode", 10);
precision = Integer.parseInt(val.substring(10, roundingModeIndex - 1));
+ roundMode = RoundingMode.valueOf(val.substring(roundingModeIndex + 13));
}
catch (NumberFormatException nfe)
{
@@ -109,7 +150,8 @@ public final class MathContext implements Serializable
if (!(x instanceof MathContext))
return false;
MathContext mc = (MathContext)x;
- return mc.precision == this.precision;
+ return mc.precision == this.precision
+ && mc.roundMode.equals(this.roundMode);
}
/**
@@ -122,6 +164,18 @@ public final class MathContext implements Serializable
}
/**
+ * Returns the rounding mode setting. This will be one of
+ * RoundingMode.CEILING, RoundingMode.DOWN, RoundingMode.FLOOR,
+ * RoundingMode.HALF_DOWN, RoundingMode.HALF_EVEN, RoundingMode.HALF_UP,
+ * RoundingMode.UNNECESSARY, or RoundingMode.UP.
+ * @return the rounding mode setting.
+ */
+ public RoundingMode getRoundingMode()
+ {
+ return roundMode;
+ }
+
+ /**
* Returns "precision=p roundingMode=MODE" where p is an int giving the
* precision and MODE is UP, DOWN, HALF_UP, HALF_DOWN, HALF_EVEN, CEILING,
* FLOOR, or UNNECESSARY corresponding to rounding modes.
@@ -130,7 +184,7 @@ public final class MathContext implements Serializable
*/
public String toString()
{
- return "precision="+precision;
+ return "precision="+precision+" roundingMode="+roundMode;
}
/**
@@ -139,6 +193,6 @@ public final class MathContext implements Serializable
*/
public int hashCode()
{
- return precision;
+ return precision ^ roundMode.hashCode();
}
}
diff --git a/libjava/classpath/java/math/RoundingMode.java b/libjava/classpath/java/math/RoundingMode.java
new file mode 100644
index 00000000000..c85bf4ff533
--- /dev/null
+++ b/libjava/classpath/java/math/RoundingMode.java
@@ -0,0 +1,89 @@
+/* RoundingMode.java -- An Enum to replace BigDecimal rounding constants.
+ Copyright (C) 1999, 2000, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.math;
+
+/**
+ * An enum to specify rounding behaviour for numerical operations that may
+ * discard precision.
+ * @author Anthony Balkissoon abalkiss at redhat dot com
+ *
+ */
+public enum RoundingMode
+{
+ UP, DOWN, CEILING, FLOOR, HALF_UP, HALF_DOWN, HALF_EVEN, UNNECESSARY;
+
+ /**
+ * For compatability with Sun's JDK
+ */
+ private static final long serialVersionUID = 432302042773881265L;
+
+ /**
+ * Returns the RoundingMode object corresponding to the legacy rounding modes
+ * in BigDecimal.
+ * @param rm the legacy rounding mode
+ * @return the corresponding RoundingMode
+ */
+ public static RoundingMode valueOf(int rm)
+ {
+ switch (rm)
+ {
+ case BigDecimal.ROUND_CEILING:
+ return CEILING;
+ case BigDecimal.ROUND_FLOOR:
+ return FLOOR;
+ case BigDecimal.ROUND_DOWN:
+ return DOWN;
+ case BigDecimal.ROUND_UP:
+ return UP;
+ case BigDecimal.ROUND_HALF_UP:
+ return HALF_UP;
+ case BigDecimal.ROUND_HALF_DOWN:
+ return HALF_DOWN;
+ case BigDecimal.ROUND_HALF_EVEN:
+ return HALF_EVEN;
+ case BigDecimal.ROUND_UNNECESSARY:
+ return UNNECESSARY;
+ default:
+ throw new
+ IllegalArgumentException("invalid argument: " + rm +
+ ". Argument should be one of the " +
+ "rounding modes defined in BigDecimal.");
+ }
+ }
+}
diff --git a/libjava/classpath/java/math/class-dependencies.conf b/libjava/classpath/java/math/class-dependencies.conf
new file mode 100644
index 00000000000..4fbf75eb1ce
--- /dev/null
+++ b/libjava/classpath/java/math/class-dependencies.conf
@@ -0,0 +1,58 @@
+# This property file contains dependencies of classes, methods, and
+# field on other methods or classes.
+#
+# Syntax:
+#
+# <used>: <needed 1> [... <needed N>]
+#
+# means that when <used> is included, <needed 1> (... <needed N>) must
+# be included as well.
+#
+# <needed X> and <used> are of the form
+#
+# <class.methodOrField(signature)>
+#
+# or just
+#
+# <class>
+#
+# Within dependencies, variables can be used. A variable is defined as
+# follows:
+#
+# {variable}: value1 value2 ... value<n>
+#
+# variables can be used on the right side of dependencies as follows:
+#
+# <used>: com.bla.blu.{variable}.Class.m()V
+#
+# The use of the variable will expand to <n> dependencies of the form
+#
+# <used>: com.bla.blu.value1.Class.m()V
+# <used>: com.bla.blu.value2.Class.m()V
+# ...
+# <used>: com.bla.blu.value<n>.Class.m()V
+#
+# Variables can be redefined when building a system to select the
+# required support for features like encodings, protocols, etc.
+#
+# Hints:
+#
+# - For methods and fields, the signature is mandatory. For
+# specification, please see the Java Virtual Machine Specification by
+# SUN. Unlike in the spec, field signatures (types) are in brackets.
+#
+# - Package names must be separated by '/' (and not '.'). E.g.,
+# java/lang/Class (this is necessary, because the '.' is used to
+# separate method or field names from classes)
+#
+# - In case <needed> refers to a class, only the class itself will be
+# included in the resulting binary, NOT necessarily all its methods
+# and fields. If you want to refer to all methods and fields, you can
+# write class.* as an abbreviation.
+#
+# - Abbreviations for packages are also possible: my/package/* means all
+# methods and fields of all classes in my/package.
+#
+# - A line with a trailing '\' continues in the next line.
+
+# end of file