Fix number input floating point issue when pressing plus/minus buttons

This commit is contained in:
2026-02-02 18:04:14 +00:00
parent 2c55652f92
commit 11dacb5441
3 changed files with 20 additions and 4 deletions

View File

@@ -99,15 +99,23 @@ const FormNumericInput = React.forwardRef<HTMLInputElement, NumericInputProps>(
numValue = 0
}
// Round the current value to avoid floating-point precision issues in comparisons
const decimalPlaces = getDecimalPlaces()
numValue = Math.round(numValue * Math.pow(10, decimalPlaces)) / Math.pow(10, decimalPlaces)
// Snap to nearest increment first, then move one increment in the desired direction
if (direction > 0) {
// For increment: round up to next increment value, ensuring at least one increment is added
const snapped = Math.ceil(numValue / numIncrement) * numIncrement
numValue = snapped > numValue ? snapped : snapped + numIncrement
const steps = Math.round((numValue / numIncrement) * 1e10) / 1e10 // Avoid floating-point errors in division
const snappedSteps = Math.ceil(steps)
const snapped = Math.round((snappedSteps * numIncrement) * Math.pow(10, decimalPlaces)) / Math.pow(10, decimalPlaces)
numValue = snapped > numValue ? snapped : Math.round(((snappedSteps + 1) * numIncrement) * Math.pow(10, decimalPlaces)) / Math.pow(10, decimalPlaces)
} else {
// For decrement: round down to previous increment value, ensuring at least one increment is subtracted
const snapped = Math.floor(numValue / numIncrement) * numIncrement
numValue = snapped < numValue ? snapped : snapped - numIncrement
const steps = Math.round((numValue / numIncrement) * 1e10) / 1e10 // Avoid floating-point errors in division
const snappedSteps = Math.floor(steps)
const snapped = Math.round((snappedSteps * numIncrement) * Math.pow(10, decimalPlaces)) / Math.pow(10, decimalPlaces)
numValue = snapped < numValue ? snapped : Math.round(((snappedSteps - 1) * numIncrement) * Math.pow(10, decimalPlaces)) / Math.pow(10, decimalPlaces)
}
numValue = Math.max(min, numValue)

View File

@@ -314,6 +314,10 @@ export const de = {
timePickerApply: "Übernehmen",
timePickerCancel: "Abbrechen",
// Input field placeholders
min: "Min",
max: "Max",
// Sorting
sortByTime: "Nach Zeit sortieren",
sortByTimeNeeded: "Dosen sind nicht in chronologischer Reihenfolge. Klicken zum Sortieren.",

View File

@@ -287,6 +287,10 @@ export const en = {
timePickerApply: "Apply",
timePickerCancel: "Cancel",
// Input field placeholders
min: "Min",
max: "Max",
// Sorting
sortByTime: "Sort by time",
sortByTimeNeeded: "Doses are not in chronological order. Click to sort.",