2004-05-05 Guilhem Lavaux <guilhem@kaffe.org>

* java/text/DecimalFormat.java
	(MAXIMUM_INTEGER_DIGITS): New constant to keep the numeric value 309.
	(applyPatternWithSymbols): Use MAXIMUM_INTEGER_DIGITS.
	(parse): Fixed handling of exponentiation notation and grouping.

From-SVN: r81502
This commit is contained in:
Guilhem Lavaux 2004-05-05 06:02:37 +00:00 committed by Michael Koch
parent 07b232667e
commit b335a54914

View file

@ -330,7 +330,7 @@ public class DecimalFormat extends NumberFormat
useExponentialNotation = false; useExponentialNotation = false;
groupingUsed = false; groupingUsed = false;
maximumFractionDigits = 0; maximumFractionDigits = 0;
maximumIntegerDigits = 309; maximumIntegerDigits = MAXIMUM_INTEGER_DIGITS;
minimumFractionDigits = 0; minimumFractionDigits = 0;
minimumIntegerDigits = 1; minimumIntegerDigits = 1;
@ -562,7 +562,7 @@ public class DecimalFormat extends NumberFormat
dest.append (symbols.getDecimalSeparator(), NumberFormat.Field.DECIMAL_SEPARATOR); dest.append (symbols.getDecimalSeparator(), NumberFormat.Field.DECIMAL_SEPARATOR);
} }
int fraction_begin = dest.length();
dest.setDefaultAttribute(NumberFormat.Field.FRACTION); dest.setDefaultAttribute(NumberFormat.Field.FRACTION);
for (count = 0; for (count = 0;
count < localMaximumFractionDigits count < localMaximumFractionDigits
@ -594,6 +594,12 @@ public class DecimalFormat extends NumberFormat
dest.cutTail(1); dest.cutTail(1);
} }
if (fieldPos != null && fieldPos.getField() == FRACTION_FIELD)
{
fieldPos.setBeginIndex(fraction_begin);
fieldPos.setEndIndex(dest.length());
}
// Finally, print the exponent. // Finally, print the exponent.
if (useExponentialNotation) if (useExponentialNotation)
{ {
@ -793,13 +799,18 @@ public class DecimalFormat extends NumberFormat
public Number parse (String str, ParsePosition pos) public Number parse (String str, ParsePosition pos)
{ {
// Our strategy is simple: copy the text into a buffer, /*
// translating or omitting locale-specific information. Then * Our strategy is simple: copy the text into separate buffers: one for the int part,
// let Double or Long convert the number for us. * one for the fraction part and for the exponential part.
* We translate or omit locale-specific information.
* If exponential is sufficiently big we merge the fraction and int part and
* remove the '.' and then we use Long to convert the number. In the other
* case, we use Double to convert the full number.
*/
boolean is_neg = false; boolean is_neg = false;
int index = pos.getIndex(); int index = pos.getIndex();
StringBuffer buf = new StringBuffer (); StringBuffer int_buf = new StringBuffer ();
// We have to check both prefixes, because one might be empty. We // We have to check both prefixes, because one might be empty. We
// want to pick the longest prefix that matches. // want to pick the longest prefix that matches.
@ -840,11 +851,17 @@ public class DecimalFormat extends NumberFormat
// FIXME: do we have to respect minimum digits? // FIXME: do we have to respect minimum digits?
// What about leading zeros? What about multiplier? // What about leading zeros? What about multiplier?
StringBuffer buf = int_buf;
StringBuffer frac_buf = null;
StringBuffer exp_buf = null;
int start_index = index; int start_index = index;
int max = str.length(); int max = str.length();
int last = index + maximumIntegerDigits; int exp_index = -1;
int last = index + MAXIMUM_INTEGER_DIGITS;
if (last > 0 && max > last) if (last > 0 && max > last)
max = last; max = last;
char zero = symbols.getZeroDigit(); char zero = symbols.getZeroDigit();
int last_group = -1; int last_group = -1;
boolean int_part = true; boolean int_part = true;
@ -863,12 +880,11 @@ public class DecimalFormat extends NumberFormat
pos.setErrorIndex(index); pos.setErrorIndex(index);
return null; return null;
} }
last_group = index; last_group = index+1;
} }
else if (c >= zero && c <= zero + 9) else if (c >= zero && c <= zero + 9)
{ {
buf.append((char) (c - zero + '0')); buf.append((char) (c - zero + '0'));
exp_part = false;
} }
else if (parseIntegerOnly) else if (parseIntegerOnly)
break; break;
@ -881,14 +897,16 @@ public class DecimalFormat extends NumberFormat
pos.setErrorIndex(index); pos.setErrorIndex(index);
return null; return null;
} }
buf.append('.'); buf = frac_buf = new StringBuffer();
frac_buf.append('.');
int_part = false; int_part = false;
} }
else if (c == symbols.getExponential()) else if (c == symbols.getExponential())
{ {
buf.append('E'); buf = exp_buf = new StringBuffer();
int_part = false; int_part = false;
exp_part = true; exp_part = true;
exp_index = index+1;
} }
else if (exp_part else if (exp_part
&& (c == '+' || c == '-' || c == symbols.getMinusSign())) && (c == '+' || c == '-' || c == symbols.getMinusSign()))
@ -932,16 +950,111 @@ public class DecimalFormat extends NumberFormat
} }
String suffix = is_neg ? ns : positiveSuffix; String suffix = is_neg ? ns : positiveSuffix;
if (is_neg) long multiplier = 1;
buf.insert(0, '-'); boolean use_long;
String t = buf.toString(); if (is_neg)
Number result = null; int_buf.insert(0, '-');
try
// Now handle the exponential part if there is one.
if (exp_buf != null)
{ {
result = new Long (t); int exponent_value;
try
{
exponent_value = Integer.parseInt(exp_buf.toString());
}
catch (NumberFormatException x1)
{
pos.setErrorIndex(exp_index);
return null;
}
if (frac_buf == null)
{
// We only have to add some zeros to the int part.
// Build a multiplier.
for (int i = 0; i < exponent_value; i++)
int_buf.append('0');
use_long = true;
}
else
{
boolean long_sufficient;
if (exponent_value < frac_buf.length()-1)
{
int lastNonNull = -1;
/* We have to check the fraction buffer: it may only be full of '0'
* or be sufficiently filled with it to convert the number into Long.
*/
for (int i = 1; i < frac_buf.length(); i++)
if (frac_buf.charAt(i) != '0')
lastNonNull = i;
long_sufficient = (lastNonNull < 0 || lastNonNull <= exponent_value);
}
else
long_sufficient = true;
if (long_sufficient)
{
for (int i = 1; i < frac_buf.length() && i < exponent_value; i++)
int_buf.append(frac_buf.charAt(i));
for (int i = frac_buf.length()-1; i < exponent_value; i++)
int_buf.append('0');
use_long = true;
}
else
{
/*
* A long type is not sufficient, we build the full buffer to
* be parsed by Double.
*/
int_buf.append(frac_buf);
int_buf.append('E');
int_buf.append(exp_buf);
use_long = false;
}
}
} }
catch (NumberFormatException x1) else
{
if (frac_buf != null)
{
/* Check whether the fraction buffer contains only '0' */
int i;
for (i = 1; i < frac_buf.length(); i++)
if (frac_buf.charAt(i) != '0')
break;
if (i != frac_buf.length())
{
use_long = false;
int_buf.append(frac_buf);
}
else
use_long = true;
}
else
use_long = true;
}
String t = int_buf.toString();
Number result = null;
if (use_long)
{
try
{
result = new Long (t);
}
catch (NumberFormatException x1)
{
}
}
else
{ {
try try
{ {
@ -1110,6 +1223,8 @@ public class DecimalFormat extends NumberFormat
return computePattern (nonLocalizedSymbols); return computePattern (nonLocalizedSymbols);
} }
private static final int MAXIMUM_INTEGER_DIGITS = 309;
// These names are fixed by the serialization spec. // These names are fixed by the serialization spec.
private boolean decimalSeparatorAlwaysShown; private boolean decimalSeparatorAlwaysShown;
private byte groupingSize; private byte groupingSize;