Übungsblatt 7

Gruppenaufgabe 7.1: CalcTest

Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.

Übungsblatt 7
In der Aufgabe steht „Bei den Testfällen, soll die gegebene Implementierung zu falschen Ergebnissen kommen, aber die Berechnung nicht (zB. durch eine Exception) abbrechen.”

Im Fall eines (im Sinne der Aufgabe erwünschten) Überlaufs wird ebenso wie in (unerwüschten) anderen Fällen eine „java.lang.reflect.InvocationTargetException” mit anschließendem StackTrace geworfen.

Ich habe nun in Runner.java ab Zeile 35 eingefügt,

[color=gray]
}catch(Exception e) {
[/color]

if (e.getCause().toString().indexOf("java.lang.AssertionError") == 0) { System.err.println(meth.getName() + ": " + e.getCause()); continue; } else {

System.err.println("Test with method " …

und nur noch in den unerwünschten Fällen eine Exception sichtbar.

War es so gemeint?


Ich denke folgendes ist der Fall:

Es soll genau diese Exception auftreten, wenn das berechnete Ergebnis nicht mit dem in should angegebenen Wert übereinstimmt.
Dadurch, dass bei der Berechnung z.B. ein Überlauf auftritt kommt ein anderes Ergebnis raus als es eigentlich laut should rauskommen sollte.
In Runner.java soll nichts verändert werden. (Schließlich gibt man Runner.java gar nicht ab)

Meine Frage:

Kann mir jemand einen Tipp geben, wie es sein kann, dass in der Schleife durch einen Überlauf ein falsches Ergebnis rauskommt? Wenn ich ja über Integer.MAX_VALUE hinauskomme, dann muss ich ja auch wieder etwas abziehen, damit ich wieder zu einem gültigen Ergebnis komme, aber das stimmt ja dann trotz des Überlaufs?

Danke :slight_smile:

public class Calc {
	public int a = 0;

	public void calc(int x, int y[]) throws ArithmeticException{
		a += x;
		a /= 4;
		a = (int)Math.round(Math.sqrt(a));
		a *= 2;
		for(int i=0; i<y.length; ++i){
			a += y[i] / (i+1);
		}
	}
}

Ohne zu viel zu verraten, aber bedenke, dass du immer nur einen Teil vom Array drauf addierst. Also berücksichtige das folgende:

a += y[ i ] / (i+1);


Ich verstehe nicht was das teilen bringen soll. Damit kann ich ja einen Rundungsfehler erzeugen.
Aber nach einem Overflow muss ich doch wieder zurück durch einen Underflow um ein gültiges Ergebnis zu erhalten!?


Da scheinst du wohl recht zu haben. Das muss ich selbst nochmal überdenken.

Edit: Doch, durch das Teilen kann deine Rechnung schief gehen, auch ohne Rundungsfehler. Gerade nochmal probiert. Hoffentlich stimmts auch.


Innerhalb der Schleife kann ich mich aus dem Intervall [MIN_VALUE, MAX_VALUE] herausbewegen. Damit hätte ich meinen Under-/Overflow erzeugt.

Aber dann kann ich keinen gültigen Wert für den Parameter should vom Typ INT angeben, da dieser innerhalb der Intervallgrenzen liegen muss.

Also ich habs nicht hinbekommen, einen AssertionError durch Under-/Overflow in der Schleife zu erzeugen.


Wieso kannst du keinen Wert Should angeben? Das Array hat doch maximal 10 Stellen, wenn du deinen Under-oder Overflow zeitig erzeugst hast du doch noch genug Reststellen um wieder auf ein Ergebnis zu kommen dass angebbar ist.


Ein Under-/Overflow, der nicht außerhalb der Intervallgrenzen endet (letzte Zuweisung a=…), wäre zwar eine Assertion-violation, erzeugt aber keinen AssertionError wie die anderen Testmethoden. Zur Laufzeit hat sich a auf dem Zahlenkreis auch nur kurz über eine Intervallgrenze (theoretisch auch mehrfach), bis zum Schluss aber vollständig wieder in die Intervallgrenzen zurück bewegt.

Dass kann man mit einem zusätzlichen Attribut long aa gut mitverfolgen und da ist es egal, wie viele Werte das array y[] enthält.

Dann endet die Testmethode trotz des Under-/Overflow unterwegs, mit a innerhalb der Intervallgrenzen immer wie erwartet (should == is), und mit der Ausgabe “Test with method test3 OK”. Befindet sich a zum Test(methoden)ende außerhalb der Intervallgrenzen, so kann die Klasse Assert das nicht erkennen, denn der int should lässt sich nicht entsprechend parametrieren. Somit scheint dieser Teil der Aufgabenstellung nicht lösbar, solange der Parameter should vom Typ int ist. Dazu wäre hier der Typ long notwendig.


ich steh irgendwie aufm schlauch, ich versteh nicht wirklich wie man auf den Wert should kommen soll
die Berechnungen in calc haben dich nix mit der Wurzel von a zu tun, wie des in dem tipp angegeben ist.
die wurzel von a is ja nur von a abhängig und calc ja von a,x und y ?
danke!


Den Wert should musst du selbst von “Hand” ausrechnen, also dass ist der Wert der rauskommen würde wenn es keine Intervallgrenzen oder z.b. rundungsfehler geben würde.


Ich weiß auch nicht wie das gehen soll…