无法解释数字格式异常
Can't explain exception in number formatting
我有这个功能:
static private DecimalFormat df1 = new DecimalFormat("#0.###############",
new DecimalFormatSymbols(Locale.US));
static private DecimalFormat df2 = new DecimalFormat(
"0.0##############E000", new DecimalFormatSymbols(Locale.US));
public static String toChar(final double val) {
String cont = Double.toString(val);
final String f1 = df1.format(val);
final String f2 = df2.format(val);
try {
final double v1 = df1.parse(f1).doubleValue();
final double v2 = df2.parse(f2).doubleValue();
if (Math.abs(v1 - val) <= Math.abs(v2 - val) && f1.length() < 16) {
// 6.0 -> 6
cont = f1;
} else {
final int j = f2.indexOf('E');
if (f2.charAt(j + 1) == '-') {
cont = f2.substring(0, j - 1) + "e" + f2.substring(j + 1);
} else {
cont = f2.substring(0, j - 1) + "e+" + f2.substring(j + 1);
}
}
} catch (final ParseException e) {
throw new AssertionError(e);
}
return cont;
}
现在,奇怪的是我们的一位客户能够从这段代码中得到异常:
java.lang.StringIndexOutOfBoundsException: String index out of range: -2
Begin trace of call stack:
Level 0: String.substring(..) {java.lang.String.java, -1}
Level 1: Functions.toChar(..) {....runtime.Functions.java, 1579}
...
行号1579指的是第二个子串是代码片段。如果变量 f2
中没有 "E",我可以得到这个结果,但我无法提供任何可以这样做的输入。
你们有人看到我们在这里忽略的问题吗?
由于您没有提供实际导致此错误发生的双精度值,我们只能猜测:
f2
没有 'E'
,所以 indexOf
returns -1
,因此 j - 1 = -2
,这是 [= 的无效索引15=]。您应该检查 indexOf
的 return 值。
检查如果将 NaN(不是数字 - 如 1/0)放入方法中会发生什么。
在我的单元测试中它失败了
toChar(Double.NaN);
toChar(Double.POSITIVE_INFINITY);
toChar(Double.NEGATIVE_INFINITY);
这些的字符串表示是
NaN
Infinity
-Infinity
当您像这样通过 Double.NaN
时会发生这种情况:
toChar(Double.NaN);
(可能是产生相同值的其他值和范围),因此只需执行:
public static String toChar(final double val) {
if(Double.isNaN(val)) {
return "NaN";
}
...
我有这个功能:
static private DecimalFormat df1 = new DecimalFormat("#0.###############",
new DecimalFormatSymbols(Locale.US));
static private DecimalFormat df2 = new DecimalFormat(
"0.0##############E000", new DecimalFormatSymbols(Locale.US));
public static String toChar(final double val) {
String cont = Double.toString(val);
final String f1 = df1.format(val);
final String f2 = df2.format(val);
try {
final double v1 = df1.parse(f1).doubleValue();
final double v2 = df2.parse(f2).doubleValue();
if (Math.abs(v1 - val) <= Math.abs(v2 - val) && f1.length() < 16) {
// 6.0 -> 6
cont = f1;
} else {
final int j = f2.indexOf('E');
if (f2.charAt(j + 1) == '-') {
cont = f2.substring(0, j - 1) + "e" + f2.substring(j + 1);
} else {
cont = f2.substring(0, j - 1) + "e+" + f2.substring(j + 1);
}
}
} catch (final ParseException e) {
throw new AssertionError(e);
}
return cont;
}
现在,奇怪的是我们的一位客户能够从这段代码中得到异常:
java.lang.StringIndexOutOfBoundsException: String index out of range: -2
Begin trace of call stack:
Level 0: String.substring(..) {java.lang.String.java, -1}
Level 1: Functions.toChar(..) {....runtime.Functions.java, 1579}
...
行号1579指的是第二个子串是代码片段。如果变量 f2
中没有 "E",我可以得到这个结果,但我无法提供任何可以这样做的输入。
你们有人看到我们在这里忽略的问题吗?
由于您没有提供实际导致此错误发生的双精度值,我们只能猜测:
f2
没有 'E'
,所以 indexOf
returns -1
,因此 j - 1 = -2
,这是 [= 的无效索引15=]。您应该检查 indexOf
的 return 值。
检查如果将 NaN(不是数字 - 如 1/0)放入方法中会发生什么。
在我的单元测试中它失败了
toChar(Double.NaN);
toChar(Double.POSITIVE_INFINITY);
toChar(Double.NEGATIVE_INFINITY);
这些的字符串表示是
NaN
Infinity
-Infinity
当您像这样通过 Double.NaN
时会发生这种情况:
toChar(Double.NaN);
(可能是产生相同值的其他值和范围),因此只需执行:
public static String toChar(final double val) {
if(Double.isNaN(val)) {
return "NaN";
}
...