Rundungs- und Zusammenfassungsproblem

Status
Nicht offen für weitere Antworten.
Hallo liebes Forum,

ich bin (so gut wie) absoluter Neuling auf dem Gebiet Java und möchte nun ein Programm schreiben, das mir die Einkommensteuer berechnet. Das hat im Großen und Ganzen auch schon ganz gut geklappt, jedoch gibt es noch ein paar Kleinigkeiten, die ich noch nicht gelöst bekommen habe.
Und zwar:
1. Unterläuft mir beim Splitting-Verfahren irgendwo ein Rundungsfehler, d.h. ich komme bei einem Einkommen von 55.555,55€ nicht auf 10.010, sondern auf 10.012€. Ich habe schon ein paar Möglichkeiten durchprobiert, leider ohne Erfolg :(
2. Wollte ich mal wissen, ob es evtl. möglich ist, den Programmcode noch irgendwie mehr zusammenzufassen bzw. etwas anders zu schreiben (z.B., ob es für das Splitting-Verfahren wirklich notwendig ist, den kompletten Programmcode vom ersten Verfahren zu "kopieren" und dann zu modifizieren).

Die Aufgabe lautet:


§ 32 a EStG Einkommensteuertarif

(1) Die tarifliche Einkommensteuer bemisst sich nach dem zu versteuernden Einkommen.
Sie beträgt jeweils in Euro für zu versteuernde Einkommen

1. bis 7834 € (Grundfreibetrag): 0
2. von 7835 € bis 13139 €: (939,68y + 1400)y
3. von 13140 € bis 52551 €: (228,74z + 2397)z + 1007
4. von 52552 € bis 250400 €: 0,42x − 8064
5. von 250401 € an: 0,45x − 15576

y ist ein Zehntausendstel des 7834 € übersteigenden Teils des auf einen vollen
Euro-Betrag abgerundeten zu versteuernden Einkommens. z ist ein Zehntausendstel
des 13139 € übersteigenden Teils des auf einen vollen Euro-Betrag abgerundeten
zu versteuernden Einkommens. x ist das auf einen vollen Euro-Betrag abgerundete
zu versteuernde Einkommen. Der sich ergebende Steuerbetrag ist auf
den nächsten vollen Euro-Betrag abzurunden.

(5) Bei Ehegatten, die zusammen zur Einkommensteuer veranlagt werden, beträgt
die tarifliche Einkommensteuer das Zweifache des Steuerbetrags, der sich
für die Hälfte ihres gemeinsam zu versteuernden Einkommens nach Absatz 1 ergibt
(Splitting-Verfahren).

Ihre Aufgabe ist es ein Programm zu schreiben, das auf der Kommandozeile als Parameter
ein zu versteuerndes Einkommen erhält und als Ergebnis die sich nach § 32 a (1) und (5)
ergebenden Steuerbeträge ausgibt.

Beispiel:

javac Steuer.java
java Steuer 55555.55
15269 Euro
10010 Euro (Splitting-Verfahren)



Java:
public class Einkommensteuer {
	
	public static void main(String[] a) {
		
		double einkommen = Double.parseDouble(a[0]); 
		double x,
			y,
			z,
			steuer = 0,
			splitting = 0;

		if (einkommen <= 7834 && einkommen >= 0) {    //Abschnitt für Einkommensteuer nach (1)
			steuer = 0;
		}

			else if (einkommen < 0) {
				System.out.println("Negatives Einkommen, Eingabe bitte überprüfen!");
			}

			else if (einkommen > 7834 && einkommen <= 13139) {
				y = einkommen / 10000;
				steuer = (939.68 * y + 1400) * y;
			}

			else if (einkommen > 13139 && einkommen <= 52551) {
				z = einkommen / 10000;
				steuer = (228.74 * z + 2397) * z + 1007;
			}

			else if (einkommen > 52551 && einkommen <= 250400) {
				x = einkommen;
				steuer = (0.42 * x) - 8064;
			}

			else if (einkommen > 250400) {
				x = einkommen;
				steuer = (0.45 * x) - 15576;
			}


		if (einkommen / 2 <= 7834 && einkommen / 2 >= 0) {      //Abschnitt für Splitting-Verfahren
			splitting = 0;
		}

			else if (einkommen < 0) {
				System.out.println("Negatives Einkommen, Eingabe bitte überprüfen!");
			}

			else if (einkommen / 2 > 7834 && einkommen / 2 <= 13139) {
				y = einkommen  / 10000;
				splitting = (939.68 * y + 1400) * y;
			}

			else if (einkommen / 2 > 13139 && einkommen / 2 <= 52551) {
				z = (einkommen / 2 - 13139) / 10000;
				splitting = (228.74 * z + 2397) * z + 1007;
			}

			else if (einkommen / 2 > 52551 && einkommen / 2 <= 250400) {
				x = einkommen;
				splitting = (0.42 * x) - 8064;
			}

			else if (einkommen / 2 > 250400) {
				x = einkommen;
				splitting = (0.45 * x) - 15576;
			}



		if (einkommen >= 0) {
			System.out.println("Die Einkommensteuer beträgt: "+(int)(steuer)+"€");
			System.out.println("Nach Splitting-Verfahren: "+(int)(splitting)*2+"€");
		}

	}

}

Bin für jeden Tip sehr dankbar!

Grüße
 
S

SlaterB

Gast
du rundest bisher noch sehr wenig,
in deinem Beispiel komme ich beispielsweise per Excel nachgerechnet auf ich ganz ohne Runden erstmal auf 10011,83961,
kommt dir das bekannt vor?

die Hälfte von 55.555 ist 27777,5, das musst du nach Aufgabenstellung abrunden ("x ist das auf einen vollen Euro-Betrag abgerundete [..]"), spart schon bisschen auf 10011,53296

10011,53296 ist das Doppelte der Einzelsteuer von 5005,766478, auch die soll man nach Aufgabenstellung abrunden,
also 5005 -> 10010

überall abrunden, wie die Aufgabe es sagt,
wenn du das für sich nicht kennst, dann in einem separate Programm testen,

die Variablen x,y, z alle nur einmal ausrechnen, ruhig alle einmal vor dem if/else, egal ob sie benötigt werden,

y ist übrigens "ein Zehntausendstel des 7834 € übersteigenden Teils", nicht einfach einkommen/10000

splitting:
vor dem nur einmal programmieren if/ else + x,y, z das einkommen /2 teilen, dann ist der restliche Code genauso gut,
außerdem eine Variable splitting auf true setzen, damit du am Ende weißt, dass du noch *2 rechnen musst
 
Erst mal danke für die schnelle Antwort :)

y ist übrigens "ein Zehntausendstel des 7834 € übersteigenden Teils", nicht einfach einkommen/10000

Das habe ich jetzt schon mal gecheckt^^ Jetzt verstehe ich auch, warum wir bei dem z in der Beispielrechnung 27777 - 13139 gerechnet haben.

die Variablen x,y, z alle nur einmal ausrechnen, ruhig alle einmal vor dem if/else, egal ob sie benötigt werden,

Wenn ich die alle aber vorher schon ausrechne, muss ich dann aber für das Splitting-Verfahren nicht neue Variablen definieren? Weil x,y,z dort doch etwas anders berechnet werden (da Einkommen/2)? Beziehungsweise, wie stelle ich das an, wenn das wirklich möglich ist?
Macht das eigentlich gar nichts aus, dass ich im Teil für das Splitting-Verfahren die gleichen Variablen benutzt habe, wie weiter oben schon? Also sind x, y und z nicht bereits Werte von "oben" zugeordnet?

Abrunden tue ich doch mit (int)(Zahlen/Rechnung) oder nicht?

splitting:
vor dem nur einmal programmieren if/ else + x,y, z das einkommen /2 teilen, dann ist der restliche Code genauso gut,
außerdem eine Variable splitting auf true setzen, damit du am Ende weißt, dass du noch *2 rechnen musst

Das habe ich noch nicht so verstanden...und wie und was mache ich mit dem true? :oops:

Das Programm rechnet jetzt für das Beispiel mit dem Einkommen von 55.555,55€ genauso, wie wir das auch gezeigt bekommen haben...allerdings komme ich beim Splitten immer noch nicht auf 10010€, sondern auf 7264€.

[JAVA=54]else if (einkommen / 2 > 13139 && einkommen / 2 <= 52551) {
z = ((int)(einkommen / 2) - 13139) / 10000;
splitting = (228.74 * z + 2397) * z + 1007;
}[/code]
 
S

SlaterB

Gast
es ist so simpel, dass man es gar nicht erklären kann,
einfach irgendwo
einkommen = einkommen/2;
schon ist der Rest exakt derselbe, x,y,z musst du nicht neu ausrechnen, die beziehen sich doch automatisch auf das verringerte Einkommen, falls die Code-Reihenfolge stimmt,
nur noch daran denken, am Ende die Steuer zu verdoppeln

am anschaulichsten und saubersten ist es mit einer Untermethode

steuer = berechneSteuer(einkommen);

oder bei Splitting
steuer = 2* berechneSteuer(einkommen/2);

der Untermethode berechneSteuer(int x) ist es dann ganz egal, ob doppelt oder einfach

-------

noch ein wichtiger Test-Tipp:
berechne die Steuer an den Grenzen, also wieviel Steuer bei z.B. 13137-13143 Euro in ein Euro-Schritten,
der Übergang müsste da ja punktgenau sein, die Steuer verändert sich höchstens um paar Cent pro Euro,
wenn irgendwo bei nur einem Euro Unterschied Einkommen auf einmal ein großer Steuersprung von > 1 Euro ist, dann ist bestimmt noch irgendwo ein Fehler,
falls es von der Rechenvorschrift nicht so gedacht ist, auf Papier nachrechnen
 
Bei mir sieht es jetzt folgendermaßen aus:

Java:
import java.lang.Math;

public class Einkommensteuer {
	
	public static void main(String[] a) {
		
		double einkommen = Double.parseDouble(a[0]);
		double x = Math.floor(einkommen);
		double y = (Math.floor(einkommen) - 7834) / 10000;
		double z = (Math.floor(einkommen) - 13139) / 10000;
		double steuer = 0,
		       splitting = 0;


		if (einkommen <= 7834 && einkommen >= 0) {
			steuer = 0;
		}

			else if (einkommen > 7834 && einkommen <= 13139) {
				steuer = (939.68 * y + 1400) * y;
			}

			else if (einkommen > 13139 && einkommen <= 52551) {
				steuer = (228.74 * z + 2397) * z + 1007;
			}

			else if (einkommen > 52551 && einkommen <= 250400) {
				steuer = (0.42 * x) - 8064;
			}

			else if (einkommen > 250400) {
				steuer = (0.45 * x) - 15576;
			}


		einkommen = einkommen / 2;

		if (einkommen <= 7834 && einkommen >= 0) {
			splitting = 0;
		}

			else if (einkommen > 7834 && einkommen <= 13139) {
				splitting = (939.68 * y + 1400) * y;
			}

			else if (einkommen > 13139 && einkommen <= 52551) {
				splitting = (228.74 * z + 2397) * z + 1007;
			}

			else if (einkommen > 52551 && einkommen <= 250400) {
				splitting = (0.42 * x) - 8064;
			}

			else if (einkommen > 250400) {
				splitting = (0.45 * x) - 15576;
			}


		if (einkommen >= 0) {
			System.out.println("Die Einkommensteuer beträgt: "+Math.floor(steuer)+" Euro");
			System.out.println("Nach Splitting-Verfahren: "+Math.floor(splitting) * 2+" Euro");
		}

		else {
			System.out.println("Negatives Einkommen, bitte Eingabe überprüfen!");
		}		

	}

}

Übrigens hat die Beispielrechnung gestern noch geklappt und zwar, nachdem ich mit Math.floor gerundet habe und nicht mehr mit (int)(x). Jetzt habe ich x, y und z bereits oben initialisiert und einkommen = einkommen / 2 eingefügt, komme aber nicht mehr auf das richtige Ergebnis...von der Codereihenfolge müsste das doch aber okay sein oder?
Das mit der Untermethode für die zu berechnende Steuer verstehe ich nicht so ganz...ist das so nicht okay, wie ich das in Zeile 60 und 61 gemacht habe?
Den Test mit den 1€-Schritten mache ich dann auch noch auf jeden Fall :toll:
 
S

SlaterB

Gast
du rechnest erst y = einkommen ...;
und danach einkommen = einkommen / 2;
aber y bezieht sich noch auf das ursprüngliche einkommen

und das obwohl das schon vorher ein Thema war
> Also sind x, y und z nicht bereits Werte von "oben" zugeordnet?

> schon ist der Rest exakt derselbe, x,y,z musst du nicht neu ausrechnen, die beziehen sich doch automatisch auf das verringerte Einkommen, falls die Code-Reihenfolge stimmt,

muss ich wirklich dazu was schreiben? da vergeht mir ja jede Hoffnung auf Erkenntnis
 
Status
Nicht offen für weitere Antworten.

Oben