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
93 changes: 81 additions & 12 deletions src/main/java/htw/berlin/prog2/ha1/Calculator.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ public class Calculator {

private String latestOperation = "";

// --- NEU für wiederholtes "=" -----------------------------------------
private double lastOperand = Double.NaN; // <<< NEW: merkt den zuletzt benutzten 2. Operanden
private String lastOperator = ""; // <<< NEW: merkt den zuletzt benutzten Operator


/**
* @return den aktuellen Bildschirminhalt als String
*/
Expand Down Expand Up @@ -60,7 +65,19 @@ 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);
if ("*".equals(operation)) operation = "x";

double current = Double.parseDouble(screen);

// FALL: Es gibt bereits einen Operator, aber der 2. Operand wurde NOCH NICHT eingegeben
// -> nur den Operator austauschen (kein Rechnen, kein Zustand sonst ändern)
if (!latestOperation.isEmpty() && latestValue == current) {
latestOperation = operation;
return;
}

// normaler Fall: ersten Operanden übernehmen und Operator setzen
latestValue = current;
latestOperation = operation;
}

Expand Down Expand Up @@ -118,16 +135,68 @@ public void pressNegativeKey() {
* und das Ergebnis direkt angezeigt.
*/
public void pressEqualsKey() {
var result = switch(latestOperation) {
case "+" -> latestValue + Double.parseDouble(screen);
case "-" -> latestValue - Double.parseDouble(screen);
case "x" -> latestValue * Double.parseDouble(screen);
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);
if (latestOperation == null) latestOperation = "";
if (lastOperator == null) lastOperator = "";

double current = Double.parseDouble(screen);

// Fall A: aktiver Operator vorhanden -> erste Ausführung (z. B. 2 + 3 = 5)
if (!latestOperation.isEmpty()) {
double result = switch (latestOperation) {
case "+" -> latestValue + current;
case "-" -> latestValue - current;
case "x" -> latestValue * current;
case "/" -> {
if (current == 0.0) {
screen = "Error";
latestOperation = "";
yield Double.NaN; // ✅ use yield instead of return
}
yield latestValue / current;
}
default -> throw new IllegalArgumentException();
};

screen = Double.toString(result);
if (screen.equals("Infinity") || screen.equals("-Infinity") || screen.equals("NaN")) screen = "Error";
if (screen.endsWith(".0")) screen = screen.substring(0, screen.length() - 2);
if (screen.contains(".") && screen.length() > 11) screen = screen.substring(0, 10);

// Für wiederholtes "=" merken
lastOperand = current;
lastOperator = latestOperation;

// Ergebnis als Basis; aktiven Operator „verbrauchen“
latestValue = result;
latestOperation = "";
return;
}

// Fall B: Kein aktiver Operator -> letzte Operation wiederholen (z. B. 5 = -> 8)
if (!lastOperator.isEmpty() && !Double.isNaN(lastOperand)) {
double base = Double.parseDouble(screen);

double result = switch (lastOperator) {
case "+" -> base + lastOperand;
case "-" -> base - lastOperand;
case "x" -> base * lastOperand;
case "/" -> {
if (lastOperand == 0.0) {
screen = "Error";
yield Double.NaN; // ✅ use yield instead
}
yield base / lastOperand;
}

default -> throw new IllegalArgumentException();
};

screen = Double.toString(result);
if (screen.equals("Infinity") || screen.equals("-Infinity") || screen.equals("NaN")) screen = "Error";
if (screen.endsWith(".0")) screen = screen.substring(0, screen.length() - 2);
if (screen.contains(".") && screen.length() > 11) screen = screen.substring(0, 10);

latestValue = result; // Basis für weiteres "="
}
}
}
47 changes: 47 additions & 0 deletions src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,53 @@ void testMultipleDecimalDots() {

assertEquals(expected, actual);
}
@Test
@DisplayName("should subtract two positive numbers correctly")
void testSimpleSubtraction() {
Calculator calc = new Calculator();

calc.pressDigitKey(9);
calc.pressBinaryOperationKey("-");
calc.pressDigitKey(4);
calc.pressEqualsKey();

assertEquals("5", calc.readScreen());
}

@Test
@DisplayName("should repeat last operation when pressing equals multiple times")
void testRepeatOperation() {
Calculator calc = new Calculator();

calc.pressDigitKey(2);
calc.pressBinaryOperationKey("+");
calc.pressDigitKey(3);
calc.pressEqualsKey(); // 2 + 3 = 5
calc.pressEqualsKey(); // should repeat +3 => 8

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

assertEquals(expected, actual);
}
@Test
@DisplayName("should use the new operator if user changes it before entering second operand")
void testChangeOperatorBeforeSecondOperand() {
Calculator calc = new Calculator();

calc.pressDigitKey(7);
calc.pressBinaryOperationKey("+");
calc.pressBinaryOperationKey("*"); // Nutzer ändert Meinung: + -> *
calc.pressDigitKey(3);
calc.pressEqualsKey();

String expected = "21"; // 7 * 3
String actual = calc.readScreen();

assertEquals(expected, actual);
}




//TODO hier weitere Tests erstellen
Expand Down