【问题标题】:How to keep trailing 0s while converting a string to BigDecimal without exponent如何在没有指数的情况下将字符串转换为 BigDecimal 时保持尾随 0
【发布时间】:2019-09-19 06:59:28
【问题描述】:

我需要将这两个字符串 "0.0000000""0.0000008" 转换为 BigDecimal 而不会丢失尾随的 0。

我试过 String.format

String format = "%." + precision + "f";
BigDecimal divisor = new BigDecimal(Math.pow(10, precision));
formattedAmount = amountValue.divide(divisor).setScale(precision, BigDecimal.ROUND_DOWN);
String str= String.format(format, formattedAmount);
System.out.println(str);
BigDecimal strb = new BigDecimal(str);
System.out.println(strb);

我希望这两个字符串 "0.0000000""0.0000008" 以 BigDecimal 的形式返回,没有像 0.0000000 这样的指数0.0000008。但我得到 0E-78E-7我需要 0.0000000 和 0.0000008 作为 BigDecimal 而不是 String。

【问题讨论】:

  • “我期待这两个字符串”“as BigDecimal not as String” 是相反的陈述。你想要哪个?
  • BigDecimal.doubleValue() 呢?
  • @Phil :我可以使用 .plainString() 方法实现我想要的输出,但此方法将返回 String 而不是 BigDecimal。就像如果您将此字符串“1234.567890”转换为 BigDecimal,它将返回 1234.567890,但在“0.0000000”的情况下,它将返回 0E-7 而不是 0.0000000。我希望你明白我要说的话。谢谢。
  • 0.0000008 (BigDecimal, not String) 与 8E-7 (BigDecimal, not String) 完全相同 - 如果您 打印 或显示它(GUI、控制台),您将得到一个代表该值的 String,这是不同的
  • @AashuY 当您在System.out.println(...) 中打印 bigDeciamal 对象时,它也会返回一个字符串,因为.toString() 方法将被自动调用。这只是输出格式的问题。在任何情况下 bigDecimal 的值都是一样的,不管有没有指数

标签: java


【解决方案1】:

当您尝试在 System.out.println(strb) 中打印 BigDecimal 时,将调用 strb 对象上的 toString() 方法。所以控制台的输出也是string

查看更多The connection between 'System.out.println()' and 'toString()' in Java

所以告诉java不要在这里使用指数System.out.println(strb)的唯一方法是改变toString()方法。您不能直接更改它,但您可以创建自己的类来扩展 BigDecimal 并覆盖您需要的 toString() 方法。显然这没有意义..只需使用toPlainString() 方法。来自 java 文档:

返回此 {@code BigDecimal} 的字符串表示,不带指数字段。

【讨论】:

    【解决方案2】:

    首先,无论您如何输出BigDecimal 的值,它在它的实例中都保持不变(只要您不对其进行计算)。

    但是,输出可能会有很大差异。 以下是BigDecimal 提供的方法

    public static void main(String[] args) {
        String zero = "0.0000000";
        String zeroDotsEight = "0.0000008";
    
        BigDecimal z = new BigDecimal(zero);
        BigDecimal zE = new BigDecimal(zeroDotsEight);
    
        // play around with the precision and have a look at the output
        int precision = 7;
    
        System.out.println("String:\t\t\t\t\t" + zero);
        System.out.println("BigDecimal:\t\t\t\t" + z.setScale(precision, BigDecimal.ROUND_DOWN));
        System.out.println("BigDecimal.toString():\t\t\t"
                + z.setScale(precision, BigDecimal.ROUND_DOWN).toString());
        System.out.println("BigDecimal.toPlainString():\t\t"
                + z.setScale(precision, BigDecimal.ROUND_DOWN).toPlainString());
        System.out.println("BigDecimal.toEngineeringString():\t"
                + z.setScale(precision, BigDecimal.ROUND_DOWN).toEngineeringString());
        System.out.println("BigDecimal.doubleValue():\t\t"
                + z.setScale(precision, BigDecimal.ROUND_DOWN).doubleValue());
    
        System.out.println("————————————————————————————————————————————————————————————————");
    
        System.out.println("String:\t\t\t\t\t" + zeroDotsEight);
        System.out.println("BigDecimal:\t\t\t\t" + zE.setScale(precision, BigDecimal.ROUND_DOWN));
        System.out.println("BigDecimal.toString():\t\t\t"
                + zE.setScale(precision, BigDecimal.ROUND_DOWN).toString());
        System.out.println("BigDecimal.toPlainString():\t\t"
                + zE.setScale(precision, BigDecimal.ROUND_DOWN).toPlainString());
        System.out.println("BigDecimal.toEngineeringString():\t"
                + zE.setScale(precision, BigDecimal.ROUND_DOWN).toEngineeringString());
        System.out.println("BigDecimal.doubleValue():\t\t"
                + zE.setScale(precision, BigDecimal.ROUND_DOWN).doubleValue());
    }
    

    这是我系统上的输出

    String:                             0.0000000
    BigDecimal:                         0E-7
    BigDecimal.toString():              0E-7
    BigDecimal.toPlainString():         0.0000000
    BigDecimal.toEngineeringString():   0.0E-6
    BigDecimal.doubleValue():           0.0
    ————————————————————————————————————————————————————————————————
    String:                             0.0000008
    BigDecimal:                         8E-7
    BigDecimal.toString():              8E-7
    BigDecimal.toPlainString():         0.0000008
    BigDecimal.toEngineeringString():   800E-9
    BigDecimal.doubleValue():           8.0E-7
    

    如您所见,@Ruslan 是对的。您必须创建自己的类或使用 toPlainString() 以保持格式并且不会丢失任何尾随零(这应该只对人眼很重要,但我什至怀疑它们是否真的如此)。 此外,当您评论说doubleValue() 不是要走的路时,您也是对的。

    正如唯一的代码注释中所述,玩弄精度,也许在打印和/或将结果存储在变量中之前计算一些值。

    【讨论】:

      猜你喜欢
      • 2021-09-19
      • 1970-01-01
      • 1970-01-01
      • 2022-07-07
      • 2020-09-16
      • 1970-01-01
      • 2012-08-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多