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
This commit is contained in:
Tom Tromey 2001-11-25 19:32:28 +00:00 committed by Tom Tromey
parent a021c4736a
commit 200f4143a2
2 changed files with 117 additions and 8 deletions

View File

@ -1,3 +1,9 @@
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>
* verify.cc (_Jv_BytecodeVerifier::branch_prepass) [op_iinc]:

View File

@ -28,7 +28,8 @@ package java.math;
import java.math.BigInteger;
public class BigDecimal extends Number implements Comparable {
public class BigDecimal extends Number implements Comparable
{
private BigInteger intVal;
private int scale;
private static final long serialVersionUID = 6108874887143696463L;
@ -63,16 +64,119 @@ public class BigDecimal extends Number implements Comparable {
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
{
int point = num.indexOf('.');
this.intVal = new BigInteger (point == -1 ? num :
num.substring (0, point) +
num.substring (point + 1));
scale = num.length() - (point == -1 ? num.length () : point + 1);
int len = num.length();
int start = 0, point = 0;
int dot = -1;
boolean negative = false;
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)
@ -338,7 +442,6 @@ public class BigDecimal extends Number implements Comparable {
intVal.divide (BigInteger.valueOf (10).pow (scale));
}
public int intValue ()
{
return toBigInteger ().intValue ();