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..1514aec 100644 --- a/app/src/main/java/htw/berlin/prog2/ha1/Calculator.java +++ b/app/src/main/java/htw/berlin/prog2/ha1/Calculator.java @@ -1,5 +1,7 @@ package htw.berlin.prog2.ha1; +import java.util.OptionalDouble; + /** * Eine Klasse, die das Verhalten des Online Taschenrechners imitiert, welcher auf * https://www.online-calculator.com/ aufgerufen werden kann (ohne die Memory-Funktionen) @@ -10,10 +12,12 @@ public class Calculator { private String screen = "0"; - private double latestValue; + private OptionalDouble latestValue = OptionalDouble.empty(); private String latestOperation = ""; + private boolean resetScreen = false; // Is used to controll reset from the binary operator + /** * @return den aktuellen Bildschirminhalt als String */ @@ -31,7 +35,9 @@ public String readScreen() { public void pressDigitKey(int digit) { if(digit > 9 || digit < 0) throw new IllegalArgumentException(); - if(screen.equals("0") || latestValue == Double.parseDouble(screen)) screen = ""; + if(screen.equals("0") || resetScreen) screen = ""; + + resetScreen = false; screen = screen + digit; } @@ -47,7 +53,8 @@ public void pressDigitKey(int digit) { public void pressClearKey() { screen = "0"; latestOperation = ""; - latestValue = 0.0; + latestValue = OptionalDouble.empty(); + resetScreen = false; } /** @@ -60,8 +67,9 @@ public void pressClearKey() { * @param operation "+" für Addition, "-" für Substraktion, "x" für Multiplikation, "/" für Division */ public void pressBinaryOperationKey(String operation) { - latestValue = Double.parseDouble(screen); + latestValue = OptionalDouble.of(this.calculate()); latestOperation = operation; + resetScreen = true; } /** @@ -72,18 +80,16 @@ public void pressBinaryOperationKey(String operation) { * @param operation "√" für Quadratwurzel, "%" für Prozent, "1/x" für Inversion */ public void pressUnaryOperationKey(String operation) { - latestValue = Double.parseDouble(screen); - latestOperation = operation; - var result = switch(operation) { + var value = switch(operation) { case "√" -> Math.sqrt(Double.parseDouble(screen)); case "%" -> Double.parseDouble(screen) / 100; case "1/x" -> 1 / Double.parseDouble(screen); + case "-" -> -Double.parseDouble(screen); default -> throw new IllegalArgumentException(); }; - screen = Double.toString(result); + screen = Double.toString(value); if(screen.equals("NaN")) screen = "Error"; - if(screen.contains(".") && screen.length() > 11) screen = screen.substring(0, 10); - + screen = trimFloatingPoints(screen); } /** @@ -118,6 +124,26 @@ public void pressNegativeKey() { * und das Ergebnis direkt angezeigt. */ public void pressEqualsKey() { + var result = calculate(); + screen = Double.toString(result); + if(screen.equals("Infinity")) screen = "Error"; + screen = trimFloatingPoints(screen); + } + + + /** + * Calculates the current value with the value in the screen. + * If there is no current value it will return the value of the screen, + * + * @return Result of the current calculation + */ + private double calculate() { + if (latestValue.isEmpty()) { + return Double.parseDouble(screen); + } + + var latestValue = this.latestValue.getAsDouble(); + var result = switch(latestOperation) { case "+" -> latestValue + Double.parseDouble(screen); case "-" -> latestValue - Double.parseDouble(screen); @@ -125,9 +151,17 @@ public void pressEqualsKey() { case "/" -> latestValue / Double.parseDouble(screen); default -> throw new IllegalArgumentException(); }; - screen = Double.toString(result); - if(screen.equals("Infinity")) screen = "Error"; - if(screen.endsWith(".0")) screen = screen.substring(0,screen.length()-2); - if(screen.contains(".") && screen.length() > 11) screen = screen.substring(0, 10); + + return result; + } + + + /** + * Trim floating point string. + */ + private static String trimFloatingPoints(String input) { + if(input.endsWith(".0")) input = input.substring(0,input.length()-2); + if(input.contains(".") && input.length() > 11) input = input.substring(0, 10); + return input; } } 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..b400ef9 100644 --- a/app/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java +++ b/app/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java @@ -90,5 +90,53 @@ void testMultipleDecimalDots() { //TODO hier weitere Tests erstellen + + @Test + @DisplayName("should parse percent") + void testPercent() { + Calculator calc = new Calculator(); + calc.pressDigitKey(5); + calc.pressBinaryOperationKey("+"); + calc.pressDigitKey(5); + calc.pressDigitKey(0); + calc.pressUnaryOperationKey("%"); + calc.pressEqualsKey(); + + String expected = "5.5"; + String actual = calc.readScreen(); + assertEquals(expected, actual); + } + + @Test + @DisplayName("should parse multiple operators") + void testMultipleOperators() { + Calculator calc = new Calculator(); + calc.pressDigitKey(9); + calc.pressBinaryOperationKey("+"); + + calc.pressUnaryOperationKey("1/x"); + calc.pressDigitKey(3); + + + String expected = "3"; + String actual = calc.readScreen(); + assertEquals(expected, actual); + } + + @Test + @DisplayName("should calculate multiple binary operators") + void testMultipleBinaryOperators() { + Calculator calc = new Calculator(); + calc.pressDigitKey(9); + calc.pressBinaryOperationKey("+"); + calc.pressDigitKey(3); + calc.pressBinaryOperationKey("-"); + calc.pressDigitKey(2); + calc.pressEqualsKey(); + + String expected = "10"; + String actual = calc.readScreen(); + assertEquals(expected, actual); + } }