Ralf: Wie vermeide zu viele Nachkommastellen (1.9000000000000001)

Hi,

in einem java Programm berechne ich eine Variable vom Type double. Wenn ich dann z.B. auf einem Label ausgebe:

  
mylabel.setText(String.valueOf(myDouble));  

erhalte ich manchmal Ausgaben wie z.B.: 1.9000000000000001.
Ich vermute, das hängt im der internen Darstellung (dualsystem) der doubles zusammen.

auch folgendes funktioniert nicht:

  
double minRes = 0.001;  
myDouble = (Math.round(myDouble / minRes )) * minRes ;  
mylabel.setText(String.valueOf(myDouble));  

Wichtig ist, dass die Anzahl der gewünschten Nachkommstellen (minRes) variabel ist.

Wie könnte ich das Problem lösen?

MfG Ralf

  1. Hi!

    erhalte ich manchmal Ausgaben wie z.B.: 1.9000000000000001.
    Ich vermute, das hängt im der internen Darstellung (dualsystem) der doubles zusammen.

    Ja.

    auch folgendes funktioniert nicht:

    double minRes = 0.001;

    myDouble = (Math.round(myDouble / minRes )) * minRes ;
    mylabel.setText(String.valueOf(myDouble));

      
    "Funktioniert nicht" funktioniert nicht als Fehlerbeschreibung. Ich will und kann es jetzt nicht nachstellen. Also wenn es wichtig ist, beschreibe was passiert und was du gern hättest.  
      
    
    > Wichtig ist, dass die Anzahl der gewünschten Nachkommstellen (minRes) variabel ist.  
      
    Was bedeutet das "variabel" genau? Meinst du, dass du soviele Stellen kommen sollen, wie es sind und du keine Anzahl festlegen willst? Es gibt auch beim dezimalen Rechnen Ergebnisse, die unendlich lang werden können.  
      
    
    > Wie könnte ich das Problem lösen?  
      
    Runde mit einer festen (Maximal-)Stellenanzahl. Trimme gegebenenfalls rechts stehende Nullen weg.  
    Nimm einen Datentyp, der das Problem der binären Speicherung nicht hat. Bei Geldbeträgen beispielsweise ist es ungünstig, wenn sich solche "Rundungsfehler" ergeben. Suche, wie man mit Geldbeträgen sicher rechnet. Unter PHP gibt es Extensions, die dezimal rechnen (BC Math, GMP). Da gibt es garantiert auch was für Java.  
      
      
    Lo!
    
    1. Hi

      auch folgendes funktioniert nicht:

      double minRes = 0.001;

      myDouble = (Math.round(myDouble / minRes )) * minRes ;
      mylabel.setText(String.valueOf(myDouble));

      
      >   
      > "Funktioniert nicht" funktioniert nicht als Fehlerbeschreibung.  
        
      Es werden bei manchen Werten von myDouble immer noch zu viele Nachkommstellen ausgegeben.  
        
      
      > > Wichtig ist, dass die Anzahl der gewünschten Nachkommstellen (minRes) variabel ist.  
      >   
      > Was bedeutet das "variabel" genau?  
        
      Dass abhängig von anderen Variablen im Programm manchmal 0, 2, 3 oder 6 Nachkommstellen gewünscht sind. Ich könnte mit DecimalFormat alle (evtl.) vorkommenden Formate vordefinieren und dann jeweils mit case eines auswählen. Aber gibts da nicht eine "elegantere" Lösung?  
        
      MfG Ralf
      
      1. Hi!

        Was bedeutet das "variabel" genau?
        Dass abhängig von anderen Variablen im Programm manchmal 0, 2, 3 oder 6 Nachkommstellen gewünscht sind. Ich könnte mit DecimalFormat alle (evtl.) vorkommenden Formate vordefinieren und dann jeweils mit case eines auswählen. Aber gibts da nicht eine "elegantere" Lösung?

        Wenn es keine Methode gibt, der du die Anzahl der Nachkommastellen als Zahl übergeben kannst, wird sich sicherlich eine String-Wiederholungs-Funktion finden lassen, die anhand einer Zahl die gewünschte Anzahl Nullen für den Formatstring erzeugt.

        Lo!

        1. @@dedlfix:

          nuqneH

          […] wird sich sicherlich eine String-Wiederholungs-Funktion finden lassen, die anhand einer Zahl die gewünschte Anzahl Nullen

          oder Neunen

          für den Formatstring erzeugt.

          Qapla'

          --
          Gut sein ist edel. Andere lehren, gut zu sein, ist noch edler. Und einfacher.
          (Mark Twain)
  2. moin,
    java.text.DecimalFormat dürfte helfen.

    javadoc:
    http://download.oracle.com/javase/6/docs/api/java/text/DecimalFormat.html

    Bsp.

      
    DecimalFormat dezi =   new DecimalFormat("0.00");// gewünschtes format an nachkommastellen  
      
    String long = "1.00000000004";  
    Number N = dezi.parse(long);  
    long 	= dezi.format(N);           // 1.00
    
    1. Hi,

      Bsp.

      DecimalFormat dezi =   new DecimalFormat("0.00");// gewünschtes format an nachkommastellen

      String long = "1.00000000004";
      Number N = dezi.parse(long);
      long = dezi.format(N);           // 1.00

        
      Wie schon geschrieben ändern sich die Anzahl der Nachkommstellen zur Laufzeit.  
        
      Kann man die Anzahl der Nachkommstellen ändern z.B.: dezi.setNachkommstellen = 4 ?  
        
      Je ein DecimalFormat für alle denkbaren Fälle und dann eine Fallunterscheidung mit if oder case würde auch gehen, siht aber doch irgendwie "stümperhaft" aus, oder?  
        
      NfG Ralf
      
      1. Kann man die Anzahl der Nachkommstellen ändern z.B.: dezi.setNachkommstellen = 4 ?

        ja sicher. bei der Instanz gibt man sie an.
        bei 4 also
        new DecimalFormat("0.0000");

        Je ein DecimalFormat für alle denkbaren Fälle und dann eine Fallunterscheidung mit if oder case würde auch gehen, siht aber doch irgendwie "stümperhaft" aus, oder?

        ich weiss nicht genau was damit bezweckt werden soll, aber in dem Zusammenhang klingt das nicht elegant, ja :)

        1. Kann man die Anzahl der Nachkommstellen ändern z.B.: dezi.setNachkommstellen = 4 ?
          ja sicher. bei der Instanz gibt man sie an.
          bei 4 also
          new DecimalFormat("0.0000");

          Ich meine natürlich _nachdem_ das Object erzeugt wurde, so dass ich es zur Laufzeit an die gewünschte Stellenzahl anpassen kann.

          1. Hallo,

            Ich meine natürlich _nachdem_ das Object erzeugt wurde, so dass ich es zur Laufzeit an die gewünschte Stellenzahl anpassen kann.

            Warum schaust du nicht einfach in der Doku nach?

            Gruss,
            OhneName

          2. Kann man die Anzahl der Nachkommstellen ändern z.B.: dezi.setNachkommstellen = 4 ?
            ja sicher. bei der Instanz gibt man sie an.
            bei 4 also
            new DecimalFormat("0.0000");

            Ich meine natürlich _nachdem_ das Object erzeugt wurde, so dass ich es zur Laufzeit an die gewünschte Stellenzahl anpassen kann.

            ne. wenn du unterschiedliche Formate brauchst, erzeuge vorher eben soviele Instanzen wie du brauchst. jeweils mit der Anzahl Nachkommastellen

  3. Hi,

    Wichtig ist, dass die Anzahl der gewünschten Nachkommstellen (minRes) variabel ist.

    DecimalFormat und Konsorten. Oder String.format(...)

    cu,
    Andreas

    --
    Warum nennt sich Andreas hier MudGuard?
    O o ostern ...
    Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.