Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 52 additions & 7 deletions app/src/main/java/htw/berlin/prog2/ha1/Calculator.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,22 @@ public String readScreen() {
/**
* Empfängt den Wert einer gedrückten Zifferntaste. Da man nur eine Taste auf einmal
* drücken kann muss der Wert positiv und einstellig sein und zwischen 0 und 9 liegen.
* Wenn der Bildschirm "0" anzeigt und keine Dezimalstelle vorhanden ist, wird die führende Null
* entfernt, bevor die neue Ziffer angezeigt wird. Andersfalls wird die Ziffer rechts an die vorhandene
* Zahl angehängt. Das ermöglicht es, dass Ziffern an bestehenden Werten oder Dezimalzahlen angefügt
* werden, ohne dass führende Nullen verbleiben.
* Führt in jedem Fall dazu, dass die gerade gedrückte Ziffer auf dem Bildschirm angezeigt
* oder rechts an die zuvor gedrückte Ziffer angehängt angezeigt wird.
* @param digit Die Ziffer, deren Taste gedrückt wurde
* @param digit Die Ziffer, deren Taste gedrückt wurde.
* @throws IllegalArgumentException wenn die Ziffer außerhalb des Bereiches 0-9 liegt.
*/
public void pressDigitKey(int digit) {
if(digit > 9 || digit < 0) throw new IllegalArgumentException();

if(screen.equals("0") || latestValue == Double.parseDouble(screen)) screen = "";

screen = screen + digit;
if(screen.equals("0") && !screen.contains(".")){
screen = "";
}
screen += digit;
}

/**
Expand All @@ -50,18 +56,52 @@ public void pressClearKey() {
latestValue = 0.0;
}

/**
* Führt die angegebene Operation auf 2 Operanden aus und gibt das Ergebnis zurück.
* Falls eine Division durch 0 stattfindet, gibt die Methode "Double.POSITIVE_INFINITY" zurück,
* was im Anzeigebildschirm später als "Error" dargestellt wird. Dieser spezielle Wert signalisiert,
* dass das Ergebnis mathematisch unendlich ist und über die darstellbare Zahl hinausgeht.
* @param operation Die auszuführende Operation: "+" für Addition, "-" für Subtraktion,
* "x" für Multiplikation, "/" für Division.
* @param left der linke Operand
* @param right der rechte Operand
* @return Das Ergebnis der ausgeführten Operation als double. Gibt `Double.POSITIVE_INFINITY` zurück,
* falls eine Division durch Null auftritt, was später als "Error" auf dem Bildschirm angezeigt wird.
* @throws IllegalArgumentException falls eine unbekannte Operation übergeben wird.
*/
private double applyOperation(String operation, double left, double right) {
return switch (operation) {
case "+" -> left + right;
case "-" -> left - right;
case "x" -> left * right;
case "/" -> right == 0 ? Double.POSITIVE_INFINITY : left / right;
default -> throw new IllegalArgumentException("Unknown operation: " + operation);
};
}

/**
* Empfängt den Wert einer gedrückten binären Operationstaste, also eine der vier Operationen
* Addition, Substraktion, Division, oder Multiplikation, welche zwei Operanden benötigen.
* Beim ersten Drücken der Taste wird der Bildschirminhalt nicht verändert, sondern nur der
* Rechner in den passenden Operationsmodus versetzt.
* Beim zweiten Drücken nach Eingabe einer weiteren Zahl wird direkt des aktuelle Zwischenergebnis
* auf dem Bildschirm angezeigt. Falls hierbei eine Division durch Null auftritt, wird "Error" angezeigt.
* Die Methode wurde daraufhin erweitert, damit wir die Zwischenergebnisse sofort berechnet werden, wenn
* neue Operationen gedrückt werden. Dies stellt hierbei sicher, dass die aufeinanderfolgenden Operationen
* korrekt verarbeitet werden.
* @param operation "+" für Addition, "-" für Substraktion, "x" für Multiplikation, "/" für Division
*/
public void pressBinaryOperationKey(String operation) {
latestValue = Double.parseDouble(screen);
public void pressBinaryOperationKey(String operation) {
double currentValue = Double.parseDouble(screen);

if (!latestOperation.isEmpty()) {
currentValue = applyOperation(latestOperation, latestValue, currentValue);
screen = String.valueOf(currentValue);
}

latestValue = currentValue;
latestOperation = operation;
screen = "0";
}

/**
Expand Down Expand Up @@ -92,9 +132,13 @@ public void pressUnaryOperationKey(String operation) {
* Seite hinzu und aktualisiert den Bildschirm. Daraufhin eingegebene Zahlen werden rechts vom
* Trennzeichen angegeben und daher als Dezimalziffern interpretiert.
* Beim zweimaligem Drücken, oder wenn bereits ein Trennzeichen angezeigt wird, passiert nichts.
* Falls der Bildschirm nur "0" anzeigt oder leer ist, wird automatisch "0." hinzugefügt, um sicherzustellen,
* dass das Dezimalformat korrekt ist. Diese Änderung stellt sicher, dass die Dezimalzahlen wie angezeigt werden.
*/
public void pressDotKey() {
if(!screen.contains(".")) screen = screen + ".";
if(!screen.contains(".")) {
screen = (screen.equals("0") || screen.isEmpty()) ? "0." : screen + ".";
}
}

/**
Expand Down Expand Up @@ -130,4 +174,5 @@ public void pressEqualsKey() {
if(screen.endsWith(".0")) screen = screen.substring(0,screen.length()-2);
if(screen.contains(".") && screen.length() > 11) screen = screen.substring(0, 10);
}

}
48 changes: 47 additions & 1 deletion app/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,54 @@ void testMultipleDecimalDots() {

assertEquals(expected, actual);
}
@Test
@DisplayName("should display result after multiplying two positive numbers")
void testMultiplication() {
Calculator calc = new Calculator();

calc.pressDigitKey(5);
calc.pressBinaryOperationKey("x");
calc.pressDigitKey(8);
calc.pressEqualsKey();

String expected = "40";
String actual = calc.readScreen();

assertEquals(expected, actual);

}

@Test
@DisplayName("should handle consecutive subtractions correctly")
void testConsecutiveSubtraction() {
Calculator calc = new Calculator();

//TODO hier weitere Tests erstellen
calc.pressDigitKey(8);
calc.pressBinaryOperationKey("-");
calc.pressDigitKey(2);
calc.pressBinaryOperationKey("-");
calc.pressDigitKey(2);
calc.pressEqualsKey();

String expected = "4";
String actual = calc.readScreen();

assertEquals(expected, actual);
}

@Test
@DisplayName("should handle decimal point at the start of input")
void testDecimalPoint() {
Calculator calc = new Calculator();

calc.pressDotKey();
calc.pressDigitKey(2);

String expected = "0.2";
String actual = calc.readScreen();

assertEquals(expected, actual);

}
}