diff --git a/zeitlaeufer/src/main/java/de/szimnau/DrinkingBar.java b/zeitlaeufer/src/main/java/de/szimnau/DrinkingBar.java index e51e890..0ec61aa 100644 --- a/zeitlaeufer/src/main/java/de/szimnau/DrinkingBar.java +++ b/zeitlaeufer/src/main/java/de/szimnau/DrinkingBar.java @@ -6,6 +6,8 @@ import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.math.BigDecimal; +import java.math.MathContext; +import java.math.RoundingMode; import java.nio.charset.StandardCharsets; import java.text.DecimalFormat; import java.time.LocalTime; @@ -20,16 +22,17 @@ public class DrinkingBar extends AbstractLoadingBar { private static final int MINUTES_BEFORE_PAUSE = 4 * CommonTools.MINS_PER_HOUR + MINS_PER_HALF_HOUR; private static final int MINUTES_WITH_PAUSE = 6 * CommonTools.MINS_PER_HOUR; private static final int DEFAULT_TOTAL_TIME = 8 * CommonTools.MINS_PER_HOUR + MINS_PER_HALF_HOUR; - private static final double DEFAULT_TOTAL_LITRES = 2.0; - private static final double QUARTER_LITRE = 0.25; + private static final BigDecimal DEFAULT_TOTAL_TIME_BD = BigDecimal.valueOf(DEFAULT_TOTAL_TIME); + private static final BigDecimal DEFAULT_TOTAL_LITRES = BigDecimal.valueOf(2.0); + private static final BigDecimal QUARTER_LITRE = BigDecimal.valueOf(0.25); private static final DecimalFormat LITER_FORMAT = new DecimalFormat("0.00"); - private double totalLitres; + private BigDecimal totalLitresBD; protected DrinkingBar(LocalTime startTime) { super(startTime, DEFAULT_TOTAL_TIME); - this.totalLitres = DEFAULT_TOTAL_LITRES; + this.totalLitresBD = DEFAULT_TOTAL_LITRES; } @@ -38,13 +41,15 @@ public class DrinkingBar extends AbstractLoadingBar { super.setEndTime(endTime); // correct necessary litres to drink based on the end time. // lower the volume in quarter litre steps - double calcTotalLitres = DEFAULT_TOTAL_LITRES; - double totalLitresFromMinutes = calcTotalLitres / DEFAULT_TOTAL_TIME * getTotalMinutes(); + BigDecimal calcTotalLitres = DEFAULT_TOTAL_LITRES; + BigDecimal totalLitresFromMinutes = DEFAULT_TOTAL_LITRES + .multiply(getTotalMinutesBD()) // reverse dreisatz + .divide(DEFAULT_TOTAL_TIME_BD, MathContext.DECIMAL64); do { - calcTotalLitres -= QUARTER_LITRE; - } while (calcTotalLitres >= totalLitresFromMinutes); + calcTotalLitres = calcTotalLitres.subtract(QUARTER_LITRE); + } while (calcTotalLitres.compareTo(totalLitresFromMinutes) >= 0); // add quarter since we always did a step "too many", due to the do ... while loop - this.totalLitres = calcTotalLitres + QUARTER_LITRE; + this.totalLitresBD = calcTotalLitres.add(QUARTER_LITRE); } @@ -59,13 +64,19 @@ public class DrinkingBar extends AbstractLoadingBar { @Override protected String fillLoadingBar(long passedMinutes, boolean progressive) { - long effectivePassedMinutes = passedMinutes; + long effectivePassedMinutes = passedMinutes < 0 ? 0 : passedMinutes; if (getTotalMinutes() > MINUTES_WITH_PAUSE && passedMinutes > MINUTES_BEFORE_PAUSE && passedMinutes <= MINUTES_WITH_PAUSE) { effectivePassedMinutes = MINUTES_BEFORE_PAUSE; } - double currentLitres = totalLitres / getTotalMinutes() * effectivePassedMinutes + QUARTER_LITRE; - double printedLitres = currentLitres - (currentLitres % QUARTER_LITRE); - // double currentProgressToNextStep = 100 / QUARTER_LITRE * (currentLitres - printedLitres); + var effectivePassedMinutesBD = BigDecimal.valueOf(effectivePassedMinutes); + BigDecimal currentLitres = totalLitresBD + .multiply(effectivePassedMinutesBD) // reverse dreisatz + .divide(getTotalMinutesBD(), MathContext.DECIMAL64) + .add(QUARTER_LITRE); + BigDecimal printedLitres = currentLitres.subtract(currentLitres.remainder(QUARTER_LITRE, MathContext.DECIMAL64)); + /* BigDecimal currentProgressToNextStep = ONE_HUNDRED_PERCENT + .multiply(currentLitres.subtract(printedLitres)) // reverse dreisatz + .divide(QUARTER_LITRE, MathContext.DECIMAL64); */ BigDecimal minutesToNextStep = getMinutesToNextStep(currentLitres); String progressivePart = progressive ? "\r" : ""; return progressivePart + "Aktuelles Volumen: " + LITER_FORMAT.format(printedLitres) + "L - " @@ -74,13 +85,12 @@ public class DrinkingBar extends AbstractLoadingBar { } - private BigDecimal getMinutesToNextStep(double currentLitres) { + private BigDecimal getMinutesToNextStep(BigDecimal currentLitres) { // berechne Liter benötigt bis zum nächsten 0.25er Schritt - double litresToNextStep = QUARTER_LITRE - (currentLitres % QUARTER_LITRE); + BigDecimal litresToNextStep = QUARTER_LITRE.subtract(currentLitres.remainder(QUARTER_LITRE)); // berechne Minuten benötigt für 1 Liter - double minutesPerLitre = getTotalMinutes() / totalLitres; + BigDecimal minutesPerLitre = getTotalMinutesBD().divide(totalLitresBD); // berechne Minuten benötigt bis zum nächsten 0.25er Schritt - // + 1 since we only show minutes and have to adjust for the "ignored" seconds - return BigDecimal.valueOf((minutesPerLitre * litresToNextStep) + 1); + return minutesPerLitre.multiply(litresToNextStep).setScale(0, RoundingMode.HALF_EVEN); } }