Improve number fields/labels in the UI to filter out floating point noise and truncate at correct precision (#4363)

* Improve the displayed precision of float number labels

* Show actual tiny values in high-precision number fields
This commit is contained in:
Keavon Chambers
2026-07-23 00:22:13 -07:00
committed by Dennis Kobert
parent 31239f77c6
commit f4609e0e3b
7 changed files with 153 additions and 20 deletions

View File

@@ -3,6 +3,7 @@
import { preventEscapeClosingParentFloatingMenu } from "/src/components/layout/FloatingMenu.svelte";
import FieldInput from "/src/components/widgets/inputs/FieldInput.svelte";
import { PRESS_REPEAT_DELAY_MS, PRESS_REPEAT_INTERVAL_MS } from "/src/managers/input";
import { roundAwayFloatNoise } from "/src/utility-functions/numbers";
import { browserVersion } from "/src/utility-functions/platform";
import type { ActionShortcut, EditorWrapper, NumberInputIncrementBehavior, NumberInputMode } from "/wrapper/pkg/graphite_wasm_wrapper";
@@ -213,9 +214,19 @@
function displayText(displayValue: number | undefined, unit: string): string {
if (displayValue === undefined) return "-";
const roundingPower = 10 ** Math.max(displayDecimalPlaces, 0);
const decimalPlaces = Math.max(displayDecimalPlaces, 0);
const roundingPower = 10 ** decimalPlaces;
// Values within floating point noise of zero (including -0) display as unsigned zero, unless the field's decimal precision is fine enough to display them
const effectiveValue = Math.abs(displayValue) < Math.min(1e-12, 0.5 / roundingPower) ? 0 : roundAwayFloatNoise(displayValue);
const unitlessDisplayValue = Math.round(effectiveValue * roundingPower) / roundingPower;
// Trailing zeros are trimmed only when the display is exact, so a truncated value keeps its decimal places (like "0.00" or "3.10") to indicate the truncation
if (unitlessDisplayValue !== effectiveValue) {
const sign = unitlessDisplayValue === 0 && effectiveValue < 0 ? "-" : "";
return `${sign}${unitlessDisplayValue.toFixed(decimalPlaces)}${unPluralize(unit, displayValue)}`;
}
const unitlessDisplayValue = Math.round(displayValue * roundingPower) / roundingPower;
return `${unitlessDisplayValue}${unPluralize(unit, displayValue)}`;
}
@@ -230,9 +241,8 @@
// ===========================
function onTextFocused() {
// The degree of precision allowed in the number that's shown when editing the number field, where additional precision is removed to round out floating point errors.
const MAX_PRECISION = 12;
const noFloatingImprecisionValue = value === undefined ? undefined : Number(value.toPrecision(MAX_PRECISION));
// The number shown when editing the field, with floating point imprecision noise removed
const noFloatingImprecisionValue = value === undefined ? undefined : roundAwayFloatNoise(value);
if (value === undefined) text = "";
else if (unitIsHiddenWhenEditing) text = `${noFloatingImprecisionValue}`;