java 在 BigDecimal 中修剪两个以上的尾随零

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6175993/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 14:41:47  来源:igfitidea点击:

Trim More than two trailing Zeros in BigDecimal

javabigdecimal

提问by geoaxis

What would be a good way to trim more than two trailing zeros for a BigDecimal

为 BigDecimal 修剪两个以上的尾随零的好方法是什么

So 1.2200 would print 1.22 and 1.0000 would print 1.00

所以 1.2200 会打印 1.22 而 1.0000 会打印 1.00

Edit As well as to return 1.222200 as 1.2222 and 1.220000001 as 1.220000001 etc. So disregarding first two zeros I want to trim any incoming 0s and not trim non-zero values

编辑以及将 1.222200 作为 1.2222 和 1.220000001 作为 1.220000001 等返回。所以忽略前两个零我想修剪任何传入的 0 而不是修剪非零值

One way could be to multiply, then apply the built in trim trailing zeros and then divide by 100. It could be problematic with corner cases but the values in my problem are currency based and would never exceed the bounds set by Java (or else it means my software is dealing with bids which are in gazzilions of dollars)

一种方法可能是相乘,然后应用内置的修剪尾随零,然后除以 100。它可能会在极端情况下出现问题,但我的问题中的值是基于货币的,永远不会超过 Java 设置的界限(否则意味着我的软件正在处理以美元计的投标)

The ugly solution is as folows

丑陋的解决方案如下

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

回答by Joachim Sauer

Update: Having those mixed requirements (i.e. at least 2 digits after the decimal point should be displayed, but as many as necessary) is not trivially implemented, but you can come close:

更新:具有这些混合要求(即应显示小数点后至少 2 位数字,但根据需要尽可能多)并不是很容易实现,但您可以接近:

Combine stripTrailingZeros()with DecimalFormatto get the desired behaviour (or close to it):

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

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

This will format any BigDecimalvalue with at least 2 digits after the decimal point and up to 10 digits after the decimal point, if it improves the precision.

BigDecimal如果可以提高精度,这将格式化小数点后至少 2 位和小数点后最多 10 位的任何值。

BigDecimalvalues with morethan 10 digits after the decimal point will still be cut off:

BigDecimal其值小数点后十位仍然会被剪除。

      input      |  output
-----------------+----------
 1.20000         | 1.20
 1.23000         | 1.23
 1.2301          | 1.2301
 1.230001000     | 1.230001
 1.2300000000001 | 1.23


Original answer:

原答案:

If you always want to have exactly 2 digits after the comma and know that you won't lose precision this way, then you can call setScale(2, RoundingMode.UNNECESSARY):

如果您总是希望在逗号后恰好有 2 位数字并且知道这样不会丢失精度,那么您可以调用setScale(2, RoundingMode.UNNECESSARY)

System.out.println(new BigDecimal("1.23000").setScale(2, RoundingMode.UNNECESSARY));

This code will print 1.23. Note that this will throw an ArithmeticExceptionwhen rounding would be necessary (i.e. anything after the first 2 digits is not zero).

此代码将打印1.23. 请注意,这将ArithmeticException在需要四舍五入时抛出一个(即前两位数字之后的任何内容都不是零)。

If your values can have a higher precision and you want to apply some rounding, simply replace RoundingMode.UNNECESSARYwith the appropriate value:

如果你的价值观可以有较高的精度,要应用某些圆整,只需更换RoundingMode.UNNECESSARY具有相应的值

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

This will print 1.24.

这将打印1.24.

If you don't know the exact number of digits but want as few as possible (i.e. you want the smallest possible scalefor your BigDecimal) then calling stripTrailingZeros()will do exactly what you want:

如果您不知道确切的数字位数但想要尽可能少的数字(即您想要尽可能小scaleBigDecimal),那么调用stripTrailingZeros()将完全按照您的要求进行:

System.out.println(new BigDecimal("1.230001000").stripTrailingZeros();

This will print 1.230001.

这将打印1.230001.

回答by Max

Check this,

检查这个,

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));
  }
}  

回答by Mattias Jiderhamn

For outputting as String, use DecimalFormat.

要输出为String,请使用DecimalFormat.

Otherwise, use this:

否则,使用这个:

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
  }
}

回答by EricParis16

This method will give you the result you want (monetary round): (what is String because it's better for BigDecimal see documentation)

这个方法会给你你想要的结果(货币回合):(什么是字符串,因为它更适合 BigDecimal 参见文档)

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);
    }
}

回答by Till

If it's for displaying purposes use:

如果用于显示目的,请使用:

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

回答by Reju Koshy

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