2017-10-19 1 views
-1

Ich gebe hier drei große Dezimalstellen, aber es sollte mir eine genaue Antwort geben. Ich habe hier zwei Strings und konvertiere dann in eine große Dezimalzahl. Bitte fragen Sie nicht, warum ich Strings benutze. Es gibt ein Geschäft, wo ich diese Werte als String bekommen werde, dann muss ich konvertieren. Sie finden den CodeBigdecimal Keine exakte Ausgabe in Java

BigDecimal a= new BigDecimal(100.05); --> This value I receive from web service. Its a decimal value from the service. 
    String b= "100.05"; 
    String c= "200.03"; 
    System.out.println(a.add(new BigDecimal(b).add(new BigDecimal(c)))); 

Ausgabe gibt es

400,1299999999999971578290569595992565155029296875

Wo, wie es 400,13

Antwort

7

Das Problem ist Ihre Verwendung von new BigDecimal(100.05). Der Wert von a ist dann 100,0499999999999971578290569595992565155029296875.

Wenn Sie diesen Wert als Zeichenfolge statt angegeben hatte, wäre alles gut:

BigDecimal a = new BigDecimal("100.05"); 
String b = "100.05"; 
String c = "200.03"; 
System.out.println(a.add(new BigDecimal(b).add(new BigDecimal(c)))); 
// Output: 400.13 

Wenn Sie nur haben den Eingang als double Sie BigDecimal.valueOf(double) statt den Aufruf der Konstruktor verwenden:

BigDecimal a = BigDecimal.valueOf(100.05); // a is now exactly 100.05 

Vergleichen Sie die BigDecimal(double) Dokumentation:

Übersetzt ein Double in ein BigDecimal, das die Dezimalzahl des binären Gleitkommawerts des Double darstellt. (...)

, die mit der BigDecimal.valueOf(Double):

Verschiebt ein Doppel in eine BigDecimal die Doppel kanonischen Stringdarstellung durch die Double.toString(double) Verfahren bereitgestellt werden.

Anmerkung: Dies ist im allgemeinen der bevorzugte Weg, um eine double (oder float) in eine BigDecimal, umzuwandeln, wie der zurückgegebene Wert gleich derjenigen ist, die sich von einem BigDecimal aus dem Ergebnis der Konstruktion des Verwendens Double.toString(double).

+1

Danke Jon. Ich habs. Einen kleinen Fehler gemacht – Yakhoob

5
new BigDecimal(100.05) 

100,0499999999999971578290569595992565155029296875 Dies gibt sein sollte, weil 100.05 kann nicht genau als double dargestellt werden.

Sie haben hier Zeichenfolge zu verwenden, wie gut:

new BigDecimal("100.05") 

Wie Sie diesen Wert von einem Web-Service zu bekommen, Sie wandeln es wahrscheinlich von einem String zu einem float/double. Wenn dies der Fall ist, überspringen Sie einfach diesen Konvertierungsschritt.

Wenn Ihr Web-Service Stub den Rückgabewert zuordnet float/double, können Sie es zu einer Abbildung betrachten String direkt und ihn dann zu BigDecimal Konstruktor wie folgt aus:

double v = 100.05; // Value from web service 
BigDecimal a= new BigDecimal(String.valueOf(v)); 
String b= "100.05"; 
String c= "200.03"; 
System.out.println(a.add(new BigDecimal(b).add(new BigDecimal(c)))); 

Live Example

Das funktioniert, weil der String nur so viele Ziffern enthält, wie benötigt werden, um den fast-100.05-Wert vom nächsten Wert auf jeder Seite zu unterscheiden, die dargestellt werden kann, und so erhalten wir die Zeichenfolge "100.05", die dann BigDecimal kann korrekt verarbeitet werden.

+0

@Roman, meinen Sie a oder b Wert – Yakhoob

+0

@TJCrowder Dank, habe ich die Antwort –

+0

fixiert Es sollte beachtet werden, dass die Dokumentation der BigDecimal Klasse erwähnt tatsächlich die Probleme des Konstrukteurs doppelten Wert mit: https://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html#BigDecimal(double) - vor allem: * Daher ist es in der Regel empfohlen, dass das String-Konstruktor in Vorzug diesen verwendet werden one. * –

0

Sie können die Antwort mit String.format auf Dezimalstellen formatieren und angeben, wie viele Ziffern.

System.out.println(String.format("%.2f", a.add(new BigDecimal(b).add(new BigDecimal(c)))));