Decode in one step
You will learn
Why a fixed-field format decodes its fields in parallel and a posit cannot, as the spec counts the steps.
A posit packs a regime of variable length before its exponent, so a decoder must find where the regime ends before it can read anything else. GF16 and IEEE FP16 keep every field at a fixed position, so all fields decode at once. gf_competitive.t27 counts the steps: 3 for FP16, 6 for POSIT16, 3 for GF16, and marks which can run in parallel. These are counts written into the spec, not a timing measured on hardware.
Try it
Find decode_complexity and the three entries it returns. Then find the invariant that compares the posit with GF16, and say what a timing on hardware would add.

Decode steps as gf_competitive.t27 counts them, read from gf_competitive.t27. Lesson 27 of the GoldenFloat course.
specs/math/gf_competitive.t27
// SPDX-License-Identifier: Apache-2.0
// t27/specs/math/gf_competitive.t27
// GoldenFloat Competitive Analysis — GF vs Posit vs IEEE 754
// MATH-COMPETITIVE-001 — Decode latency, parallelism, hardware efficiency
//
// Ring 051: Competitive analysis showing GF's structural advantages
// Main result: GF has O(1) parallel decode vs Posit's O(N) sequential
module GFCompetitive {
use math::constants;
use math::sacred_physics;
// ═══════════════════════════════════════════════════════════════════════════
// 1. Decode Complexity Analysis
// ═════════════════════════════════════════════════════════════════════════════════════════
// Decode operation counts (worst case)
struct DecodeComplexity {
format : string,
steps_sequential : u8,
steps_parallel : u8,
can_parallelize : bool,
}
// Worst-case decode steps for each format
fn decode_complexity() -> [3]DecodeComplexity {
return [
DecodeComplexity{
format = "IEEE_754_FP16",
steps_sequential = 3, // sign, exp, mantissa (fixed position)
steps_parallel = 3, // all fields decodeable in parallel
can_parallelize = true,
},
DecodeComplexity{
format = "POSIT16",
steps_sequential = 6, // regime (variable) + sign + exp + mantissa
steps_parallel = 6,
can_parallelize = false, // regime detection is sequential
},
DecodeComplexity{
format = "GF16",
steps_sequential = 3, // sign (trit), exp (fixed), mantissa (fixed)
steps_parallel = 3,
can_parallelize = true, // all fields decodeable in parallel
},
];
}
// ═══════════════════════════════════════════════════════════════════════════
// Tests
// ═════════════════════════════════════════════════════════════════════════════════════════
test "decode_complexity_returns_3_formats" {
let complexity = decode_complexity();
assert(complexity.len() == 3);
}
test "gf16_can_parallelize" {
let complexity = decode_complexity();
assert(complexity[2].can_parallelize);
}
test "posit_cannot_parallelize" {
let complexity = decode_complexity();
assert(!complexity[1].can_parallelize);
}
test "ieee754_fp16_can_parallelize" {
let complexity = decode_complexity();
assert(complexity[0].can_parallelize);
}
test "gf16_has_minimal_sequential_steps" {
let complexity = decode_complexity();
assert(complexity[2].steps_sequential == 3);
}
test "posit_has_more_sequential_steps" {
let complexity = decode_complexity();
assert(complexity[1].steps_sequential > complexity[2].steps_sequential);
}
// ═══════════════════════════════════════════════════════════════════════════
// Invariants
// ═════════════════════════════════════════════════════════════════════════════════════════
invariant "decode_complexity_always_returns_3_entries" {
let complexity = decode_complexity();
assert(complexity.len() == 3);
}
invariant "gf16_can_parallelize_is_true" {
let complexity = decode_complexity();
assert(complexity[2].can_parallelize);
}
invariant "posit_has_more_sequential_steps_than_gf16" {
let complexity = decode_complexity();
assert(complexity[1].steps_sequential >= complexity[2].steps_sequential);
}
invariant "all_formats_have_positive_steps" {
let complexity = decode_complexity();
for c in complexity {
assert(c.steps_sequential > 0);
assert(c.steps_parallel > 0);
}
}
// ═══════════════════════════════════════════════════════════════════════════
// Benchmarks
// ═════════════════════════════════════════════════════════════════════════════════════════
bench "decode_complexity" {
let iterations = 10000;
for _ in 0..iterations {
let _ = decode_complexity();
}
}
}
All lessons
Module 1 · The rule and its numbers
One rule splits every width, the ratio it aims at, and the Lucas numbers behind the 3.
Module 2 · Why phi, why three
Why the split is phi, why base three, and how a spec checks GF16 keeps phi.
Module 3 · The small rungs: GF4 to GF8
GF4, GF6 and GF8, the fewest bits, where rounding to whole bits costs the most.
Module 4 · Ten to fourteen bits
GF10, GF12 and GF14, and how the distance from 1 / phi moves as the word grows.
Module 5 · GF16 at work
The primary 16-bit format, a two-term dot product in GF-T16, then GF20 and GF24.
Module 6 · GF32 to GF64
GF32 beside IEEE single, GF48 with no IEEE twin, GF64 beside IEEE double.
Module 7 · GF96 to GF256
GF96, GF128 and GF256, where the specs hold the layout with invariants.
Module 8 · The widest rungs, then trits
GF512 and GF1024, the two widest rungs, then GF-T8, where the exponent moves to trits.
Module 9 · More trits, then the decode
GF-T16 and GF-T32, then why fixed fields decode in parallel and a posit does not.