2010-11-30 7 views
2

Die folgende unterschiedliche Ergebnisse in J2SE und Android für die de_DE gibt:String.format() Fehler?

Locale locale = new Locale("de","DE"); 
log(String.format(locale,"%.1f", 0.45)); 

In JRE 1.6.0_22, I "0,5" erhalten, wie erwartet. 2.2

Mit der Android-Plattform erhalte ich „0,4“

Danke, Roland

Antwort

3

Ich würde es nicht um einen Fehler nennen, wenn du mich nicht auf eine Spezifikation verweisen, der sagt, das den Modus Rundung String.format Methode sollte verwendet werden. Es scheint, dass die 1.6 JRE UP oder HALF_UP als RoundingMode verwendet. In Android wird jedoch der HALF_EVEN-Modus verwendet, der auch als Standardmodus für DecimalFormat erscheint. Dies ist der Code, den ich mit JRE verwendet habe, die oben zu testen:

import java.util.Locale; 
import java.text.DecimalFormat; 
import java.math.RoundingMode; 

public class Test { 

    public static void main(String [] args) { 
     Locale locale = new Locale("de","DE"); 
     String str = String.format(locale,"%.1f", 0.45); 
     System.out.println(str); 
     System.out.println(String.format("%.1f", 0.45)); 

     DecimalFormat df = new DecimalFormat("#.#"); 
     System.out.println(df.format(0.45)); 
     System.out.println(df.getRoundingMode()); 
     df.setRoundingMode(RoundingMode.HALF_UP); 
     System.out.println(df.format(0.45)); 
    } 
} 

Es scheint, dass das Gebietsschema nichts mit dem Rundungsmodus zu tun hat. Leider scheint DecimalFormat in Android keine Rundungsmodi zu unterstützen, so dass Sie nicht den gleichen Code ausführen können wie er ist.

Ich wäre auch daran interessiert, den gleichen Code in JRE 1.5 (die Einstellung des Rundenmodus nicht unterstützt) zu laufen, aber ich habe keine geeignete Umgebung in meinem Rechner.

0

die Lösung für Android gefunden:

// format 
DecimalFormat df = new DecimalFormat("0.0"); 
BigDecimal valDec = new BigDecimal(String.valueOf(val)); 
BigDecimal roundedDec = valDec.setScale(1,BigDecimal.ROUND_HALF_UP); 
return df.format(roundedDec.doubleValue()); 

Es scheint, ist zu wichtig zu sein, die BigDecimal mit der String-Darstellung des Doppel zu instanziiert, denn wenn Sie nicht tun, werden Sie ein paar lustige Werte erhalten. Hier ist ein Beispiel:

BigDecimal test = new BigDecimal(0.85); 
Log.v(TAG,"BigDecimal: "+test.toPlainString()); 

-----> BigDecimal: 0,84999999999999997779553950749686919152736663818359375

Wenn Sie nun den angezeigten Code verwenden, können Sie natürlich 0.8 bekommen und nicht 0,9, was man erwarten würde.

Danke, Roland