- More precise calculation thanks to BigDecimals
- instead of adding one and ignore the postdecimals in FormatTools.minutesToTimeString, round to integer
This commit is contained in:
		@@ -6,6 +6,8 @@ import java.io.BufferedReader;
 | 
				
			|||||||
import java.io.InputStreamReader;
 | 
					import java.io.InputStreamReader;
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
import java.math.BigDecimal;
 | 
					import java.math.BigDecimal;
 | 
				
			||||||
 | 
					import java.math.MathContext;
 | 
				
			||||||
 | 
					import java.math.RoundingMode;
 | 
				
			||||||
import java.nio.charset.StandardCharsets;
 | 
					import java.nio.charset.StandardCharsets;
 | 
				
			||||||
import java.text.DecimalFormat;
 | 
					import java.text.DecimalFormat;
 | 
				
			||||||
import java.time.LocalTime;
 | 
					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_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 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 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 BigDecimal DEFAULT_TOTAL_TIME_BD = BigDecimal.valueOf(DEFAULT_TOTAL_TIME);
 | 
				
			||||||
   private static final double QUARTER_LITRE = 0.25;
 | 
					   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 static final DecimalFormat LITER_FORMAT = new DecimalFormat("0.00");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   private double totalLitres;
 | 
					   private BigDecimal totalLitresBD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   protected DrinkingBar(LocalTime startTime) {
 | 
					   protected DrinkingBar(LocalTime startTime) {
 | 
				
			||||||
      super(startTime, DEFAULT_TOTAL_TIME);
 | 
					      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);
 | 
					      super.setEndTime(endTime);
 | 
				
			||||||
      // correct necessary litres to drink based on the end time.
 | 
					      // correct necessary litres to drink based on the end time.
 | 
				
			||||||
      // lower the volume in quarter litre steps
 | 
					      // lower the volume in quarter litre steps
 | 
				
			||||||
      double calcTotalLitres = DEFAULT_TOTAL_LITRES;
 | 
					      BigDecimal calcTotalLitres = DEFAULT_TOTAL_LITRES;
 | 
				
			||||||
      double totalLitresFromMinutes = calcTotalLitres / DEFAULT_TOTAL_TIME * getTotalMinutes();
 | 
					      BigDecimal totalLitresFromMinutes = DEFAULT_TOTAL_LITRES
 | 
				
			||||||
 | 
					         .multiply(getTotalMinutesBD()) // reverse dreisatz
 | 
				
			||||||
 | 
					         .divide(DEFAULT_TOTAL_TIME_BD, MathContext.DECIMAL64);
 | 
				
			||||||
      do {
 | 
					      do {
 | 
				
			||||||
         calcTotalLitres -= QUARTER_LITRE;
 | 
					         calcTotalLitres = calcTotalLitres.subtract(QUARTER_LITRE);
 | 
				
			||||||
      } while (calcTotalLitres >= totalLitresFromMinutes);
 | 
					      } while (calcTotalLitres.compareTo(totalLitresFromMinutes) >= 0);
 | 
				
			||||||
      // add quarter since we always did a step "too many", due to the do ... while loop
 | 
					      // 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
 | 
					   @Override
 | 
				
			||||||
   protected String fillLoadingBar(long passedMinutes, boolean progressive) {
 | 
					   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) {
 | 
					      if (getTotalMinutes() > MINUTES_WITH_PAUSE && passedMinutes > MINUTES_BEFORE_PAUSE && passedMinutes <= MINUTES_WITH_PAUSE) {
 | 
				
			||||||
         effectivePassedMinutes = MINUTES_BEFORE_PAUSE;
 | 
					         effectivePassedMinutes = MINUTES_BEFORE_PAUSE;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      double currentLitres = totalLitres / getTotalMinutes() * effectivePassedMinutes + QUARTER_LITRE;
 | 
					      var effectivePassedMinutesBD = BigDecimal.valueOf(effectivePassedMinutes);
 | 
				
			||||||
      double printedLitres = currentLitres - (currentLitres % QUARTER_LITRE);
 | 
					      BigDecimal currentLitres = totalLitresBD
 | 
				
			||||||
      // double currentProgressToNextStep = 100 / QUARTER_LITRE * (currentLitres - printedLitres);
 | 
					         .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);
 | 
					      BigDecimal minutesToNextStep = getMinutesToNextStep(currentLitres);
 | 
				
			||||||
      String progressivePart = progressive ? "\r" : "";
 | 
					      String progressivePart = progressive ? "\r" : "";
 | 
				
			||||||
      return progressivePart + "Aktuelles Volumen: " + LITER_FORMAT.format(printedLitres) + "L - "
 | 
					      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
 | 
					      // 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
 | 
					      // 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
 | 
					      // 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 minutesPerLitre.multiply(litresToNextStep).setScale(0, RoundingMode.HALF_EVEN);
 | 
				
			||||||
      return BigDecimal.valueOf((minutesPerLitre * litresToNextStep) + 1);
 | 
					 | 
				
			||||||
   }
 | 
					   }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user