double_Problem im ZinsesZins Rechner

javastudent25

Bekanntes Mitglied
Hallo zusammen und ein gutes neues Jahr wünsche ich allen 😉

Ich habe da ein kleines Problem das ich zuerst behandeln möchte.
Und zwar habe ich eine Klasse Zinseszins und eine Testklasse
Ich komme leider nicht dazu die Klasse vollständig zu testen, da ich bei er Eingabe von 0.05, sprich eines double Wertes scheitere, egal ob ich ein . (Punkt) oder , (Komma) eingebe auf meiner Tastatur...

Kann mir jemand helfen und sagen, was das Problem ist?

Java:
public class Zinseszins {

    double betrag;
    double prozent;
    int laufzeit;

    public Zinseszins(double betrag, double prozent, int laufzeit) {

        this.betrag = betrag;
        this.prozent = prozent;
        this.laufzeit = laufzeit;

    }

    public double ergebnisBerechnen() {
        betrag = betrag *(1+prozent);
        return betrag;
    }
 

}

Java:
import java.util.Scanner;
import javax.swing.JOptionPane;

public class Test {
 
    static double number;
 
    public static double einlesen() {
        try {
            Scanner sc = new Scanner(System.in);
            number = Integer.parseInt(sc.nextLine());
            System.out.println("Du hast " + number + "eingegeben.");
         
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, "Sie müssen dafür eine Zahl eingegeben");
            System.exit(1);
        }
        return number;
    }


    public static void main(String[] args) {
     
        System.out.println("Geben Sie einen Betrag ein: ");
        einlesen();
        double betrag = number;
        System.out.println("Geben Sie für Prozent eine Zahl in Prozent ein (zB 0.05 für 5%): ");
        einlesen();
        double prozent = number;
        System.out.println("Geben Sie eine Laufzeit in Jahren ein (Ganzzahl): ");
        einlesen();
        int laufzeit = (int) number;
             
        Zinseszins zinsesZins = new Zinseszins(betrag, prozent, laufzeit);
   
        for(int i=0; i <= laufzeit; i++){
         
            System.out.println("Das Kapital am Ende des " + i + ". Jahres betraegt " + zinsesZins.ergebnisBerechnen());
        }

    }
 
}
 
Zuletzt bearbeitet:
Das Problem ist eigentlich recht einfach:

Java:
Integer.parseInt(   )
ist für ganzzahlige Integer-Zahlen vorgesehen.
Um eine Dezimalzahl umzuwandeln gibt es:
Java:
Double.parseDouble(   )

Außerdem ist einlesen eine Funktion, d.h. der Rückgabewert muss irgendwo abgespeichert werden. Beispiel:
Java:
double zahl = einlesen();
 
Hi,
schau mal was du machst:
Java:
number = Integer.parseInt(sc.nextLine());
dann
Java:
 double betrag = number;
ein int ist IMMER eine Ganzzahl.
Vieleicht hilft dir soetwas:
Java:
number = Dobule.parseDouble(sc.nextLine());
...ups war ein wenig zu spät...
 
Auhh ich Depp!!
Ok, dann folgt die nächste Frage:


und was hat die Zahl in der Klammer von System.exit(1); auf sich?
warum muss da eine Zahl stehen?

Im Beitrag von Flown, da sagte er mir, dass der Scanner die bessere Anwendung als BufferedReader wäre und mir der Scanner die Funktionalität bietet, die ich benötige.

Dann schrieb er unter:
http://www.java-forum.org/thema/programmfehler-mit-array.171124/page-2

Also generell würde ich die Konvertierung in eine Methode auslagern. Statt den BufferedInputStream würde ich auch einen Scanner verwenden.
Java:
import java.util.Scanner;

public class Test {

   public static void main(String... args) {
     final Scanner sc = new Scanner(System.in);
     System.out.print("Number to convert: ");
     int n = sc.nextInt();
     System.out.print("Base: ");
     int base = sc.nextInt();
     System.out.println("The number " + n + " to base " + base + ": " + decimalToBase(n, base));
   }

}

Warum muss ich nun parsen und weshalb übergibt er sc.nextInt() direkt n??


Java:
import java.util.Scanner;
import javax.swing.JOptionPane;

public class Test {

    static double number;

    public static double einlesen() {
        try {
            Scanner sc = new Scanner(System.in);
            number = Double.parseDouble(sc.nextLine());
            System.out.println("Du hast " + number + "eingegeben.");
    
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, "Sie müssen dafür eine Zahl eingegeben");
            System.exit(1);
    
        }
        return number;
    }


    public static void main(String[] args) {

        System.out.println("Geben Sie einen Betrag ein: ");
        double betrag = einlesen();
        System.out.println("Geben Sie für Prozent eine Zahl in Prozent ein (zB 0.05 für 5%): ");
        double prozent = einlesen();
        System.out.println("Geben Sie eine Laufzeit in Jahren ein (Ganzzahl): ");
        int laufzeit = (int) einlesen();;
        
        Zinseszins zinsesZins = new Zinseszins(betrag, prozent, laufzeit);

        for(int i=1; i <= laufzeit; i++){
    
            System.out.println("Das Kapital am Ende des " + i + ". Jahres betraegt " + zinsesZins.ergebnisBerechnen());
        }

    }

}

Java:
public class Zinseszins {

    double betrag;
    double prozent;
    int laufzeit;

    public Zinseszins(double betrag, double prozent, int laufzeit) {

        this.betrag = betrag;
        this.prozent = prozent;
        this.laufzeit = laufzeit;

    }

    public double ergebnisBerechnen() {
        betrag = betrag *(1+prozent);
        return betrag;
    }


}
 
Zuletzt bearbeitet:
🙂🙂 Führst du Selbstgespräche
Nein richtiger Programmierer bin ich noch nicht 😛

Ja diese Frage ist noch offen:

Warum muss ich nun trotzdem parsen und weshalb kann Flown sc.nextInt() direkt n übergeben?? Das funktioniert bei mir nämlich nicht so wie er es hat.

und was hat die Zahl in der Klammer von System.exit(1); auf sich?
warum muss da eine Zahl stehen?

Auhh ich Depp!!
Ok, dann folgt die nächste Frage:


und was hat die Zahl in der Klammer von System.exit(1); auf sich?
warum muss da eine Zahl stehen?

Im Beitrag von Flown, da sagte er mir, dass der Scanner die bessere Anwendung als BufferedReader wäre und mir der Scanner die Funktionalität bietet, die ich benötige.

Dann schrieb er unter:
http://www.java-forum.org/thema/programmfehler-mit-array.171124/page-2



Warum muss ich nun parsen und weshalb übergibt er sc.nextInt() direkt n??


Java:
import java.util.Scanner;
import javax.swing.JOptionPane;

public class Test {

    static double number;

    public static double einlesen() {
        try {
            Scanner sc = new Scanner(System.in);
            number = Double.parseDouble(sc.nextLine());
            System.out.println("Du hast " + number + "eingegeben.");

        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, "Sie müssen dafür eine Zahl eingegeben");
            System.exit(1);

        }
        return number;
    }


    public static void main(String[] args) {

        System.out.println("Geben Sie einen Betrag ein: ");
        double betrag = einlesen();
        System.out.println("Geben Sie für Prozent eine Zahl in Prozent ein (zB 0.05 für 5%): ");
        double prozent = einlesen();
        System.out.println("Geben Sie eine Laufzeit in Jahren ein (Ganzzahl): ");
        int laufzeit = (int) einlesen();;
    
        Zinseszins zinsesZins = new Zinseszins(betrag, prozent, laufzeit);

        for(int i=1; i <= laufzeit; i++){

            System.out.println("Das Kapital am Ende des " + i + ". Jahres betraegt " + zinsesZins.ergebnisBerechnen());
        }

    }

}

Java:
public class Zinseszins {

    double betrag;
    double prozent;
    int laufzeit;

    public Zinseszins(double betrag, double prozent, int laufzeit) {

        this.betrag = betrag;
        this.prozent = prozent;
        this.laufzeit = laufzeit;

    }

    public double ergebnisBerechnen() {
        betrag = betrag *(1+prozent);
        return betrag;
    }


}
 
Du beziehst dich sicher auf folgendes:
public static void main(String... args) {
final Scanner sc = new Scanner(System.in);
System.out.print("Number to convert: ");
int n = sc.nextInt();
System.out.print("Base: ");
int base = sc.nextInt();
System.out.println("The number " + n + " to base " + base + ": " + decimalToBase(n, base));
}

Du liest halt in deinem Code oben via scanner eine neue Zeile als String ein und suchst dir dann daraus die double-Zahl (parsen). Es gäbe auch analog zu dem was Flown dir beschrieben hat ein nextDouble();

Und exit(0); ist das normale Ende eines Programmes, exit(1) ist ein Beenden auf Grund von Fehlern.
Du könntest in einer aufrufenden Shell oder einer Batch-Datei o.ä. den exit-Code auswerten
 
Es funktioniert 🙂
Na dann vielen Dank


Java:
import java.util.Scanner;
import javax.swing.JOptionPane;

public class Test {
  
    static double number;
  
    public static double einlesen() {
        try {
            Scanner sc = new Scanner(System.in);
            //number = Double.parseDouble(sc.nextLine());
            //oder
            number = sc.nextDouble();
            System.out.println("Du hast " + number + " eingegeben.");
          
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, "Sie müssen dafür eine Zahl eingeben");
            System.exit(1);
          
        }
        return number;
    }


    public static void main(String[] args) {
      
        System.out.println("Geben Sie einen Betrag ein: ");
        double betrag = einlesen();
        System.out.println("Geben Sie für Prozent eine Zahl in Prozent ein (zB 0.05 für 5%): ");
        double prozent = einlesen();
        System.out.println("Geben Sie eine Laufzeit in Jahren ein (Ganzzahl): ");
        int laufzeit = (int) einlesen();
              
        Zinseszins zinsesZins = new Zinseszins(betrag, prozent, laufzeit);
    
        for(int i=1; i <= laufzeit; i++){
          
            System.out.println("Das Kapital am Ende des " + i + ". Jahres betraegt " + zinsesZins.ergebnisBerechnen());
        }

    }
  
}

Java:
public class Zinseszins {

    double betrag;
    double prozent;
    int laufzeit;

    public Zinseszins(double betrag, double prozent, int laufzeit) {

        this.betrag = betrag;
        this.prozent = prozent;
        this.laufzeit = laufzeit;

    }

    public double ergebnisBerechnen() {
        betrag = betrag *(1+prozent);
        return betrag;
    }


}
 
kurze Frage noch
Ich möchte nach einem Algorithmus PI berechnen.
Warum geht folgende Anweisung nicht?

double sum -= (1/n);

Fehler ist:
Syntax error on token "-=", = expected

Java:
public double berechnePI(){
      
        for (int i = 1; i <= anzahlStellen; i++){
            double n = Math.pow(2, i) - 1;
            double sum -= (1/n);
        }
        return PI;
      
    }
 
Weil du da ja sum auch gleichzeitig schon auf der rechten Seite der Zuweisung verwendest.

Edit: na ja nicht so ganz. Es ist eher eine Initialisierung und die geht in der Form nicht. Also nochmal, hinter double sum kommt entweder ein ; oder eine Initialisierung mit = aber nix mit -= += etc.

Edit1: mal davon abgesehen dass es auch semantisch falsch wäre. Du würdest ja innerhalb der Schleife jedesmal eine neue Variable sum deklarieren ! Der alte Wert wäre dann verloren. d.h. das double sum; gehört vor die Schleife
 
Zuletzt bearbeitet:
ok, das hab ich gelöst.
ich überlege jetzt schon eine halbe Stunde, aber wie macht man alternierendes Vorzeichen in Java in der Schleife bei jedem Durchgang?
 
Code:
+(-1)^i*deineZahl

z.b.

/e oder mit einem if auf i%2 == 0 prüfen und dann je nach je plus oder minus ausführen
 
das hab ich ja so oder nicht?
ich sollte pi = 4 * (1 - 1/3 + 1/5 - 1/7 etc.) rechnen.
Ich soll dabei 32000 Terme berücksichtigen.
Die Berechnung sollte mit folgendem Code doch passen oder?
Java:
import java.lang.Math;


public class Berechnung_von_PI {

  
    double PI;
    int anzahlStellen;
    double sum = 0;
    double differenz;
  
    public Berechnung_von_PI(int anzahlStellen){
      
        this.anzahlStellen = anzahlStellen;
      
    }
  
    public double berechnePI(){
      
        for (int i = 1; i <= anzahlStellen; i++){
            double n = (2*i - 1);
            sum += (1/n)  * (Math.pow(-1,n));
              if (n==1){
                sum=0;
             }
        }
        PI = 4 * (1-sum);
        return PI;
      
    }
  
    public double getDifferenz(){
        differenz = Math.PI - berechnePI();
        return differenz;
    }
}

Java:
public class Test {

    public static void main(String[] args) {
      
        Berechnung_von_PI zahlPI = new Berechnung_von_PI(32000);
        double PI = zahlPI.berechnePI();
        System.out.println("Die berechnete Zahl von PI ist: " + PI);
        double differenz = zahlPI.getDifferenz();
        System.out.println("Die Differenz zu realem PI ist: " + differenz);
      

    }

}
 
Math.pow(-1, i) in deinem Fall

dann ist es einmal positiv und einmal negativ. Also quasi einmal addition einmal Subtraktion. Halt einfach mit der Zählvariabel
 
Das ihr das immer so schnell seht... das demotiviert mich 😛
das funktioniert in diesem Fall auch, danke 😀
das neue Jahr fängt gut an, ich komme voran 😉 ...
....natürlich nur mit eurer Hilfe



Java:
import java.lang.Math;


public class Berechnung_von_PI {

  
    double PI;
    int anzahlStellen;
    double sum = 0;
    double differenz;
  
    public Berechnung_von_PI(int anzahlStellen){
      
        this.anzahlStellen = anzahlStellen;
      
    }
  
    public double berechnePI(){
      
        for (int i = 1; i <= anzahlStellen; i++){
            double n = (2*i - 1);
            sum += (1/n)  * (Math.pow(-1,i));
              if (n==1){
                sum=0;
             }
        }
        System.out.println(sum);
        PI = 4 * (1-sum);
        return PI;
      
    }
  
    public double getDifferenz(){
        differenz = Math.PI - berechnePI();
        return differenz;
    }
}

Java:
public class Test {

    public static void main(String[] args) {
      
        Berechnung_von_PI zahlPI = new Berechnung_von_PI(32000);
        double PI = zahlPI.berechnePI();
        System.out.println("Die berechnete Zahl von PI ist: " + PI);
        double differenz = zahlPI.getDifferenz();
        System.out.println("Die Differenz zu realem PI ist: " + differenz);
      

    }

}
 
Nochmals kurze Frage:
Hier steht, ich sollte nun eine Version machen, bei der die Berechnung stoppt, sobald das Resultat auf 5 Dezimalstellen genau ist, sprich mein berechneter Wert von PI mit den 5 Nachkommastellen vom wirklichen PI übereinstimmt.
Ich habe jetzt versucht, die Math.PI zu berehnen einer Variable des Typs double zu übergeben.
Dann habe ich versucht diese Variable in einen ZahlenString umzuwandeln. mittels dem String.parseString(x)
(Da kommt mir leider eine Fehlermeldung, dass dies mit double nicht geht), mit toString gehts es auch nicht..
Dann hatte ich vor irgendwie durch eine Abfrage herauszufinden, wo das komma steht, um dann die nächsten 5 Dezimalstellen abzufragen

Aber das ist ja viel zu kompliziert, geht das nicht irgendwie einfacher??
 
ok, und wie stelle ich das an?
Ich muss ja irgendwie eine Schleife zählen lassen und gleichzeitig überprüfen, ob der WErt erreicht wurde.
wenn ich aus der Schleife hüpfe um zu überprüfen, ist es doch vorbei.
 
ok, ich habe mal etwas zusammen, aber irgendwas funktioniert noch nicht so ganz.
Ich denke, die Schleife hört einfach nicht auf..
Ich habe aber keine Ahnung, wo das Problem liegt..

Java:
import java.lang.Math;

public class PI_ohne_Terme {
  
    double sum, differenz, pi, n;
  
    public PI_ohne_Terme(){
      
        double sum = 0;
        double differenz = 0;
        double pi = 0;
        double n = 0;
      
    }
  
    public double berechnePI(){
      
        int i = 0;
        int n= 32000 - 1;
        while (differenz <= 0.0001) {
          
            n++;
            for (i=0; i<=n; i++){
            n = (2*i - 1);
            sum += (1/n)  * (Math.pow(-1,i));
              if (n==1){
                sum=0;
             }
            }
            pi = 4 * (1-sum);
            differenz = Math.PI - pi;
          
        }
        return pi;
      
      
    }

}

Java:
public class Test2 {

    public static void main(String[] args) {

        PI_ohne_Terme zahl = new PI_ohne_Terme();
        double pi = zahl.berechnePI();
        System.out.println(pi);

    }

}
 
du musst die schleifen ja nicht verschachteln
macht doch ein
Code:
while(differenz <=0.0001 && i <= n)
 
ich weiss nicht was du meinst, ich summiere alle Terme in der For Schleife und berechne ausserhalb der ForSchleife pi aus.
dann bilde ich die Differenz, wenn die Diffenz nicht passt
zähle ich n eins dazu und mache den ganzen Spass nochmals, bis der Vergleich stimmt.
Das geht ja nicht, wenn ich n mit in die while nehme oder??

aber ist auch ok, wenn ich das so nicht hinbekomme, das hat auch nichts mehr direkt mit Java zu tun..

Mir ist noch aufgefallen:

Wenn ich also zB Math.PI einer Variable zuweise, welche als double deklariert ist.
diese dann zu einem String machen will.
Mit welchem Befehl stelle ich das an und wie könnte ich dabei die Stelle suchen, wo das Komma steht und danach die Nachkommastellen abfragen?
Geht das irgendwie??
 
Wieso willst du das tun? Die Differenz zu berechnen ist viel einfacher.

habe mal mit berechnePI rumgespielt und versucht soviel wie möglich von dir drin zu belassen.

Java:
    public double berechnePI(){
        double pi = 0;
        double n = 0;
        int i = 1;
        double differenz = 3; // initial nicht auf 0 setzen sonst gehts nie in die schleife
        double sum = 0;
        int maxRuns= 32000 - 1;
        while (differenz >= 0.000001&& i <= maxRuns) {
            n = (2*i - 1);
            sum += (1/n)*(Math.pow(-1,i+1)); // +1 weil sonst im ersten durchlauf subtrahiert wird da -1^1 = -1
            pi = 4 * sum;
            differenz = Math.abs(Math.PI - pi);
            i++;
        }
        return pi;
    }
 
ok, du hast wie ich sehe auch die Formel für pi geändert..
wieso komme ich aber bei meiner "falsch gerechneten" Variante, wenn man die Berechnung mal ausser Acht lässt, nicht aus der Schleife. Das hab ich immer noch nicht gerafft.

ps: habs raus, das <= 0.0001 ist falsch...
wenn dann >=
 
Zuletzt bearbeitet:
Ich hab die Formel für Pi nicht verändert, schau es dir mal genau an. Ich hab einfach die 1 oben in die Summe reingenommen, damit ich das nicht gesondert behandeln muss.

Weil dein if falsch war. (differenz <=0.0001 statt differenz >= 0.00001) Du bist solange drin geblieben wie es kleiner ist. Am Anfang hast du es dann gleich auf 0 gesetzt und im inneren loop 32000x berechnet, was auch wieder kleiner war als 0.0001
 
jetzt seh ichs auch😀

Ich möchte es nun nicht noch so kompliziert programmieren, aber dennoch wüsste ich gerne:

Wenn ich also zB Math.PI einer Variable zuweise, welche als double deklariert ist.
Diese dann zu einem String mache, aber kein Array nutzen möchte.
Mit welchem Befehl stelle ich das an und wie könnte ich dabei die Stelle suchen, wo das Komma steht und danach die Nachkommastellen abfragen?
Geht das irgendwie??
 
Mit String.valueOf(double d), dann mit findstr und substring die Zeichen auslesen, aber wie gesagt, zu lernzwecken mag das OK sein, eine saubere Lösung ist das aber auf keinen Fall
 
Vielen Dank 🙂
Darum hatte ich auch gefragt, ob das nicht einfacher geht.
Aber das hast du mir ja erfolgreich gezeigt.
Ich hab deshalb gefragt, weil wir sowas Ähnliches schon irgendo gebraucht hatten, dass man also irgendwelche Zeichen abfragt.. Weiss nur nicht mehr worum es da genau ging..
So ich gehe jetzt erst mal schlafen..
Gut Nacht
 
Hallo

ich komme übrigens und zufällig grad drauf, dass die while Schleife nicht aufgrund des Erreichens von der Differenz aufhört, sondern durch die Erreichung der Endzahl der Iteration.
Meiner Meinung nach müsste das da oben anstatt && ein || sein, aber es funktioniert weder noch.
Es hört nur auf, wenn ich den maxRun auf etwas viel Niedrigeres setze.
Aber dann stimmt die Bedingung nicht mehr, dass 5 Dezimalstellen genau sein müssen..
 
Ein && ist schon richtig, aber eventuell wird die Differenz nie erreicht. Du kannst sie ja testeshalber mal auf 0.1 setzen, dann sollte es ziemlich direkt rausspringen.
 
ja passt der Wert wird bis zu 6 Stellen gut erreicht, danach wirds mühsam... weil auch die Terme immer kleiner werden mit den Iterationen

6.535901571069758E-7
6.535895602510777E-7
3.141592000000233
Der wirkliche Wert ist: 3.141592653589793

danke

Java:
public class Test2 {

    public static void main(String[] args) {

        PI_ohne_Terme zahl = new PI_ohne_Terme();
        double pi = zahl.berechnePI();
        System.out.println(pi);
        double z = Math.PI;
        System.out.println("Der wirkliche Wert ist: " + z);
     
    }

}

Java:
import java.lang.Math;

public class PI_ohne_Terme {
  
    double sum, differenz, pi;
  
    public PI_ohne_Terme(){
      
        double sum = 0;
        double differenz = 3;
        double pi = 0;
    }
  
    public double berechnePI(){
        double n = 0;
        int i = 1;
        double differenz = 3; // initial nicht auf 0 setzen sonst gehts nie in die schleife
        int maxRuns= 10000000;
        while ((differenz >= 6.535898*Math.pow(10,-7)) && (i <= maxRuns)) {
            n = (2*i - 1);
            sum += (1/n)*(Math.pow(-1,i+1)); // +1 weil sonst im ersten durchlauf subtrahiert wird da -1^1 = -1
            pi = 4 * sum;
            differenz = Math.abs(Math.PI - pi);
            System.out.println(differenz);
            i++;
          
        }
        return pi;
    }

}
 
Zuletzt bearbeitet:

Zurück
Oben