Seite 1 von 2 12 Letzte »
Ergebnis 1 bis 20 von 31

[Java] - Double immer mit 2 Nachkommastellen ausgeben

  1. #1 Zitieren
    #11 Avatar von Alpha
    Registriert seit
    Oct 2008
    Beiträge
    23.117
    Servus Jungs

    Ich fange seit neustem wieder an, Java zu lernen, haben wir aktuell in unserem Kurs, von daher schadets nicht, wenn man zuhause bisschen übt
    So, ich verzweifle grad daran, wie ich bitte eine double dazu zwinge, sie immer mit zwei nachkommastellen auszugeben.

    Ich hab da ein kleines Programm geschrieben als Übung: Man gibt das Startkapital ein, dann den Zinssatz und schließlich die Laufzeit in jahren, berechnet und so wird das alles wunderbar und wird in der Konsole auch angezeigt. Runden tut es aber nicht so, wie ich will, wenn eine Zahl zum Beispiel 4,503 lautet, rundet es auf 4,5. Gleiches bei 4,03, da wird auf 4,0 gerundet. Ich will aber dass auf 4,50 gerundet wird bzw auf 4,00. Dies ist aber leider nicht so! Hat da jemand ne Idee wie man das macht.

    Hier mal der Code:
    Code:
    import java.io.*;
    
    public class Zinsrechnungen {
    	
    	public static double runden (double d1)
            {
              double ergebnis = Math.round(d1*Math.pow(10d,2))/Math.pow(10d,2);
      		
              return ergebnis;
            }
    	
    	public static void main ( String[] args ) throws IOException
           {
    		
    
    		BufferedReader in = new BufferedReader(new InputStreamReader(System.in) );
    		
    	//------Variablen-----------
    		double Startkapital;
    		double Zinssatz; //ohne Prozentzeichen
    		int Laufzeit;
    		double S2;
    		int aktuelleLaufzeit = 1;
    		double Einnahmen;
    		double Guthabenlastyear;
    
    		//--------------------------
    		//------Funktion für die Tastaureingabe---------------
    		System.out.println("Geben Sie ihr Startkapital ein (in €): "); 
    		Startkapital = Double.parseDouble(in.readLine());
    		System.out.println("Geben Sie ihr Zinssatz ein (ohne %): ");
    		Zinssatz = Double.parseDouble(in.readLine());
    		System.out.println("Geben Sie ihre Laufzeit ein (in Jahre): ");
    		Laufzeit = Integer.parseInt(in.readLine());
    		//------------------------------------------------------
    
    	
    		S2 = runden(Startkapital);
    		double aktuellesGuthaben = S2;
    		System.out.println("---------------------------------------");
    		System.out.println("Startkapital: \t" + S2 + "€");
    		System.out.println("Zinssatz: \t" + Zinssatz + "%");
    		System.out.println("Laufzeit: \t" + Laufzeit + " Jahre");
    		System.out.println("---------------------------------------");
    		System.out.println("Guthaben am Anfang: \t \t" + Startkapital + "€");
    			for (aktuelleLaufzeit = 1; aktuelleLaufzeit <= Laufzeit; aktuelleLaufzeit = aktuelleLaufzeit + 1)
    			{
    				Guthabenlastyear = aktuellesGuthaben;
    				aktuellesGuthaben=aktuellesGuthaben + aktuellesGuthaben*(Zinssatz/100);
    				aktuellesGuthaben=runden(aktuellesGuthaben);
    				Einnahmen = aktuellesGuthaben - Guthabenlastyear;
    				Einnahmen = runden(Einnahmen);
    				System.out.println ("Guthaben nach dem " + aktuelleLaufzeit + ". Jahr: \t" + aktuellesGuthaben + " € \t (+ " + Einnahmen + "€)");
    			}
    	
    	}
    }
    Und hier der Text der in der Konsole dabei ausgegeben wird:
    Code:
    Geben Sie ihr Startkapital ein (in €): 
    2000000
    Geben Sie ihr Zinssatz ein (ohne %): 
    2.5
    Geben Sie ihre Laufzeit ein (in Jahre): 
    20
    ---------------------------------------
    Startkapital: 	2000000.0€
    Zinssatz: 	2.5%
    Laufzeit: 	20 Jahre
    ---------------------------------------
    Guthaben am Anfang: 	 	2000000.0€
    Guthaben nach dem 1. Jahr: 	2050000.0 € 	 (+ 50000.0€)
    Guthaben nach dem 2. Jahr: 	2101250.0 € 	 (+ 51250.0€)
    Guthaben nach dem 3. Jahr: 	2153781.25 € 	 (+ 52531.25€)
    Guthaben nach dem 4. Jahr: 	2207625.78 € 	 (+ 53844.53€)
    Guthaben nach dem 5. Jahr: 	2262816.42 € 	 (+ 55190.64€)
    Guthaben nach dem 6. Jahr: 	2319386.83 € 	 (+ 56570.41€)
    Guthaben nach dem 7. Jahr: 	2377371.5 € 	 (+ 57984.67€)
    Guthaben nach dem 8. Jahr: 	2436805.79 € 	 (+ 59434.29€)
    Guthaben nach dem 9. Jahr: 	2497725.93 € 	 (+ 60920.14€)
    Guthaben nach dem 10. Jahr: 	2560169.08 € 	 (+ 62443.15€)
    Guthaben nach dem 11. Jahr: 	2624173.31 € 	 (+ 64004.23€)
    Guthaben nach dem 12. Jahr: 	2689777.64 € 	 (+ 65604.33€)
    Guthaben nach dem 13. Jahr: 	2757022.08 € 	 (+ 67244.44€)
    Guthaben nach dem 14. Jahr: 	2825947.63 € 	 (+ 68925.55€)
    Guthaben nach dem 15. Jahr: 	2896596.32 € 	 (+ 70648.69€)
    Guthaben nach dem 16. Jahr: 	2969011.23 € 	 (+ 72414.91€)
    Guthaben nach dem 17. Jahr: 	3043236.51 € 	 (+ 74225.28€)
    Guthaben nach dem 18. Jahr: 	3119317.42 € 	 (+ 76080.91€)
    Guthaben nach dem 19. Jahr: 	3197300.36 € 	 (+ 77982.94€)
    Guthaben nach dem 20. Jahr: 	3277232.87 € 	 (+ 79932.51€)
    Alpha ist offline

  2. #2 Zitieren
    Daepilin ist offline

  3. #3 Zitieren
    #11 Avatar von Alpha
    Registriert seit
    Oct 2008
    Beiträge
    23.117
    Klappt nicht wirklich.

    Code:
    System.out.println ("Guthaben nach dem " + aktuelleLaufzeit + ". Jahr: \t" + d.format(aktuellesGuthaben) + " € \t (+ " + d.format(Einnahmen) + "€)");
    Kommt jetzt halt statt . ein ,
    aber sonst das gleiche Problem.
    Auch wenn ich math.round bzw runden () entferne aus meinem Script, tut sich da nichts.
    Problem ist halt, ich will das alles in einer Zeile haben, da gehts nicht einfach mit System.out.println(f.format(d));
    Alpha ist offline

  4. #4 Zitieren
    Held Avatar von Lolomoloko
    Registriert seit
    Aug 2006
    Ort
    ~/
    Beiträge
    5.700
    wie sieht dein format string aus?
    Lolomoloko ist offline

  5. #5 Zitieren
    #11 Avatar von Alpha
    Registriert seit
    Oct 2008
    Beiträge
    23.117
    Zitat Zitat von Lolomoloko Beitrag anzeigen
    wie sieht dein format string aus?
    meinst du das?
    DecimalFormat d = new DecimalFormat("#.##");
    Alpha ist offline

  6. #6 Zitieren
    Held Avatar von Lolomoloko
    Registriert seit
    Aug 2006
    Ort
    ~/
    Beiträge
    5.700
    Zitat Zitat von Alpha Beitrag anzeigen
    meinst du das?
    DecimalFormat d = new DecimalFormat("#.##");
    das ist aber nicht das was du wolltest, das schneidet die stellen ab wenn sie unnötig sind.

    also 2.00 → 2 usw.


    zumindest machts das bei mir.
    schau dir mal die anderen beispiele dort an.
    Lolomoloko ist offline

  7. #7 Zitieren
    Pretty Pink Pony Princess  Avatar von Multithread
    Registriert seit
    Jun 2010
    Ort
    Crystal Empire
    Beiträge
    11.310
    Das schöne am prgorammieren ist das man es sich eine funktion die man vermisst auch schnell selber schreiben kann:
    string str=double;
    return str.substring(0,str.indexof(',')+2);


    Mal so ganz primitiv, ohne irgendwelche Fehler abzufangen und in pseudocode(wird so nicht gleich laufen)
    [Bild: AMD_Threadripper.png] Bei Hardware gibt es keine eigene Meinung, bei Hardware zählen nur die Fakten.


    Probleme mit der Haarpracht? Starres Haar ohne Glanz? TressFX schafft Abhilfe. Ja, TressFX verhilft auch Ihnen zu schönem und Geschmeidigen Haar.
    [Bild: i6tfHoa3ooSEraFH63.png]
    Multithread ist offline

  8. #8 Zitieren
    Held Avatar von Satans Krümelmonster
    Registriert seit
    Aug 2007
    Beiträge
    5.797
    @Chrysalis: was macht dein code, wenn die zahl nur zwei nachkommastellen hat?
    2,5 soll beispielsweise als 2,50 ausgegeben werden. das macht deine funktion nicht.
    Satans Krümelmonster ist offline

  9. #9 Zitieren
    Held Avatar von Lolomoloko
    Registriert seit
    Aug 2006
    Ort
    ~/
    Beiträge
    5.700
    Zitat Zitat von Satans Krümelmonster Beitrag anzeigen
    @Chrysalis: was macht dein code, wenn die zahl nur zwei nachkommastellen hat?
    2,5 soll beispielsweise als 2,50 ausgegeben werden. das macht deine funktion nicht.
    zudem ist das ein übler hack
    Lolomoloko ist offline

  10. #10 Zitieren
    Knight Commander Avatar von Kellendil
    Registriert seit
    Jul 2009
    Beiträge
    2.112
    So, habs mal schnell ausprobiert:
    Das folgende geht 100%ig : ]
    Code:
    public static String format(double i)
    {
    	DecimalFormat f = new DecimalFormat("#0.00");
    	double toFormat = ((double)Math.round(i*100))/100;
    	return f.format(toFormat);
    }
    Edit: Zahl die du runden willst/mitgeben eingeben, bekommst nen string mit der formatierten Zahl zurück.
    Kannste dann so verwenden

    Code:
    double a = xyz;
    System.out.println(format(a));
    Kellendil ist offline

  11. #11 Zitieren
    #11 Avatar von Alpha
    Registriert seit
    Oct 2008
    Beiträge
    23.117
    Danke, hat geklappt
    Alpha ist offline

  12. #12 Zitieren
    General Avatar von dc2
    Registriert seit
    Jan 2006
    Ort
    Hannover
    Beiträge
    3.967
    Oder man nutzt das gute alte printf (Für die reine 2-Nachkommastellen-Geschichte, Runden muss man natürlich trotzdem falls gewünscht):

    Code:
    System.out.printf("%.2f", 3.14159);
    Ist deutlich kürzer und meiner Meinung nach auch übersichtlicher als alles sonst so vorgeschlagene.
    dc2 ist offline

  13. #13 Zitieren
    Knight Commander Avatar von Kellendil
    Registriert seit
    Jul 2009
    Beiträge
    2.112
    Kann man mit printf auch Strings aus ner Funktion formatiert zurückgeben? Ich kenn mich mit System.xxx.bla nicht so wirklich aus.
    Aber dann wäre es natürlich deutlich einfacher.

    Das Hauptproblem ist aber immer noch das Runden, das ist bei mir auch sehr unelegant. Und was besonders komisch ist:
    format() rundet Zahlen eigentlich selber schon automatisch auf die hinterste Stelle. mit einer Ausnahme:

    Code:
    DecimalFormat f = new DecimalFormat("0.00");
    f.format(0.0017) //=> Ausgabe = 0.00
    f.format(0.0082) //=> Ausgabe = 0.01
    f.format(0.0057) //=> Ausgabe = 0.01
    f.format(0.0050001) //=> Ausgabe = 0.01
    
    //ABER:
    f.format(0.005) //=> Ausgabe = 0.00 
    //WTF? wird 0.005 nicht eigentlich aufgerundet? Oder bin ich völlig bescheuert?
    Kellendil ist offline

  14. #14 Zitieren
    General Avatar von dc2
    Registriert seit
    Jan 2006
    Ort
    Hannover
    Beiträge
    3.967
    System.out ist in Java ein PrintStream, der mit der Standard-Ausgabe verknüpft ist. Theoretisch kann man auch eigene PrintStream-Objekte nutzen, allerdings ist das wieder deutlich umständlicher. String.format müsste eigentlich dieselbe Funktionalität mit deutlich schlankerer Syntax bieten, falls man das Resultat als String weiterverarbeiten will.

    Das Runden auf ½-Stellen lässt sich eigentlich recht einfach durch folgende Formel erreichen: round(input*2) / 2.0 - das Resultat kann man dann wieder mit printf oder String.format passend ausgeben.
    dc2 ist offline

  15. #15 Zitieren
    Knight Commander Avatar von Kellendil
    Registriert seit
    Jul 2009
    Beiträge
    2.112
    Wieso auf halbe Stellen Runden? Ich meinte ganz normales auf ganze Stellen Runden, was mit DecimalFormat.format(input) funktionieren sollte, aber was beim Runden auf die 2. Nachkommastelle eben NUR exakt bei 0.005 nicht funktioniert, da dieses auf 0.00 ab statt auf 0.01 aufgerundet wird. Bei 0.005001 wird hingegen korrekt auf 0.01 aufgerundet.
    Kellendil ist offline

  16. #16 Zitieren

    Batmanistrator
    Avatar von Thoronador
    Registriert seit
    Jul 2005
    Ort
    Morrowind, Vvardenfell-Distrikt
    Beiträge
    20.799
    Zitat Zitat von Kellendil Beitrag anzeigen
    Code:
    //ABER:
    f.format(0.005) //=> Ausgabe = 0.00 
    //WTF? wird 0.005 nicht eigentlich aufgerundet? Oder bin ich völlig bescheuert?
    Entweder nutzt die format()-Funktion das sogenannte "Banker's Rounding" oder "Round To Even", wo bei einer 5 gefolgt von Nullen nicht stur aufgerundet sondern auf die nächste gerade Ziffer gerundet wird - das wäre hier also 0.00 statt 0.01, weil letzere ungerade ist. Oder aber, und das erscheint mir in dem Falle auch wahrscheinlich, dir spielt hier die Genauigkeit von einfachen Fließkommazahlen einen Streich. Der Wert 0,005 lässt sich mit 32-Bit-Fließkommazahlen nach dem Standard IEEE 754 nicht exakt darstellen, weshalb die interne Repräsentation einen leicht davon abweichenden Wert hat, z.B. 0,00499999988824 oder sowas in der Art. Da diese interne Darstellung noch unter 0,005 liegt, wird dabei auch folgerichtig auf 0,00 abgerundet.

    0.005001 hat eine interne Darstellung, welche leicht über 0,005 liegt, daher erscheint dort beim Runden auch der erwartete Wert.
    Thoronador ist offline

  17. #17 Zitieren
    Knight Commander Avatar von Kellendil
    Registriert seit
    Jul 2009
    Beiträge
    2.112
    Achja, Fließkommazahlen Dezimal-Binär spielen einem immer wieder ganz schöne Streiche. Ein Hoch auf Ints/Longs : D
    Das mit dem Rundungsfehler leuchtet ein. Danke : ]

    Wir sollten schleunigst mal ein paar neue Zeichen erfinden und unser Standard-Zahlensystem auf Hexadezimal umstelln. Dann gäbs endlich Ruhe mit einigen solchen Problemen : ]
    Kellendil ist offline

  18. #18 Zitieren
    Held Avatar von Lolomoloko
    Registriert seit
    Aug 2006
    Ort
    ~/
    Beiträge
    5.700
    Zitat Zitat von Kellendil Beitrag anzeigen
    Wir sollten schleunigst mal ein paar neue Zeichen erfinden und unser Standard-Zahlensystem auf Hexadezimal umstelln. Dann gäbs endlich Ruhe mit einigen solchen Problemen : ]
    warum?
    die begründung interessiert mich jetzt wirklich.
    Lolomoloko ist offline

  19. #19 Zitieren
    Provinzheld Avatar von Cheesecake
    Registriert seit
    Feb 2012
    Beiträge
    270
    Zitat Zitat von Thoronador Beitrag anzeigen
    Oder aber, und das erscheint mir in dem Falle auch wahrscheinlich, dir spielt hier die Genauigkeit von einfachen Fließkommazahlen einen Streich. Der Wert 0,005 lässt sich mit 32-Bit-Fließkommazahlen nach dem Standard IEEE 754 nicht exakt darstellen, weshalb die interne Repräsentation einen leicht davon abweichenden Wert hat, z.B. 0,00499999988824 oder sowas in der Art. Da diese interne Darstellung noch unter 0,005 liegt, wird dabei auch folgerichtig auf 0,00 abgerundet.
    Da es hier ursprünglich um Geld ging, sollte man das noch einmal besonders hervorheben. Bei normalen Rechnungen sind Fließkommazahlen trotz dieser Probleme in Ordnung, aber damit Geldbeträge zu speichern, ist meistens alles andere als sinnvoll. Dafür sollte man lieber die kleinste Geldeinheit nehmen und die Beträge als Ganzzahl (am besten verpackt in einer eigenen, netten Klasse) speichern.
    Cheesecake ist offline

  20. #20 Zitieren
    Knight Commander Avatar von Kellendil
    Registriert seit
    Jul 2009
    Beiträge
    2.112
    Zitat Zitat von Lolomoloko Beitrag anzeigen
    warum?
    die begründung interessiert mich jetzt wirklich.
    Weil man hexadezimale Zahlen problemlos in binäre umrechnen kann und andersrum, ohne irgendwelche Perioden ect. in den Nachkommateil zu bekommen, wodurch man mit Fließkommazahlen dezimal nie genau rechnen kann. Immer 4 binäre Stellen entsprechen einer Hexadezimalen Stelle. Ein weiterer Vorteil wäre, dass Zahlen ein wenig kürzer wären als im Dezimalsystem.
    Kellendil ist offline

Seite 1 von 2 12 Letzte »

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •