Unexpected maths aggregating with decimals #32
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This log:
Why does
sum(ol.count * p.price)show rounding errors? Should I expect that?Fixed in
3d4a0fd.Why it happens: SQLite has no native decimal/BCD type — its only storage classes are NULL/INTEGER/REAL/TEXT/BLOB (
NUMERICis an affinity, not a type). We storedecimalas exact TEXT, so raw decimal columns round-trip perfectly (100.10keeps its trailing zero). But SQLite's arithmetic operators and aggregates only work on INTEGER/REAL, sool.count * p.priceimplicitly coerces the TEXT to an IEEE-754 double, and the computed result carries no playground type — sosum(...)rendered the double's full noise (298.59999999999997for298.60). So: no, you shouldn't expect to see that — it's a display artifact, now trimmed.Fix: floating-point values are rounded to 15 significant figures for display (a double's reliable precision) and then shown in their shortest round-tripping form —
298.59999999999997→298.6,0.1 + 0.2→0.3. Wired intoformat_cell(result-set /show datacells) only, since that's the only surface where arithmetic noise surfaces.Deliberately left exact (the boundary is semantic, not cosmetic):
realsurvives save/load byte-for-byte.render_valueis a canonical identity key for the uniqueness dry-runs (dry_run_unique,check_uniqueness_collisions) — rounding it would report a UNIQUE collision the exact-valued engine would actually accept. (Caught in review;render_valuestays full-precision with a regression test.)Raw
decimalcolumns are untouched — TEXT, rendered verbatim including trailing zeros.Not pursued: exact decimal arithmetic (a SQLite extension exposing
decimal_mul/decimal_sum) would mean rewriting your standard-SQL operators into function calls, defeating both the "validated SQL runs verbatim" model and the goal of teaching ordinary SQL. Display-fix is the pragmatic answer.Decision recorded in ADR-0005 Amendment 1. +7 tests; full suite green (2424 pass, 1 ignored).