Kreditrechner

Hag2bard

Bekanntes Mitglied
Hallo,

ich programmiere momentan einen Kreditrechner und habe folgende Formel gegeben:
1701949156832.png

Leider kann ich damit absolut nichts anfangen. Klar ich kann alles ausrechnen, aber das Ergebnis ist totaler Unsinn.
Werte zum Kontrollieren:
Kreditsumme = 24000€
Zinssatz = 5%
Laufzeit = 47 Monate

Ergebnis soll sein : 563,3€


Mein Ergebnis ist allerdings 536,17€.

Laut einem Online-Kreditrechner stimmt das Ergebnis von 563,3€.

Wie kann das sein?

Ich habe eine Kreditsumme von 24.000€. Da kommen 5% drauf, d.h. wir sind bei 25.200€.
Abschließend rechne ich die 25.200€ durch 47 Monate, sind bei mir wie gesagt 536,17€.

Das ganze soll nach der Annuitätenformel funktionieren.
Google hilft mir nicht weiter, bzw. sind da Formeln dabei, von denen mir schlecht wird. (nicht lesbar)
 

LimDul

Top Contributor
Code?

Grundsätzlich sind Fließkomma-Operationen verlustbehaftet. Ursache des Fehlers kann folgendes sein:
  • Datentyp. float ist z.B. denkbar ungeeignet - double ist besser, sinnvoller wäre BigDecimal.
  • Irgendwo eine integer Division im Code, so dass da Nachkommastellen wegfallen
  • Fehler in der Umsetzung

Bei einer Abweichung von 0.13 tippe ich auf ersteres.
 

KonradN

Super-Moderator
Mitarbeiter
Dann zeige doch bitte einmal Deinen Code. Evtl. liegt es an verwendeten Datentypen ... Oder Du hast die Formel an einer Stelle nicht richtig umgesetzt ...
 

Hag2bard

Bekanntes Mitglied
Java:
    private void calculateRate() {
        double bruch1 = zinsSatz/1200;
        double klammer1 = 1+bruch1;
        double klammerOben = Math.pow(bruch1*klammer1,laufZeit);
        double klammerUnten = (Math.pow(klammer1,laufZeit))-1;
        rate = kreditSumme*(klammerOben/klammerUnten);
    }

Noch sind die Bezeichnungen deutsch, da ich hier nicht durcheinander kommen wollte
 

Hag2bard

Bekanntes Mitglied
Vielen Dank, genau das war das Problem. Ich versuche jetzt noch zu verstehen, wieso ich diesen Fehler gemacht habe und was ich in Zukunft anders machen kann, damit mir solche Formeln nicht das Genick brechen.

edit: Ich weiß dass man dies in der 6. Klasse lernt, aber ich glaube ich habe die Regel übergangen, nach der eine Potenz eine höhere Hierarchie hat beim Klammerrechnen als ein Faktor.
4*(1+2)^3 = 108
und nicht = 1728


Ergebnis:
1701951393351.png
Java:
package de.dch.kreditrechner;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;

public class HelloApplication extends Application {
    @Override
    public void start(Stage stage) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
        Scene scene = new Scene(fxmlLoader.load(), 380, 450);
        stage.setTitle("Finanzrechner");
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}

Java:
package de.dch.kreditrechner;

import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.control.TextArea;

import java.net.URL;
import java.util.Map;
import java.util.ResourceBundle;

public class HelloController implements Initializable {
    @FXML
    private Label kreditSummeText;

    @FXML
    private Label zinsSatzText;

    @FXML
    private Label laufZeitText;

    @FXML
    private Slider kreditSummeSlider;

    @FXML
    private Slider zinsSatzSlider;

    @FXML
    private Slider laufZeitSlider;

    @FXML
    private TextArea resultText;
    private double kreditSumme = 24000;
    private double zinsSatz = 5;
    private double laufZeit = 47;
    private double rate;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        calculateRate();
        setNewText();
        kreditSummeSlider.valueProperty().addListener((observable, oldValue, newValue) -> {
            kreditSumme = newValue.intValue();
            calculateRate();
            setNewText();
        });

        zinsSatzSlider.valueProperty().addListener((observable, oldValue, newValue) -> {
            zinsSatz = newValue.intValue();
            calculateRate();
            setNewText();
        });

        laufZeitSlider.valueProperty().addListener((observable, oldValue, newValue) -> {
            laufZeit = newValue.intValue();
            calculateRate();
            setNewText();
        });
    }

    private void calculateRate() {
        double bruch = zinsSatz / 1200;
        double klammer = 1 + bruch;
        double nenner = bruch * (Math.pow(klammer, laufZeit));
        double zaehler = (Math.pow(klammer, laufZeit)) - 1;
        rate = kreditSumme * (nenner / zaehler);
    }

    private void setNewText() {
        String text = "Kreditsumme: " + kreditSumme
                + "\nZinssatz: " + zinsSatz
                + "\nLaufzeit: " + laufZeit
                + "\nRate: " + rate;
        resultText.setText(text);
    }
}

XML:
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Slider?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.VBox?>

<VBox alignment="CENTER" prefHeight="498.0" prefWidth="350.0" spacing="20.0" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.dch.kreditrechner.HelloController">
    <padding>
        <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
    </padding>

    <Label fx:id="kreditSummeText" text="Kreditsumme" />
   <Slider fx:id="kreditSummeSlider" blockIncrement="500.0" majorTickUnit="10000.0" max="50000.0" min="1000.0" showTickLabels="true" value="24000.0" />
   <Label fx:id="zinsSatzText" text="Zinssatz" />
   <Slider fx:id="zinsSatzSlider" blockIncrement="1.0" majorTickUnit="1.0" max="10.0" min="1.0" showTickLabels="true" value="5.0" />
   <Label fx:id="laufZeitText" text="Laufzeit" />
   <Slider fx:id="laufZeitSlider" blockIncrement="1.0" majorTickUnit="20.0" max="120.0" min="1.0" showTickLabels="true" value="47.0" />
   <TextArea fx:id="resultText" prefHeight="200.0" prefWidth="200.0" />
</VBox>
 
Zuletzt bearbeitet:

Robert Zenz

Top Contributor
Jippie! Endlich wieder ein Thema wo ich auf meine Wiederholung zum Thema Gleitkommazahlen verweisen darf, insbesondere der Absatz ueber Geld wird hier eine gewisse Rolle spielen.

Noch sind die Bezeichnungen deutsch
Belasse sie auf Deutsch wenn das Programm nur fuer Deutsch ist. Zwanghaftes Uebersetzen (teilweise von der Domaenensprache weg) ist ohnehin nicht so eine tolle Idee. Aber du kannst dir da mal die grosze Foren-Diskussion zu dem Thema zu Gemuete fuehren und deine eigene Meinung bilden.

Und mach' in deiner Oberflaeche einzelne Felder/Labels fuer die einzelnen Ergebniswerte, sieht dann huebscher aus. Auszerdem solltest du dir angewoehnen immer die Einheit dazu zu schreiben. Zum Beispiel bei Laufzeit weisz man nicht ob das Tage, Wochen, Monate oder Jahre sind.
 

Hag2bard

Bekanntes Mitglied
Ist die Ressourcennutzung von BigDecimal zu vernachlässigen bei der heutigen Leistung der Rechner? Nutzt man denn grundsätzlich BigDecimal bei Rechnungen mit Geld?
 

Robert Zenz

Top Contributor
Ist die Ressourcennutzung von BigDecimal zu vernachlässigen bei der heutigen Leistung der Rechner?
Wenn du das fragen musst ist die Antwort immer "Ja".

Jede Operation welche JavaFX bei der Interaktion mit der Oberflaeche macht wird um ein vielfaches, vielfaches teurer sein als ein paar Rechenoperationen mit BigDecimal. Ich bin mir fast sicher dass setNewText von den Kosten her teurer sein wird als die Berechnung mit BigDecimal.

Nutzt man denn grundsätzlich BigDecimal bei Rechnungen mit Geld?
Ja.
 

Hag2bard

Bekanntes Mitglied
Einfach eine konkrete Antwort, danke.
Eine Rest-Schnittstelle zu einem Frontend in C++, ist das effektiv oder nur funktional? Ich kann mir vorstellen, dass eine solche Anbindung auch Ressourcenhungrig ist. Und wäre es denn sinnvoll ein Projekt welches skalierbar sein soll grundsätzlich auf SpringBoot aufzubauen oder nutzt man das heutzutage nicht mehr?
 

KonradN

Super-Moderator
Mitarbeiter
Nutzt man denn grundsätzlich BigDecimal bei Rechnungen mit Geld?
Nicht zwingend. Es gibt auch andere Lösungen für exakte Berechnungen.

So gibt es z.B. auch https://javamoney.github.io/

Und auch einfache Möglichkeiten wie z.B. komplett mit den Cent zu rechnen, ist denkbar. Dann würde ein int reichen.

Es gibt also doch keine so einfache Antwort und es ist immer die Frage, was die Anforderungen sind und was genau gemacht wird.
 

Robert Zenz

Top Contributor
Eine Rest-Schnittstelle zu einem Frontend in C++, ist das effektiv oder nur funktional?
Das laesst sich so pauschal nicht beantworten...

Und wäre es denn sinnvoll ein Projekt welches skalierbar sein soll grundsätzlich auf SpringBoot aufzubauen oder nutzt man das heutzutage nicht mehr?
He, schoen waer's. Also ich bin kein Spring Freund, finde es teilweise komplett ueberzogen, ueberbewertet und echt fragwuerdig an einigen Stellen. Aber es die defacto Loesung fuer Server-Dienste.

Die Frage ist: Wie skalieren? Skalieren in dem du 500 Server mehr hochdrehst? Dann kannst du alles nehmen. Skalieren weil du das auf irgendeiner migrigen Maschine, vielleicht sogar embedded, laufen lassen musst? Dann am besten alles selbst schreiben oder nur Bibliotheken verwenden welche dafuer gedacht sind.

Es gibt auch Quarkus und Micronaut, welche beide aehnliche Dinge wie Spring machen, aber viel schlanker.
 

mihe7

Top Contributor
Wie kann das sein?

Ich habe eine Kreditsumme von 24.000€. Da kommen 5% drauf, d.h. wir sind bei 25.200€.
Abschließend rechne ich die 25.200€ durch 47 Monate, sind bei mir wie gesagt 536,17€.
Das liegt einfach daran, dass Du die Rate zu einfach berechnest. Leiten wir den Spaß doch mal her.

Wir haben eine Kreditsumme K0, eine Laufzeit von n Perioden und einen Zinsfuß p je Periode. Im Beispiel wäre K0 = 24.000, n = 47 (in Monaten) und p = 0,05/12 (Zinsfuß pro Monat). Außerdem eine unbekannte aber konstante Rate R.

Die Kreditsumme wird verzinst und anschließend wird die Rate bezahlt, das können wir mal mathematisch nachvollziehen. Der Einfachheit halber führe ich noch einen Aufzinsungsfaktor q = 1 + p ein.
1702458613725.png

Interessant ist hier der letzte Faktor, weil man mit Summen so schlecht rechnen kann. Wenn man die Summe allerdings mit (q-1) multipliziert, erhält man:
1702458685419.png
D. h. die Summe lässt sich als (q^n - 1) : (q - 1) darstellen. In die Formel für Kn eingesetzt ergibt dies:
1702458741210.png
Jetzt machen wir uns noch klar, dass der Kredit am Ende der Laufzeit abbezahlt sein soll, d. h. dass Kn = 0 gilt:
1702458798377.png
Dann brauchen wir nur noch umzuformen und erhalten
1702458818010.png
Und das ist nichts anderes als die eingangs erwähnte Formel.
 

Ähnliche Java Themen

Neue Themen


Oben