2017-10-09 6 views
1

Ich habe unter Stück Code und meine Präzision geht verloren beim Konvertieren BigDecimal zu String. Jede Hilfe wird sehr geschätzt.
Erwartetes Ergebnis: 95.10000000000000%
Tatsächliches Ergebnis: 95.09999999999999%Java BigDecimal zu String

public static String getAsString(Object value) 
{ 
    if (value == null) 
     return null; 

    if (value.toString().length() == 0) 
     return null; 

    BigDecimal inputVal = new BigDecimal(value.toString()); 

    if (inputVal == new BigDecimal(0)) 
     return ""; 

    NumberFormat numberFormat = NumberFormat.getPercentInstance(Locale.US); 
    numberFormat.setMinimumFractionDigits(14); 
    numberFormat.setMaximumFractionDigits(14); 
    if (numberFormat instanceof DecimalFormat) { 
     DecimalFormat df = (DecimalFormat) numberFormat; 
     df.setNegativePrefix("("); 
     df.setNegativeSuffix("%)"); 
    } 

    String num = null; 
    num = numberFormat.format(new BigDecimal(95.1).divide(new BigDecimal(100))); 

    return num; 
} 
+0

Welche Eingabe geben Sie es um das Problem zu reproduzieren? – marstran

+5

Außerdem wird 'inputVal == new BigDecimal (0)' immer fehlschlagen. Kein Objekt wird jemals das Gleiche sein wie ein neu erstelltes Objekt. Verwenden Sie stattdessen "equals". – marstran

+0

@marstran Während Sie mit dem falschen Referenzvergleich recht haben, ist 'equals' nicht das Richtige, da' equals' für 'BigDecimal.equals' die Skalierung berücksichtigt (sehen Sie sich die Dokumentation an). Sie sollten stattdessen 'BigDecimal.compareTo' verwenden. –

Antwort

0

Versuchen Sie, diese

BigDecimal inputVal = new BigDecimal(value.toString()).setScale(3, RoundingMode.HALF_UP); 
+0

Es gibt nicht das erwartete Ergebnis. Überprüfen Sie Ihre Antwort bitte. – imk

1

Sie setScale verwenden können und dann in einen String konvertieren.

Ich sehe Sie wollen 14 Ziffern drucken, so stellen Sie die Skala auf 14, und verwenden Sie aufrunden.

BigDecimal inputVal = new BigDecimal(95.10000000000000).setScale(14, RoundingMode.UP); 

Dann toString nennen und das% usw. hinzufügen

7

Mit diesem Beispiel Schaffung

new BigDecimal(95.1) 

Sie losing some precision sind. Was kann man eigentlich tun, ist das String-Konstruktor zu verwenden:

new BigDecimal("95.1") 

Eine weitere Möglichkeit, für Ihren Fall ist die Factory-Methoden zu verwenden:

BigDecimal.valueOf(95.1) 
BigDecimal.valueOf(100) 

Intern diese verwenden, um die String-Darstellung dieser Zahlen ein erstellen BigDecimal Objekt.

+0

Vielen Dank, es funktioniert jetzt –

1

In diesem Fall mit den new BigDecimal(double x) und double als Argument und es passiert, dass Doppel nicht x.xxxx genau darstellen kann. So wird x.xxxx in das nächstmögliche Double "transformiert", welches x.0000xxxxxxxxxxxzzzzzzzzzzyyyyy ist und das zeigt Ihr BigDecimal.

Also, hier könnte die Lösung Sie können String Konstruktor oder die valueOf() Methode verwenden, um die kanonische Darstellung Ihrer double d Wert zu erstellen.

Durch Ihre Linie zu ändern

num = numberFormat.format(new BigDecimal(95.1).divide(new BigDecimal(100))); 

zu

num = numberFormat.format(BigDecimal.valueOf(95.1).divide(BigDecimal.valueOf(100))); 

oder

num = numberFormat.format(new BigDecimal("95.1").divide(new BigDecimal("100"))); 

sollten Sie das richtige Ergebnis.

0

können Sie String-Wert verwenden

num = numberFormat.format(new BigDecimal("95.1").divide(new BigDecimal("100")));