2016-12-12 1 views
-1

Dies ist der Code und das Ergebnis in den Kommentaren:Warum BigDecimal nicht wie erwartet funktioniert?

Ich dachte, die ZahlB2 sollte 16.7500, NumB3 = 16.7500, NumB4 = 16.7 und NumB5 = 16.75 sein. Aber sie sind nicht so, wie ich es erwartet hatte. Warum?

public void testBigDecimal() 
{ 
    float num = 16.7499924f; 

    int digitCount = 4; 
    MathContext mContext = new MathContext(digitCount, RoundingMode.UP); 
    BigDecimal numB = new BigDecimal(num, mContext); 
    System.out.println("16.7499924f with MathContext(precision) of 4 =" + numB.floatValue());// 16.75 
    numB.setScale(4, RoundingMode.UP); 
    System.out 
      .println("16.7499924f with MathContext(precision) of 4 and after setScale of 4 =" + numB.floatValue());// 16.75 

    BigDecimal numB2 = new BigDecimal(num); 
    System.out.println("16.7499924f without MathContext(precision =" + numB2.floatValue());// 16.749992 
    numB2.setScale(4, RoundingMode.UP); 
    System.out.println("16.7499924f without MathContext(precision) and after setScale of 4 =" + numB2.floatValue());// 16.749992 

    BigDecimal numB3 = new BigDecimal(num); 
    numB3.setScale(4, RoundingMode.UP); 
    System.out.println("16.7499924f without MathContext(precision) but with setScale of 4 =" + numB3.floatValue());// 16.749992 

    BigDecimal numB4 = new BigDecimal(num); 
    numB4.setScale(1, RoundingMode.UP); 
    System.out.println("16.7499924f without MathContext(precision) but with setScale of 1 =" + numB4.floatValue());// 16.749992 

    BigDecimal numB5 = new BigDecimal(num); 
    numB5.setScale(2, RoundingMode.UP); 
    System.out.println("16.7499924f without MathContext(precision) but with setScale of 2 =" + numB5.floatValue());// 16.749992 

} 
+2

Was bekommen Sie anstelle dessen, was Sie erwartet haben? – cHao

+0

BigDecimals sind unveränderlich. 'setScale' gibt ein neues BigDecimal mit dem angepassten Wert zurück; Das vorhandene Objekt kann und kann nicht geändert werden. – VGR

Antwort

5

Ein BigDecimal ist unveränderlich. Sie ignorieren das Ergebnis von setScale(). Also alles, was du da hast, sind im Grunde Noops.

Verwenden Sie auch eine Zeichenfolge, um Ihre BigDecimal zu erstellen. Und drucken Sie es nicht als Gleitkommawert. Sie verlieren Präzision, wenn dabei das, was der ganze Punkt ist BigDecimal in erster Linie der Verwendung:

String num = "16.7499924"; 

int digitCount = 4; 
MathContext mContext = new MathContext(digitCount, RoundingMode.UP); 
BigDecimal numB = new BigDecimal(num, mContext); 
System.out.println("16.7499924f with MathContext(precision) of 4 =" + numB.toPlainString()); 
numB = numB.setScale(4, RoundingMode.UP); 
System.out.println("16.7499924f with MathContext(precision) of 4 and after setScale of 4 =" + numB.toPlainString()); 
1

Als BigDecimal ist unveränderlich, setScale(4, RoundingMode.UP); gibt einen neuen BigDecimal mit der Skala Betrieb angewendet wird, ist es nicht beeinflussen die ursprüngliche Variable. Ersetzen Sie also die numB.setScale(4, RoundingMode.UP); Anrufe durch numB2 = numB2.setScale(4, RoundingMode.UP); und verzichten Sie auf BigDecimal numB2 = new BigDecimal(num);, da es nutzlos ist, da Sie es ohnehin im nächsten Schritt überschreiben.

Sie verwenden auch eine BigDecimal, aber Sie konvertieren es dann in float. Dies kann ungenau sein, da die Dokumentation wird für floatValue():

Beachten Sie, dass selbst dann, wenn der Rückgabewert endlich ist, diese Umwandlung Informationen über die Genauigkeit des BigDecimal Wert verlieren können.

Verwandte Themen