summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuilhem Lavaux <guilhem@kaffe.org>2004-05-01 14:07:49 +0000
committerGuilhem Lavaux <guilhem@kaffe.org>2004-05-01 14:07:49 +0000
commitee94c11b2e2da7835b419c22b6dde02520c0c998 (patch)
tree74217bfbc3a9b73fcbff16e8895c459e1334a82c
parent7ea1a299df7453e4f5665104ce03226b372271b9 (diff)
downloadclasspath-ee94c11b2e2da7835b419c22b6dde02520c0c998.tar.gz
2004-05-01 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.
-rw-r--r--ChangeLog7
-rw-r--r--java/text/DecimalFormat.java149
2 files changed, 139 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index 038faa62b..390b8b522 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2004-05-01 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.
+
2004-05-01 Michael Koch <konqueror@gmx.de>
* native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.c,
diff --git a/java/text/DecimalFormat.java b/java/text/DecimalFormat.java
index d216be838..468d68df7 100644
--- a/java/text/DecimalFormat.java
+++ b/java/text/DecimalFormat.java
@@ -328,7 +328,7 @@ public class DecimalFormat extends NumberFormat
useExponentialNotation = false;
groupingUsed = false;
maximumFractionDigits = 0;
- maximumIntegerDigits = 309;
+ maximumIntegerDigits = MAXIMUM_INTEGER_DIGITS;
minimumFractionDigits = 0;
minimumIntegerDigits = 1;
@@ -560,7 +560,7 @@ public class DecimalFormat extends NumberFormat
dest.append (symbols.getDecimalSeparator(), NumberFormat.Field.DECIMAL_SEPARATOR);
}
-
+ int fraction_begin = dest.length();
dest.setDefaultAttribute(NumberFormat.Field.FRACTION);
for (count = 0;
count < localMaximumFractionDigits
@@ -592,6 +592,12 @@ public class DecimalFormat extends NumberFormat
dest.cutTail(1);
}
+ if (fieldPos != null && fieldPos.getField() == FRACTION_FIELD)
+ {
+ fieldPos.setBeginIndex(fraction_begin);
+ fieldPos.setEndIndex(dest.length());
+ }
+
// Finally, print the exponent.
if (useExponentialNotation)
{
@@ -791,14 +797,19 @@ public class DecimalFormat extends NumberFormat
public Number parse (String str, ParsePosition pos)
{
- // Our strategy is simple: copy the text into a buffer,
- // translating or omitting locale-specific information. Then
- // let Double or Long convert the number for us.
+ /*
+ * Our strategy is simple: copy the text into separate buffers: one for the int part,
+ * 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;
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
// want to pick the longest prefix that matches.
boolean got_pos = str.startsWith(positivePrefix, index);
@@ -838,11 +849,17 @@ public class DecimalFormat extends NumberFormat
// FIXME: do we have to respect minimum digits?
// What about leading zeros? What about multiplier?
+ StringBuffer buf = int_buf;
+ StringBuffer frac_buf = null;
+ StringBuffer exp_buf = null;
int start_index = index;
int max = str.length();
- int last = index + maximumIntegerDigits;
+ int exp_index = -1;
+ int last = index + MAXIMUM_INTEGER_DIGITS;
+
if (last > 0 && max > last)
max = last;
+
char zero = symbols.getZeroDigit();
int last_group = -1;
boolean int_part = true;
@@ -861,12 +878,11 @@ public class DecimalFormat extends NumberFormat
pos.setErrorIndex(index);
return null;
}
- last_group = index;
+ last_group = index+1;
}
else if (c >= zero && c <= zero + 9)
{
buf.append((char) (c - zero + '0'));
- exp_part = false;
}
else if (parseIntegerOnly)
break;
@@ -879,14 +895,16 @@ public class DecimalFormat extends NumberFormat
pos.setErrorIndex(index);
return null;
}
- buf.append('.');
+ buf = frac_buf = new StringBuffer();
+ frac_buf.append('.');
int_part = false;
}
else if (c == symbols.getExponential())
{
- buf.append('E');
+ buf = exp_buf = new StringBuffer();
int_part = false;
exp_part = true;
+ exp_index = index+1;
}
else if (exp_part
&& (c == '+' || c == '-' || c == symbols.getMinusSign()))
@@ -930,16 +948,111 @@ public class DecimalFormat extends NumberFormat
}
String suffix = is_neg ? ns : positiveSuffix;
+ long multiplier = 1;
+ boolean use_long;
+
if (is_neg)
- buf.insert(0, '-');
+ int_buf.insert(0, '-');
+
+ // Now handle the exponential part if there is one.
+ if (exp_buf != null)
+ {
+ 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;
+ }
+ }
+ }
+ 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 = buf.toString();
+ String t = int_buf.toString();
Number result = null;
- try
+ if (use_long)
{
- result = new Long (t);
+ try
+ {
+ result = new Long (t);
+ }
+ catch (NumberFormatException x1)
+ {
+ }
}
- catch (NumberFormatException x1)
+ else
{
try
{
@@ -1108,6 +1221,8 @@ public class DecimalFormat extends NumberFormat
return computePattern (nonLocalizedSymbols);
}
+ private static final int MAXIMUM_INTEGER_DIGITS = 309;
+
// These names are fixed by the serialization spec.
private boolean decimalSeparatorAlwaysShown;
private byte groupingSize;