在Java中从BigDecimal中删除尾随零

Tin*_*iny 52 java bigdecimal

我需要删除尾随零BigDecimal沿RoundingMode.HALF_UP.例如,

Value        Output

15.3456  <=> 15.35
15.999   <=> 16            //No trailing zeros.
15.99    <=> 15.99
15.0051  <=> 15.01
15.0001  <=> 15           //No trailing zeros.
15.000000<=> 15           //No trailing zeros.
15.00    <=> 15           //No trailing zeros.
Run Code Online (Sandbox Code Playgroud)

stripTrailingZeros() 有效,但它会在类似的情况下返回科学记数,

new BigDecimal("600.0").setScale(2, RoundingMode.HALF_UP).stripTrailingZeros();
Run Code Online (Sandbox Code Playgroud)

在这种情况下,它返回6E+2.我需要在JSF中的自定义转换器中使用它,这对最终用户来说可能很难看.那么,这样做的正确方法是什么?

Adr*_*zyk 65

使用 toPlainString()

BigDecimal d = new BigDecimal("600.0").setScale(2, RoundingMode.HALF_UP).stripTrailingZeros();
System.out.println(d.toPlainString()); // Printed 600 for me
Run Code Online (Sandbox Code Playgroud)

我还没有进入JSF,但是转换器可能看起来像这样:

@FacesConverter("bigDecimalPlainDisplay")
public class BigDecimalDisplayConverter implements Converter {
    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        throw new BigDecimal(value);
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        BigDecimal  bd = (BigDecimal)value;
        return bd.setScale(2, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在xhtml中:

<h:inputText id="bigDecimalView" value="#{bigDecimalObject}" 
    size="20" required="true" label="Value">
    <f:converter converterId="bigDecimalPlainDisplay" />
</h:inputText>
Run Code Online (Sandbox Code Playgroud)


小智 29

请注意,stripTrailingZeros()也不是很好.

在这:

val = new BigDecimal("0.0000").stripTrailingZeros();
System.out.println(val + ": plain=" + val.toPlainString());

val = new BigDecimal("40.0000").stripTrailingZeros();
System.out.println(val + ": plain=" + val.toPlainString());

val = new BigDecimal("40.50000").stripTrailingZeros();
System.out.println(val + ": plain=" + val.toPlainString());
Run Code Online (Sandbox Code Playgroud)

输出(Java 7):

0.0000: plain=0.0000
4E+1: plain=40
40.5: plain=40.5
Run Code Online (Sandbox Code Playgroud)

输出(Java 8):

0: plain=0
4E+1: plain=40
40.5: plain=40.5
Run Code Online (Sandbox Code Playgroud)

0.0000Java 7中的问题在Java 8中通过以下java修复得到修复.

  • Java 8修复了一个错误,因此第一个示例为"0"(Java 7行为为"0.0000"). (3认同)
  • 不是我发现的...关于从“0.0000”中去除零的第一个示例使用“toString()”和“toPlainString()”都会产生“0”。我们正在做一些不同的事情吗?http://ideone.com/fjS4qE (2认同)

小智 6

如果您想在 BigDecimal 对象上执行此操作,而不是使用格式化程序将其转换为字符串,则可以在 Java 8 上通过 2 个步骤执行此操作:

  1. stripTrailingZeros()
  2. 如果 scale < 0 setScale to 0 如果不喜欢 esponential/scientific notation

您可以尝试使用此代码段以更好地了解行为

BigDecimal bigDecimal = BigDecimal.valueOf(Double.parseDouble("50"));
bigDecimal = bigDecimal.setScale(2);
bigDecimal = bigDecimal.stripTrailingZeros();
if (bigDecimal.scale()<0)
    bigDecimal= bigDecimal.setScale(0);
System.out.println(bigDecimal);//50
bigDecimal = BigDecimal.valueOf(Double.parseDouble("50.20"));
bigDecimal = bigDecimal.setScale(2);
bigDecimal = bigDecimal.stripTrailingZeros();
if (bigDecimal.scale()<0)
    bigDecimal= bigDecimal.setScale(0);
System.out.println(bigDecimal);//50.2
bigDecimal = BigDecimal.valueOf(Double.parseDouble("50"));
bigDecimal = bigDecimal.setScale(2);
bigDecimal = bigDecimal.stripTrailingZeros();
System.out.println(bigDecimal);//5E+1
bigDecimal = BigDecimal.valueOf(Double.parseDouble("50.20"));
bigDecimal = bigDecimal.setScale(2);
bigDecimal = bigDecimal.stripTrailingZeros();
System.out.println(bigDecimal);//50.2
Run Code Online (Sandbox Code Playgroud)

  • 这对我来说很好。使用科学记数法时,BigDecimal 将比例设置为负值。 (2认同)

MrL*_*ore 5

您也可以使用来完成此操作String.format(),如下所示:

final BigDecimal b = new BigDecimal("600.0").setScale(2, RoundingMode.HALF_UP);
String f = String.format("%.0f", b);
System.out.println(f); //600
Run Code Online (Sandbox Code Playgroud)

  • 像“ 999.99”之类的数字会返回“ 1000”,但它会返回与.stripTrailingZeros()。toPlainString()相同的“ 999.99”。因此,它似乎并不像“ BigDecimal”那样准确。我想念什么吗? (3认同)