2013-07-21 32 views
36

Tôi cần xóa các số 0 theo sau từ BigDecimal cùng với RoundingMode.HALF_UP. Ví dụ,Xóa các số không theo sau từ BigDecimal trong Java

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. 

stripTrailingZeros() công trình nhưng nó sẽ trả về ký hiệu khoa học trong tình huống như thế,

new BigDecimal("600.0").setScale(2, RoundingMode.HALF_UP).stripTrailingZeros(); 

Trong trường hợp này, nó sẽ trả 6E+2. Tôi cần điều này trong một trình biến đổi tùy chỉnh trong JSF, nơi nó có thể là xấu cho người dùng cuối. Vì vậy, cách thích hợp để làm điều này là gì?

Trả lời

49

Sử dụng toPlainString()

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

Tôi không vào JSF (chưa), nhưng chuyển đổi có thể trông như thế này:

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

và sau đó trong xhtml:

<h:inputText id="bigDecimalView" value="#{bigDecimalObject}" 
    size="20" required="true" label="Value"> 
    <f:converter converterId="bigDecimalPlainDisplay" /> 
</h:inputText> 
4

Bạn cũng có thể thực hiện việc này với String.format(), như sau:

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

'String.format()' là giải pháp chung nhất. – gaborsch

+0

có, tôi cũng nên chọn phương pháp này. – KarelG

+2

Một số như '999,99' trả về' 1000' nhưng nó trả về cùng '999,99' với' .stripTrailingZeros(). ToPlainString() 'như nó phải làm. Vì vậy, nó không xuất hiện để được đại diện chính xác như 'BigDecimal'. Tui bỏ lỡ điều gì vậy? – Tiny

15

Lưu ý rằng stripTrailingZeros() cũng không hoạt động tốt.

On này:

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

Output (Java 7):

0.0000: plain=0.0000 
4E+1: plain=40 
40.5: plain=40.5 

Output (Java 8):

0: plain=0 
4E+1: plain=40 
40.5: plain=40.5 

Vấn đề 0.0000 trong Java 7 được cố định trong Java 8 theo sau java fix.

+0

Điều này làm việc cho tôi. Số tiền 0,000000 vẫn còn kỳ lạ, nhưng nó làm sạch phần còn lại của các giá trị có thể từ việc có giá trị ~ dp của 0 theo sau khi độ chính xác được yêu cầu ít hơn khả dụng. –

+1

Không phải những gì tôi tìm thấy ... Ví dụ đầu tiên của bạn về việc xóa số không từ "0,0000" sản lượng "0" cả với "toString()" và với "toPlainString()". Chúng ta có làm gì khác không? http://ideone.com/fjS4qE – Nateowami

+3

Java 8 sửa lỗi, vì vậy ví dụ đầu tiên là "0" (hành vi Java 7 là "0,0000"). – Rob

1

Bạn nên thực hiện một số phép tính trên BigDecimal và sau đó làm tròn một nửa lên, ví dụ:

BigDecimal toPay = new BigDecimal(1453.00005); 
    toPay = toPay.multiply(new BigDecimal(1)).setScale(2, RoundingMode.HALF_UP) 

Nó làm việc cho tôi.

0

Bạn có thể sử dụng DecimalFormat. Ví dụ:

BigDecimal value = new BigDecimal("15.3456").setScale(2, BigDecimal.ROUND_HALF_UP)); 
String valueString = new DecimalFormat("#.##").format(value); 
System.out.println(valueString); //15.35 

Hãy thử bản thân.

0

Nếu bạn muốn làm điều này ở đối tượng BigDecimal của bạn và không chuyển đổi nó thành một chuỗi với một định dạng bạn có thể làm điều đó trên Java 8 với 2 bước sau:

  1. stripTrailingZeros()
  2. nếu quy mô < 0 setScale là 0 nếu không thích esponential/ký hiệu khoa học

Bạn có thể thử đoạn này để hiểu rõ hơn về hành vi

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 
Các vấn đề liên quan