Skip to content

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:

text
0.1 + 0.2

In standard programming languages, web engines, and calculator apps backed by IEEE 754 binary 64-bit floating point, this yields:

text
0.30000000000000004

When 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:

  1. Native AppKit / TextKit 2 screen coordinates (NSRect, NSPoint).
  2. Bridging transcendental function approximations (sin, cos, log, atan) in MathFunctions.swift before 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 .kalc plain-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.5 rounds to 2
  • 3.5 rounds to 4
  • 4.5 rounds to 4
  • 5.5 rounds to 6

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 TypeRulesExample
Currencies2 decimal places by default, formatted with thousand separators.$1,450.00, 120.50 EUR
Dimensional QuantitiesUp to 6 decimal places, omitting trailing zeros for whole numbers.1.2 m, 50.8 cm, 14 kg
IntegersExact integer representation with zero fractional clutter.42, 1,000,000
Scientific NotationAutomatically formatted when magnitude $\ge 10^{12}$ or $\le 10^{-6}$.6.02214 × 10^23
Radix NotationNative 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):

  • sum on an empty block: Yields dimensionless 0 (not NaN, nil, or an error).
  • avg on 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 kg and 5 meters), Kalc emits: "Incompatible units in block aggregate".

Native macOS Computational Notepad • Pure Swift with Strict Concurrency