diff --git a/app/src/main/java/htw/berlin/prog2/ha1/Calculator.java b/app/src/main/java/htw/berlin/prog2/ha1/Calculator.java index 84c04f2..013a39a 100644 --- a/app/src/main/java/htw/berlin/prog2/ha1/Calculator.java +++ b/app/src/main/java/htw/berlin/prog2/ha1/Calculator.java @@ -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; } /** @@ -50,6 +56,29 @@ 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. @@ -57,11 +86,22 @@ public void pressClearKey() { * 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"; } /** @@ -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 + "."; + } } /** @@ -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); } + } diff --git a/app/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java b/app/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java index ddff0da..e2cf4a4 100644 --- a/app/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java +++ b/app/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java @@ -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); + + } }