Java 解析字符串以进行双重溢出检查
Java Parse String to Double Overflow Check
我正在编写一个计算器演示。计算器接受用户输入(字符串)并进行一些计算。第一步是将字符串解析为 double.
我正在使用 NumberUtils.isParsable()
和 Double.parseDouble()
。但是,我想限制用户输入,以免双数溢出。似乎 parseDouble()
只检查字符串是否为数字。我没有找到任何检查字符串值的方法。
我想知道最好的方法是什么。
我假设 "overflow" 谈论的是一个太大而无法表示的数字。
如果您在 "really large number" 上调用 Double.parseDouble()
,您实际上会得到一个 INF 值...不是异常1。所以对于数字溢出的简单解决方案2是使用Double.isInfinite(double)
来测试调用Double.parseDouble(String)
的结果。
进行转换和测试结果(尝试)在进行测试之前进行检查会更高效且代码更少。
1 - 我检查了 Java 11 源代码。查看 jdk.internal.math.FloatingDecimal
的代码。评论有点意思
2 - 如果您是 "exceptions are evil" 学派的毕业生,您可以在调用 parseDouble
之前使用正则表达式检查字符串的语法。我的意见是没有必要。只处理异常。
您可以使用 BigDecimal
class 对照 double
的最大值检查输入。
如果提供的 String
表示小于或等于 double
的最大值的数值,则此方法将 return true
并且return false
当输入大于一个 double
可以表示的最大值时。
public static boolean isValidDouble(String input){
final BigDecimal MAX_DOUBLE = new BigDecimal(Double.MAX_VALUE);
try{
BigDecimal bigInput = new BigDecimal(input);
return bigInput.compareTo(MAX_DOUBLE) < 1;
}catch(NumberFormatException e){
return false;
}
}
下面是一些测试上述方法的代码:
String[] inputs = {
"1E999999999999999999999999999999999999999999999999999999999999999999999999999999",
"1234",
"1.7976931348623157E308",
"1.79769313486231570E308",
"1.79769313486231571E308",
"1.79769313486231569E308",
"1E400"
};
for(String input: inputs){
System.out.println("input is: "+input);
System.out.println("is valid double? " + String.valueOf(isValidDouble(input)));
}
这是上述测试的结果输出:
input is: 1E999999999999999999999999999999999999999999999999999999999999999999999999999999
is valid double? false
input is: 1234
is valid double? true
input is: 1.7976931348623157E308
is valid double? true
input is: 1.79769313486231570E308
is valid double? true
input is: 1.79769313486231571E308
is valid double? false
input is: 1.79769313486231569E308
is valid double? true
input is: 1E400
is valid double? false
我正在编写一个计算器演示。计算器接受用户输入(字符串)并进行一些计算。第一步是将字符串解析为 double.
我正在使用 NumberUtils.isParsable()
和 Double.parseDouble()
。但是,我想限制用户输入,以免双数溢出。似乎 parseDouble()
只检查字符串是否为数字。我没有找到任何检查字符串值的方法。
我想知道最好的方法是什么。
我假设 "overflow" 谈论的是一个太大而无法表示的数字。
如果您在 "really large number" 上调用 Double.parseDouble()
,您实际上会得到一个 INF 值...不是异常1。所以对于数字溢出的简单解决方案2是使用Double.isInfinite(double)
来测试调用Double.parseDouble(String)
的结果。
进行转换和测试结果(尝试)在进行测试之前进行检查会更高效且代码更少。
1 - 我检查了 Java 11 源代码。查看 jdk.internal.math.FloatingDecimal
的代码。评论有点意思
2 - 如果您是 "exceptions are evil" 学派的毕业生,您可以在调用 parseDouble
之前使用正则表达式检查字符串的语法。我的意见是没有必要。只处理异常。
您可以使用 BigDecimal
class 对照 double
的最大值检查输入。
如果提供的 String
表示小于或等于 double
的最大值的数值,则此方法将 return true
并且return false
当输入大于一个 double
可以表示的最大值时。
public static boolean isValidDouble(String input){
final BigDecimal MAX_DOUBLE = new BigDecimal(Double.MAX_VALUE);
try{
BigDecimal bigInput = new BigDecimal(input);
return bigInput.compareTo(MAX_DOUBLE) < 1;
}catch(NumberFormatException e){
return false;
}
}
下面是一些测试上述方法的代码:
String[] inputs = {
"1E999999999999999999999999999999999999999999999999999999999999999999999999999999",
"1234",
"1.7976931348623157E308",
"1.79769313486231570E308",
"1.79769313486231571E308",
"1.79769313486231569E308",
"1E400"
};
for(String input: inputs){
System.out.println("input is: "+input);
System.out.println("is valid double? " + String.valueOf(isValidDouble(input)));
}
这是上述测试的结果输出:
input is: 1E999999999999999999999999999999999999999999999999999999999999999999999999999999
is valid double? false
input is: 1234
is valid double? true
input is: 1.7976931348623157E308
is valid double? true
input is: 1.79769313486231570E308
is valid double? true
input is: 1.79769313486231571E308
is valid double? false
input is: 1.79769313486231569E308
is valid double? true
input is: 1E400
is valid double? false