Commit 200f4143 by Tom Tromey Committed by Tom Tromey

re PR libgcj/4583 (problems BigDecimal(double) ctor.)

	Fix for PR libgcj/4583:
	* java/math/BigDecimal.java (BigDecimal(double)): Rewrote.
	(BigDecimal(String)): Likewise.

From-SVN: r47329
parent a021c473
2001-11-25 Tom Tromey <tromey@redhat.com>
Fix for PR libgcj/4583:
* java/math/BigDecimal.java (BigDecimal(double)): Rewrote.
(BigDecimal(String)): Likewise.
2001-11-19 Tom Tromey <tromey@redhat.com> 2001-11-19 Tom Tromey <tromey@redhat.com>
* verify.cc (_Jv_BytecodeVerifier::branch_prepass) [op_iinc]: * verify.cc (_Jv_BytecodeVerifier::branch_prepass) [op_iinc]:
......
...@@ -28,7 +28,8 @@ package java.math; ...@@ -28,7 +28,8 @@ package java.math;
import java.math.BigInteger; import java.math.BigInteger;
public class BigDecimal extends Number implements Comparable { public class BigDecimal extends Number implements Comparable
{
private BigInteger intVal; private BigInteger intVal;
private int scale; private int scale;
private static final long serialVersionUID = 6108874887143696463L; private static final long serialVersionUID = 6108874887143696463L;
...@@ -63,16 +64,119 @@ public class BigDecimal extends Number implements Comparable { ...@@ -63,16 +64,119 @@ public class BigDecimal extends Number implements Comparable {
public BigDecimal (double num) throws NumberFormatException public BigDecimal (double num) throws NumberFormatException
{ {
this (Double.toString (num)); if (Double.isInfinite (num) || Double.isNaN (num))
throw new NumberFormatException ("invalid argument: " + num);
// Note we can't convert NUM to a String and then use the
// String-based constructor. The BigDecimal documentation makes
// it clear that the two constructors work differently.
final int mantissaBits = 52;
final int exponentBits = 11;
final long mantMask = (1L << mantissaBits) - 1;
final long expMask = (1L << exponentBits) - 1;
long bits = Double.doubleToLongBits (num);
long mantissa = bits & mantMask;
long exponent = (bits >>> mantissaBits) & expMask;
boolean denormal = exponent == 0;
// Correct the exponent for the bias.
exponent -= denormal ? 1022 : 1023;
// Now correct the exponent to account for the bits to the right
// of the decimal.
exponent -= mantissaBits;
// Ordinary numbers have an implied leading `1' bit.
if (! denormal)
mantissa |= (1L << mantissaBits);
// Shave off factors of 10.
while (exponent < 0 && (mantissa & 1) == 0)
{
++exponent;
mantissa >>= 1;
}
intVal = BigInteger.valueOf (bits < 0 ? - mantissa : mantissa);
if (exponent < 0)
{
// We have MANTISSA * 2 ^ (EXPONENT).
// Since (1/2)^N == 5^N * 10^-N we can easily convert this
// into a power of 10.
scale = (int) (- exponent);
BigInteger mult = BigInteger.valueOf (5).pow (scale);
intVal = intVal.multiply (mult);
}
else
{
intVal = intVal.shiftLeft ((int) exponent);
scale = 0;
}
} }
public BigDecimal (String num) throws NumberFormatException public BigDecimal (String num) throws NumberFormatException
{ {
int point = num.indexOf('.'); int len = num.length();
this.intVal = new BigInteger (point == -1 ? num : int start = 0, point = 0;
num.substring (0, point) + int dot = -1;
num.substring (point + 1)); boolean negative = false;
scale = num.length() - (point == -1 ? num.length () : point + 1); if (num.charAt(0) == '+')
{
++start;
++point;
}
else if (num.charAt(0) == '-')
{
++start;
++point;
negative = true;
}
while (point < len)
{
char c = num.charAt (point);
if (c == '.')
{
if (dot >= 0)
throw new NumberFormatException ("multiple `.'s in number");
dot = point;
}
else if (c == 'e' || c == 'E')
break;
else if (Character.digit (c, 10) < 0)
throw new NumberFormatException ("unrecognized character: " + c);
++point;
}
String val;
if (dot >= 0)
{
val = num.substring (start, dot) + num.substring (dot + 1, point);
scale = point - 1 - dot;
}
else
{
val = num.substring (start, point);
scale = 0;
}
if (val.length () == 0)
throw new NumberFormatException ("no digits seen");
if (negative)
val = "-" + val;
intVal = new BigInteger (val);
// Now parse exponent.
if (point < len)
{
int exp = Integer.parseInt (num.substring (point + 1));
exp -= scale;
if (exp > 0)
{
intVal = intVal.multiply (BigInteger.valueOf (10).pow (exp));
scale = 0;
}
else
scale = - exp;
}
} }
public static BigDecimal valueOf (long val) public static BigDecimal valueOf (long val)
...@@ -338,7 +442,6 @@ public class BigDecimal extends Number implements Comparable { ...@@ -338,7 +442,6 @@ public class BigDecimal extends Number implements Comparable {
intVal.divide (BigInteger.valueOf (10).pow (scale)); intVal.divide (BigInteger.valueOf (10).pow (scale));
} }
public int intValue () public int intValue ()
{ {
return toBigInteger ().intValue (); return toBigInteger ().intValue ();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment