在BigDecimal中去除超过两个尾随零

7

如何去除BigDecimal中超过两个尾随零的好方法?

因此,1.2200将会打印1.22,而1.0000将打印1.00。

编辑以及返回1.222200作为1.2222和1.220000001作为1.220000001等。因此,忽略前两个零,我想要修剪任何传入的0并不修剪非零值

一种方法是先乘以100,然后应用内置的修剪尾随零,然后再除以100。这可能存在问题,但我的问题中的值基于货币,并且永远不会超过Java设置的界限(否则意味着我的软件正在处理数十亿美元的投标)。

丑陋的解决方案如下

System.out.println(((new BigDecimal("1.230223000")
                                 .multiply(new BigDecimal("100.0"))
                                 .stripTrailingZeros()).divide(new BigDecimal("100.0"))));

请注意,您的新要求与原始要求相矛盾:如何将 1.230223000 转换为 1.230223,但 1.0000 应该打印为 1.00 - Joachim Sauer
不,他们不是Joachim。请再读一遍。我想要忽略小数点后的前两个零以进行修剪。而且输入始终至少为x.xx类型。 - geoaxis
是的,我在发表评论后意识到了这一点。我的(更新后的)回答有帮助吗? - Joachim Sauer
6个回答

14
更新: 拥有这些混合要求(即至少显示2位小数,但尽可能多)并不是一件容易实现的事情,但您可以接近实现:

结合 stripTrailingZeros()DecimalFormat 来获得所需的行为(或接近它):

DecimalFormat df = new DecimalFormat("0.00########")
String formatted = df.format(bigDecimal.stripTrailingZeros())

这将格式化任何BigDecimal值,小数点后至少有2位数字,并且如果它可以提高精度,小数点后最多有10位数字。
具有超过小数点后10位数字的BigDecimal值仍将被截断:
      输入         |  输出
-----------------+----------
 1.20000         | 1.20
 1.23000         | 1.23
 1.2301          | 1.2301
 1.230001000     | 1.230001
 1.2300000000001 | 1.23

如果你想要保留小数点后两位数字,并确定这样不会失去精度,那么你可以调用 setScale(2, RoundingMode.UNNECESSARY) 方法:
System.out.println(new BigDecimal("1.23000").setScale(2, RoundingMode.UNNECESSARY));

这段代码将会打印出 1.23。请注意,当需要四舍五入时(即小数点后第三位及以后不为零),会抛出ArithmeticException异常。

如果你的值可以有更高的精度并且想要进行一些四舍五入,只需将RoundingMode.UNNECESSARY替换为适当的值

System.out.println(new BigDecimal("1.2301").setScale(2, RoundingMode.CEILING));

这将打印出1.24
如果您不知道确切的数字位数,但希望尽可能少(即希望BigDecimalscale最小),那么调用stripTrailingZeros()将完全符合您的要求:
System.out.println(new BigDecimal("1.230001000").stripTrailingZeros();

这将打印1.230001


注意:我的回答假设您需要的是。如果您只想格式化值的显示方式,那么@Max的回答更合适。 - Joachim Sauer
我确实需要这个值,并且我也希望它适用于以下情况 BigDecimal 1.230002000000 返回 BigDecimal 1.230002。 - geoaxis
@geoaxis:我已经根据这些更改的要求更新了我的答案。 - Joachim Sauer

8

请检查以下内容:

import java.text.DecimalFormat;
import java.text.NumberFormat;

public class DecimalFormatExample
{
  public static void main(String args[])
  {
  double amount = 2192.015;
  NumberFormat formatter = new DecimalFormat("#0.00");
  System.out.println("The Decimal Value is:"+formatter.format(amount));
  }
}  

2
这将截断 new BigDecimal("1.234"),而根据新的要求,应该完整打印。 - Joachim Sauer

1

这种方法可以给您想要的结果(货币般的四舍五入):(因为BigDecimal更适用于String,请参阅文档)

public static float roundUp(String what, int howmuch) throws Exception{

    try {
        return (new BigDecimal(what).setScale(howmuch, BigDecimal.ROUND_UP)).floatValue();
    } catch (NumberFormatException nfe) {
        throw new Exception("BigDecimal cannot parse value : " + what, nfe);
    }
}

0
如果是用于显示目的,请使用以下代码:

BigDecimal d = new BigDecimal("1.2200");
NumberFormat n = NumberFormat.getCurrencyInstance(Locale.US);
String s = n.format(d.doubleValue());

0

如果要输出为 String,请使用 DecimalFormat

否则,请使用以下代码:

public static BigDecimal stripToMinimumScale(BigDecimal value, 
                                             final int minimumScale) {
  if (value.scale() == minimumScale) // Already correct scale
    return value;
  else {
    value = value.stripTrailingZeros();
    return (value.scale() < minimumScale) ?  
        value.setScale(minimumScale) : // Too few decimals, needs zero pad
        value; // Do not round any significant digits
  }
}

-1
BigDecimal d = new BigDecimal("59.0000");
String d1 = new DecimalFormat().format(d);
System.out.println("d1 is " + d1);

此答案已经发布过了,不属于“西部最快枪手”的范畴。 - Woot4Moo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接