确定最适合字符串的数值变量类型

Determine the most fitting numeric variable type for a String

我正在尝试创建谓词来测试字符串并确定最合适的变量类型,这意味着我想获得解析后的字符串适合的“最小”数字变量类型。

例如,对于字符串“-1.2”,检测的类型应该是float,但是如果数字超出float范围,它应该检测double。如果数字更大,则BigDecimal。

对于非浮点数,我的测试似乎工作正常, 但是十进制数字让我更头疼了。

这是我的 isFloat 测试:

Predicate<String> isFloat =
    s -> {
      try {
        Double d = Double.parseDouble(s);
        return d >= -Float.MAX_VALUE && d <= Float.MAX_VALUE;
      } catch (Exception e) {
        return false;
      }
    };

String minOfFloat = String.valueOf(-Float.MAX_VALUE);
System.out.println(minOfFloat);
System.out.println(Double.parseDouble(minOfFloat));
System.out.println(isFloat.test(minOfFloat));

输出:

-3.4028235E38
-3.4028235E38
false //WHYYYYY

同样,我的下一个测试是检查数字是否符合双精度数,如果不符合,return "BigDecimal"。

正确的测试方法是什么?

编辑:我就是这样做的,接受的答案把我带到了那里:

public static final Predicate<String> isFloat =
  s -> {
    try {
      Double d = Double.parseDouble(s);
      
      return d.floatValue() >= -Float.MAX_VALUE
          && d.floatValue() <= Float.MAX_VALUE
          && !Float.isInfinite(d.floatValue())
          && !Float.isNaN(d.floatValue());
    } catch (Exception e) {
      return false;
    }
  };

更改谓词以与 d.floatValue() >= -Float.MAX_VALUE && d <= Float.MAX_VALUE;

进行比较

以防万一,如果你的 double 值超出浮点范围 d.floatValue() returns 无穷大,那么你应该适应变化

 Predicate<String> isFloat = s -> {
            try {
                Double d = Double.parseDouble(s);
                return d.floatValue() >= -Float.MAX_VALUE && d <= Float.MAX_VALUE;
            } catch (Exception e) {
                return false;
            }
        };
    String maxDouble = String.valueOf(Double.MAX_VALUE);
    System.out.println(maxDouble);
    System.out.println(isFloat.test(maxDouble));

在应用扩大基元转换时,建议使用 BigDecimal。我找不到合适的副本,但请参阅此帖子

comparing-float-and-double-primitives-in-java

了解为什么在比较两种不同类型时可能会得到错误的结果。所以我会做类似的事情:

Predicate<String> isFloat = 
   str -> new BigDecimal(str).compareTo(new BigDecimal(String.valueOf(Float.MAX_VALUE))) <= 0 &&
          new BigDecimal(str).compareTo(new BigDecimal(String.valueOf(-Float.MAX_VALUE))) >= 0;