summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2011-01-26 14:36:51 -0800
committerElliott Hughes <enh@google.com>2011-01-26 15:21:11 -0800
commit8899157a607a6bfd4ca4f361c77db8726885e47b (patch)
treee7606a90d2a8e87a68f1630cacf9c016fa1910e5
parent30a7ff69872ad0b8de60550a740818b645ba0f29 (diff)
downloadlibcore-8899157a607a6bfd4ca4f361c77db8726885e47b.zip
libcore-8899157a607a6bfd4ca4f361c77db8726885e47b.tar.gz
libcore-8899157a607a6bfd4ca4f361c77db8726885e47b.tar.bz2
Minor float/double parsing improvements.
This removes some duplication and fixes an actual bug: we'd accept strings like ".NaN" or "Infinity." because the length check was done incorrectly. Also add explicit unit tests for some Double.toString duplicate bug reports, since that ought to be SOP. (I'm here to fix an unrelated bug, but want to keep this cleanup separate.) Change-Id: I197613afe52fae8da7a1598bb6b43514dcc03b98
-rw-r--r--luni/src/main/java/org/apache/harmony/luni/util/FloatingPointParser.java65
-rw-r--r--luni/src/test/java/libcore/java/lang/DoubleTest.java39
-rw-r--r--luni/src/test/java/libcore/java/lang/FloatTest.java31
3 files changed, 82 insertions, 53 deletions
diff --git a/luni/src/main/java/org/apache/harmony/luni/util/FloatingPointParser.java b/luni/src/main/java/org/apache/harmony/luni/util/FloatingPointParser.java
index f4774fd..038c1d3 100644
--- a/luni/src/main/java/org/apache/harmony/luni/util/FloatingPointParser.java
+++ b/luni/src/main/java/org/apache/harmony/luni/util/FloatingPointParser.java
@@ -196,66 +196,29 @@ public final class FloatingPointParser {
return new StringExponentPair(s, e, negative);
}
- /*
- * Assumes the string is trimmed.
- */
- private static double parseDblName(String namedDouble, int length) {
- // Valid strings are only +Nan, NaN, -Nan, +Infinity, Infinity,
- // -Infinity.
- if ((length != 3) && (length != 4) && (length != 8) && (length != 9)) {
- throw invalidReal(namedDouble, true);
- }
-
+ // Parses "+Nan", "NaN", "-Nan", "+Infinity", "Infinity", and "-Infinity", case-insensitively.
+ private static float parseName(String name, boolean isDouble) {
+ // Explicit sign?
boolean negative = false;
int i = 0;
- char firstChar = namedDouble.charAt(i);
- if (firstChar == '-') {
- negative = true;
- ++i;
- } else if (firstChar == '+') {
- ++i;
- }
-
- if (namedDouble.regionMatches(false, i, "Infinity", 0, 8)) {
- return negative ? Double.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY;
- }
-
- if (namedDouble.regionMatches(false, i, "NaN", 0, 3)) {
- return Double.NaN;
- }
-
- throw invalidReal(namedDouble, true);
- }
-
- /*
- * Assumes the string is trimmed.
- */
- private static float parseFltName(String namedFloat, int length) {
- // Valid strings are only +Nan, NaN, -Nan, +Infinity, Infinity,
- // -Infinity.
- if ((length != 3) && (length != 4) && (length != 8) && (length != 9)) {
- throw invalidReal(namedFloat, false);
- }
-
- boolean negative = false;
- int i = 0;
- char firstChar = namedFloat.charAt(i);
+ int length = name.length();
+ char firstChar = name.charAt(i);
if (firstChar == '-') {
negative = true;
++i;
+ --length;
} else if (firstChar == '+') {
++i;
+ --length;
}
- if (namedFloat.regionMatches(false, i, "Infinity", 0, 8)) {
+ if (length == 8 && name.regionMatches(false, i, "Infinity", 0, 8)) {
return negative ? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY;
}
-
- if (namedFloat.regionMatches(false, i, "NaN", 0, 3)) {
+ if (length == 3 && name.regionMatches(false, i, "NaN", 0, 3)) {
return Float.NaN;
}
-
- throw invalidReal(namedFloat, false);
+ throw invalidReal(name, isDouble);
}
/**
@@ -278,8 +241,8 @@ public final class FloatingPointParser {
// See if this could be a named double
char last = s.charAt(length - 1);
- if ((last == 'y') || (last == 'N')) {
- return parseDblName(s, length);
+ if (last == 'y' || last == 'N') {
+ return parseName(s, true);
}
// See if it could be a hexadecimal representation.
@@ -320,8 +283,8 @@ public final class FloatingPointParser {
// See if this could be a named float
char last = s.charAt(length - 1);
- if ((last == 'y') || (last == 'N')) {
- return parseFltName(s, length);
+ if (last == 'y' || last == 'N') {
+ return parseName(s, false);
}
// See if it could be a hexadecimal representation
diff --git a/luni/src/test/java/libcore/java/lang/DoubleTest.java b/luni/src/test/java/libcore/java/lang/DoubleTest.java
index f92ae33..988174b 100644
--- a/luni/src/test/java/libcore/java/lang/DoubleTest.java
+++ b/luni/src/test/java/libcore/java/lang/DoubleTest.java
@@ -19,9 +19,44 @@ package libcore.java.lang;
import junit.framework.TestCase;
public class DoubleTest extends TestCase {
- // http://b/3238333
- public void test3238333() throws Exception {
+ public void testDoubleToStringUnsignedDivide() throws Exception {
+ // http://b/3238333
assertEquals("0.008", Double.toString(0.008));
assertEquals("0.008366", Double.toString(0.008366));
+ // http://code.google.com/p/android/issues/detail?id=14033
+ assertEquals("0.009", Double.toString(0.009));
+ // http://code.google.com/p/android/issues/detail?id=14302
+ assertEquals("0.008567856012638986", Double.toString(0.008567856012638986));
+ assertEquals("0.010206713752229896", Double.toString(0.010206713752229896));
+ }
+
+ public void testNamedDoubles() throws Exception {
+ assertEquals(Double.NaN, Double.parseDouble("NaN"));
+ assertEquals(Double.NaN, Double.parseDouble("-NaN"));
+ assertEquals(Double.NaN, Double.parseDouble("+NaN"));
+ try {
+ Double.parseDouble("NNaN");
+ fail();
+ } catch (NumberFormatException expected) {
+ }
+ try {
+ Double.parseDouble("NaNN");
+ fail();
+ } catch (NumberFormatException expected) {
+ }
+
+ assertEquals(Double.POSITIVE_INFINITY, Double.parseDouble("+Infinity"));
+ assertEquals(Double.POSITIVE_INFINITY, Double.parseDouble("Infinity"));
+ assertEquals(Double.NEGATIVE_INFINITY, Double.parseDouble("-Infinity"));
+ try {
+ Double.parseDouble("IInfinity");
+ fail();
+ } catch (NumberFormatException expected) {
+ }
+ try {
+ Double.parseDouble("Infinityy");
+ fail();
+ } catch (NumberFormatException expected) {
+ }
}
}
diff --git a/luni/src/test/java/libcore/java/lang/FloatTest.java b/luni/src/test/java/libcore/java/lang/FloatTest.java
index 3708d87..de20ce7 100644
--- a/luni/src/test/java/libcore/java/lang/FloatTest.java
+++ b/luni/src/test/java/libcore/java/lang/FloatTest.java
@@ -22,9 +22,40 @@ public class FloatTest extends junit.framework.TestCase {
// http://code.google.com/p/android/issues/detail?id=4185
assertEquals(2358.166016f, Float.valueOf("2358.166016"));
}
+
public void test_valueOf_String2() throws Exception {
// This threw OutOfMemoryException.
// http://code.google.com/p/android/issues/detail?id=3156
assertEquals(-2.14748365E9f, Float.valueOf(String.valueOf(Integer.MIN_VALUE)));
}
+
+ public void testNamedFloats() throws Exception {
+ assertEquals(Float.NaN, Float.parseFloat("NaN"));
+ assertEquals(Float.NaN, Float.parseFloat("-NaN"));
+ assertEquals(Float.NaN, Float.parseFloat("+NaN"));
+ try {
+ Float.parseFloat("NNaN");
+ fail();
+ } catch (NumberFormatException expected) {
+ }
+ try {
+ Float.parseFloat("NaNN");
+ fail();
+ } catch (NumberFormatException expected) {
+ }
+
+ assertEquals(Float.POSITIVE_INFINITY, Float.parseFloat("+Infinity"));
+ assertEquals(Float.POSITIVE_INFINITY, Float.parseFloat("Infinity"));
+ assertEquals(Float.NEGATIVE_INFINITY, Float.parseFloat("-Infinity"));
+ try {
+ Float.parseFloat("IInfinity");
+ fail();
+ } catch (NumberFormatException expected) {
+ }
+ try {
+ Float.parseFloat("Infinityy");
+ fail();
+ } catch (NumberFormatException expected) {
+ }
+ }
}