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