重构这个检查 Double 有多少位小数的糟糕代码

Refactor this terrible code that checks how many decimals a Double has

我有一些代码可以检查我的号码有多少位小数。

Example:

1,10 correct conversion: String.format("%.1f", Double.parseDouble(md.get("amount"))

1,10 incorrect conversion: String.format("%.2f", Double.parseDouble(md.get("amount"))

I cannot have trailing 0's

1 correct conversion: String.format("%.0f", Double.parseDouble(md.get("amount"))

1 incorrect conversion: String.format("%.1f", Double.parseDouble(md.get("amount"))

I cannot have trailing 0's

For numbers larger than 1 000 000 Java converts my numbers to scientific notation, and the only way i know to convert them back without losing decimals is to use String.format.

我的错误代码:

md 是一个映射,键 "amount" 映射到一个应该是 Double

的字符串
if( Double.parseDouble(md.get("amount")) * 10 % 10 != 0) {
  System.out.println("0,1");
  md.put("amount", String.format("%.1f", Double.parseDouble(md.get("amount"))));
  if( Double.parseDouble(md.get("amount")) * 100 % 10 != 0) {
    System.out.println("0,11");
    md.put("amount", String.format("%.2f", Double.parseDouble(md.get("amount"))));
  }
}
else if(Double.parseDouble(md.get("amount")) * 10 % 10 == 0 && Double.parseDouble(md.get("amount")) * 100 % 10 == 0){
  System.out.println("0,0");
  md.put("amount", String.format("%.0f", Double.parseDouble(md.get("amount"))));
}
String s = md.get("amount").replaceFirst("(\.(\d*[1-9])?)0+$", "");

double 只是一个近似值,0.1 并不精确:0.09999987 或类似值。

人们通常会将 BigDecimal 与 toPlainString 一起用于非科学记数法。

要查找小数位数,可以使用 BigDecimal 的 scale()。因为你的数字是一个字符串,所以你必须转换成 BigDecimal。

Map<String, String> map = new HashMap<>();
map.put("amount", "1000000.23321312");

System.out.println(new BigDecimal(map.get("amount")).scale());

显示值为:8

你试过正则表达式了吗?

        double[] v = { 221, 22.1, 22.11 };
        Locale.setDefault(Locale.GERMANY);

        for (double val : v) {
            String str = String.format("%.2f", val);
            str = str.replaceAll("(.*?)0*$", "").replaceAll("(.*?)\,$", "");

            System.out.println(str);
        }

  1. 第一个 replaceAll 删除尾随的 0
  2. 第二个 replaceAll 删除尾随小数点。