The Zero-Float Invariant & Numeric Precision
In computational software, numeric inaccuracies erode trust. Standard binary floating-point types (Double, Float) represent numbers in base-2, making it impossible to represent simple decimal fractions like $0.1$ or $0.05$ exactly without rounding errors.
Kalc is engineered around a foundational invariant: The Zero-Float Invariant.
Why Standard Calculators Fail
Consider this elementary calculation:
0.1 + 0.2In standard programming languages, web engines, and calculator apps backed by IEEE 754 binary 64-bit floating point, this yields:
0.30000000000000004When building an enterprise invoice, budgeting payroll, or compounding loan interest over 30 years, these infinitesimal errors accumulate. Subtotals drift, invoices misalign with bank transactions, and equality checks fail.
The Zero-Float Invariant
In the KalcCore mathematical engine:
Native binary floating-point types (
Double,Float) are strictly prohibited across all core evaluation, currency exchange, dimensional conversions, and state persistence routines.
Binary Double values are strictly isolated to:
- Native AppKit / TextKit 2 screen coordinates (
NSRect,NSPoint). - Bridging transcendental function approximations (
sin,cos,log,atan) inMathFunctions.swiftbefore converting results immediately back to exact decimals.
KalcDecimal Engine Architecture
All calculations run through KalcDecimal, a high-precision decimal representation wrapping Foundation.Decimal:
- Significand Precision: A minimum of 38 decimal digits of exact significand precision.
- Base-10 Arithmetic: Performs addition, subtraction, and multiplication directly in base-10 decimal space.
- Lossless Serialization: Numbers serialize directly to decimal string representations in
.kalcplain-text files and the JSON daemon API, ensuring that saving and reopening a document never introduces drift.
Half-Even Banker's Rounding
When rounding is required (such as computing taxes, exchange rates, or formatting currency outputs), Kalc enforces IEEE 754-2008 Half-Even Banker's Rounding (NSRoundingMode.bankers / roundTiesToEven).
Why Banker's Rounding?
Standard "round half up" methods always round .5 upward, creating an upward statistical bias that artificially inflates totals over large financial datasets.
Banker's Rounding breaks ties by rounding to the nearest even number:
2.5rounds to23.5rounds to44.5rounds to45.5rounds to6
Over hundreds or thousands of invoice items, this evenly balances round-up and round-down occurrences, preserving statistical equilibrium and matching official banking standards.
Output Formatting & Radix Representation
Kalc dynamically applies intelligent formatting based on the semantic type of the result:
| Result Type | Rules | Example |
|---|---|---|
| Currencies | 2 decimal places by default, formatted with thousand separators. | $1,450.00, 120.50 EUR |
| Dimensional Quantities | Up to 6 decimal places, omitting trailing zeros for whole numbers. | 1.2 m, 50.8 cm, 14 kg |
| Integers | Exact integer representation with zero fractional clutter. | 42, 1,000,000 |
| Scientific Notation | Automatically formatted when magnitude $\ge 10^{12}$ or $\le 10^{-6}$. | 6.02214 × 10^23 |
| Radix Notation | Native input and output in Hexadecimal (0x), Binary (0b), and Octal (0o). | 0xFF in bin $\to$ 0b11111111 |
Empty Block Semantics
When evaluating block aggregates (sum, avg, subtotal):
sumon an empty block: Yields dimensionless0(notNaN,nil, or an error).avgon an empty block: Because division by zero is undefined, Kalc emits a clean diagnostic:"Empty block: no values to average".- Incompatible units in block: If a block mixes incompatible dimensions (e.g.
10 kgand5 meters), Kalc emits:"Incompatible units in block aggregate".