Число с плавающей точкой, разрезанное по phi
Вы узнаете
Как одно правило, E = round((N - 1) / phi^2), делит каждую ширину GoldenFloat на знак, порядок и мантиссу.
Число с плавающей точкой тратит биты на три поля: один бит знака, порядок для диапазона и мантиссу для точности. IEEE 754 выбирает это деление комитетом для каждой ширины. GoldenFloat использует одно правило для всех: из N - 1 битов после знака round((N - 1) / phi^2) уходят в порядок, остальные в мантиссу, так что отношение E / M держится около 1 / phi, примерно 0.618. Спека семейства перечисляет 17 ширин от GF4 до GF1024, и GF16 она отмечает основным.
Попробуйте
Запустите тесты goldenfloat_family.t27 и найдите тот, что считает семейство. Затем найдите, какой формат спека отмечает основным, и тест, который говорит, что он один.

Five of the 17 GoldenFloat widths, read from goldenfloat_family.t27. Lesson 1 of the GoldenFloat course.
specs/numeric/goldenfloat_family.t27
// SPDX-License-Identifier: Apache-2.0
// t27/specs/numeric/goldenfloat_family.t27
// GoldenFloat Family -- phi-structured floating point formats
// NUMERIC-STANDARD-001 -- Agent 1 (P0)
module GoldenFloatFamily {
// Import constants for phi-structured design
use math::constants;
use math::sacred_physics;
// ----------------------------------------------------------------
// 1. GoldenFloatFormat -- canonical format descriptor
// ----------------------------------------------------------------
struct GoldenFloatFormat {
name : string, // "GF4", "GF8", ..., "GF256"
bits : u8, // Total bits: 4, 8, 12, 16, 20, 24, 32, 64, 256
sign_bits : u8, // Always 1
exp_bits : u8, // Exponent bits = round((bits-1)/phi^2)
mant_bits : u8, // Mantissa bits = bits - 1 - exp_bits
exp_mant_ratio : f64, // exp / mantissa ratio
phi_distance : f64, // |exp/mant - 1/phi| (lower = closer to 1/phi)
is_primary : bool, // true only for GF16
}
// ----------------------------------------------------------------
// 2. GOLDEN_FLOAT_FAMILY -- the canonical format registry
// ----------------------------------------------------------------
// phi-ratio target: 1/phi ~ 0.618.
// ONE closed rule (normative, FORMAT-SPEC-001 v1.2):
// e = round((N - 1) / phi^2)
// m = N - 1 - e
// bias = 2^(e - 1) - 1
// exp_max = 2^e - 1
// derives the exp:mant split for every rung of the 4-to-1024-bit
// ladder. GFTernary (2-bit code) is the special-case base of the
// ladder and lives outside this struct (no E/M split). TF3 (1+3+4)
// is a ternary-weight CONTAINER, not a binary rung, and also lives
// separately. This array holds the 17 binary-ladder rungs only.
//
// Status (v1.2):
// - Verified arithmetic (rule produces exact widths): 17/17.
// - Frozen tape-out anchor: GF16 = 1+6+9, bias = 31
// (tt-trinity-gamma/src/gf16_v2_mul.v).
// - Whether the ladder is BETTER than an equally-tuned non-phi
// family (posit / OCP-MX / takum / LNS) stays [Open conjecture].
// - Per-format PHI_BIAS empirical values are OPEN (do not invent
// via Fibonacci/Lucas coincidence for new rungs).
const PHI_RATIO_TARGET : f64 = sacred_physics::PHI_INV;
// Format array: ordered by bits (4 .. 1024), one rule across the ladder.
const GOLDEN_FLOAT_FAMILY : [17]GoldenFloatFormat = [
// name, bits, S, E, M, ratio, phi_dist, primary
GoldenFloatFormat{
name = "GF4",
bits = 4,
sign_bits = 1,
exp_bits = 1,
mant_bits = 2,
exp_mant_ratio = 0.5,
phi_distance = abs(0.5 - PHI_RATIO_TARGET),
is_primary = false,
},
GoldenFloatFormat{
name = "GF6",
bits = 6,
sign_bits = 1,
exp_bits = 2,
mant_bits = 3,
exp_mant_ratio = 0.6666666666666667,
phi_distance = abs(0.6666666666666667 - PHI_RATIO_TARGET),
is_primary = false,
},
GoldenFloatFormat{
name = "GF8",
bits = 8,
sign_bits = 1,
exp_bits = 3,
mant_bits = 4,
exp_mant_ratio = 0.75,
phi_distance = abs(0.75 - PHI_RATIO_TARGET),
is_primary = false,
},
GoldenFloatFormat{
name = "GF10",
bits = 10,
sign_bits = 1,
exp_bits = 3,
mant_bits = 6,
exp_mant_ratio = 0.5,
phi_distance = abs(0.5 - PHI_RATIO_TARGET),
is_primary = false,
},
GoldenFloatFormat{
name = "GF12",
bits = 12,
sign_bits = 1,
exp_bits = 4,
mant_bits = 7,
exp_mant_ratio = 0.5714285714285714,
phi_distance = abs(0.5714285714285714 - PHI_RATIO_TARGET),
is_primary = false,
},
GoldenFloatFormat{
name = "GF14",
bits = 14,
sign_bits = 1,
exp_bits = 5,
mant_bits = 8,
exp_mant_ratio = 0.625,
phi_distance = abs(0.625 - PHI_RATIO_TARGET),
is_primary = false,
},
GoldenFloatFormat{
name = "GF16",
bits = 16,
sign_bits = 1,
exp_bits = 6,
mant_bits = 9,
exp_mant_ratio = 0.6666666666666667,
phi_distance = abs(0.6666666666666667 - PHI_RATIO_TARGET),
is_primary = true, // PRIMARY FORMAT
},
GoldenFloatFormat{
name = "GF20",
bits = 20,
sign_bits = 1,
exp_bits = 7,
mant_bits = 12,
exp_mant_ratio = 0.5833333333333333,
phi_distance = abs(0.5833333333333333 - PHI_RATIO_TARGET),
is_primary = false,
},
GoldenFloatFormat{
name = "GF24",
bits = 24,
sign_bits = 1,
exp_bits = 9,
mant_bits = 14,
exp_mant_ratio = 0.6428571428571429,
phi_distance = abs(0.6428571428571429 - PHI_RATIO_TARGET),
is_primary = false,
},
GoldenFloatFormat{
name = "GF32",
bits = 32,
sign_bits = 1,
exp_bits = 12,
mant_bits = 19,
exp_mant_ratio = 0.631578947368421,
phi_distance = abs(0.631578947368421 - PHI_RATIO_TARGET),
is_primary = false,
},
GoldenFloatFormat{
name = "GF48",
bits = 48,
sign_bits = 1,
exp_bits = 18,
mant_bits = 29,
exp_mant_ratio = 0.6206896551724138,
phi_distance = abs(0.6206896551724138 - PHI_RATIO_TARGET),
is_primary = false,
},
GoldenFloatFormat{
name = "GF64",
bits = 64,
sign_bits = 1,
exp_bits = 24,
mant_bits = 39,
exp_mant_ratio = 0.6153846153846154,
phi_distance = abs(0.6153846153846154 - PHI_RATIO_TARGET),
is_primary = false,
},
GoldenFloatFormat{
name = "GF96",
bits = 96,
sign_bits = 1,
exp_bits = 36,
mant_bits = 59,
exp_mant_ratio = 0.6101694915254238,
phi_distance = abs(0.6101694915254238 - PHI_RATIO_TARGET),
is_primary = false,
},
GoldenFloatFormat{
name = "GF128",
bits = 128,
sign_bits = 1,
exp_bits = 49,
mant_bits = 78,
exp_mant_ratio = 0.6282051282051282,
phi_distance = abs(0.6282051282051282 - PHI_RATIO_TARGET),
is_primary = false,
},
GoldenFloatFormat{
name = "GF256",
bits = 256,
sign_bits = 1,
exp_bits = 97,
mant_bits = 158,
exp_mant_ratio = 0.6139240506329114,
phi_distance = abs(0.6139240506329114 - PHI_RATIO_TARGET),
is_primary = false,
},
GoldenFloatFormat{
name = "GF512",
bits = 512,
sign_bits = 1,
exp_bits = 195,
mant_bits = 316,
exp_mant_ratio = 0.6170886075949367,
phi_distance = abs(0.6170886075949367 - PHI_RATIO_TARGET),
is_primary = false,
},
GoldenFloatFormat{
name = "GF1024",
bits = 1024,
sign_bits = 1,
exp_bits = 391,
mant_bits = 632,
exp_mant_ratio = 0.6186708860759494,
phi_distance = abs(0.6186708860759494 - PHI_RATIO_TARGET),
is_primary = false,
},
];
// ----------------------------------------------------------------
// 3. Query functions
// ----------------------------------------------------------------
// (Loops below were `for (const XS) |x|`; the `const` qualifier inside
// the iterable parentheses is not t27 and is dropped -- same iteration.
// Rust `Option<T>` return types are written as the optional `?T`.)
fn get_format_by_name(name: string) -> ?GoldenFloatFormat {
for (GOLDEN_FLOAT_FAMILY) |fmt| {
if (fmt.name == name) {
return fmt;
}
}
return null;
}
fn get_format_by_bits(bits: u8) -> ?GoldenFloatFormat {
for (GOLDEN_FLOAT_FAMILY) |fmt| {
if (fmt.bits == bits) {
return fmt;
}
}
return null;
}
fn get_primary_format() -> GoldenFloatFormat {
return GOLDEN_FLOAT_FAMILY[6]; // GF16 at index 6 (after GF4, GF6, GF8, GF10, GF12, GF14)
}
// ----------------------------------------------------------------
// 4. Verification functions
// ----------------------------------------------------------------
struct VerificationReport {
all_valid : bool,
primary_is_gf16 : bool,
phi_distances_ok : bool,
best_phi_format : string,
best_phi_distance : f64,
avg_phi_distance : f64,
}
fn verify_golden_family() -> VerificationReport {
var primary_count : u8 = 0;
var best_dist : f64 = 1.0;
var best_name : string = "";
var total_dist : f64 = 0.0;
var format_count : u8 = 0;
var all_names_unique : bool = true;
var all_bit_sums_valid : bool = true;
var all_phi_distances_non_negative : bool = true;
// Check for duplicate names
var names_seen : [17]string = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""];
for (GOLDEN_FLOAT_FAMILY) |fmt| {
format_count = format_count + 1;
// Count primary formats (should be exactly 1)
if (fmt.is_primary) {
primary_count = primary_count + 1;
}
// Track best phi distance
if (fmt.phi_distance < best_dist) {
best_dist = fmt.phi_distance;
best_name = fmt.name;
}
total_dist = total_dist + fmt.phi_distance;
// Check for duplicate names
for (names_seen) |name| {
if (name != "" && name == fmt.name) {
all_names_unique = false;
}
}
names_seen[format_count - 1] = fmt.name;
// Check that exp_bits + mant_bits + 1 = bits (sign bit)
if (fmt.exp_bits + fmt.mant_bits + 1 != fmt.bits) {
all_bit_sums_valid = false;
}
// Check phi_distance is non-negative
if (fmt.phi_distance < 0.0) {
all_phi_distances_non_negative = false;
}
}
const avg_dist = total_dist / 17.0;
// All checks must pass
const all_checks_valid =
format_count == 17 &&
all_names_unique &&
all_bit_sums_valid &&
all_phi_distances_non_negative &&
primary_count == 1;
return VerificationReport{
all_valid = all_checks_valid,
primary_is_gf16 = (primary_count == 1) && (GOLDEN_FLOAT_FAMILY[6].is_primary),
phi_distances_ok = best_dist < 0.1, // All within 0.1 of 1/phi
best_phi_format = best_name,
best_phi_distance = best_dist,
avg_phi_distance = avg_dist,
};
}
// ----------------------------------------------------------------
// 5. Utility functions
// ----------------------------------------------------------------
fn max_value(format: GoldenFloatFormat) -> f64 {
// Max value = (2 - 2^(-M)) * 2^(2^E - 1)
const mant_max = 2.0 - pow(2.0, -(format.mant_bits as f64));
const exp_max = pow(2.0, format.exp_bits as f64) - 1.0;
return mant_max * pow(2.0, exp_max);
}
fn min_positive(format: GoldenFloatFormat) -> f64 {
// Min positive = 2^(-M) * 2^(1 - bias)
const mant_min = pow(2.0, -(format.mant_bits as f64));
const bias = pow(2.0, format.exp_bits as f64 - 1.0) - 1.0;
return mant_min * pow(2.0, 1.0 - bias);
}
fn memory_efficiency(format: GoldenFloatFormat) -> f64 {
// Memory efficiency vs FP32 (1.0 = same, 0.5 = half size)
return format.bits as f64 / 32.0;
}
// ----------------------------------------------------------------
// TDD-Inside-Spec: Tests and Invariants for GoldenFloatFamily
// ----------------------------------------------------------------
test gffamily_get_format_by_name_gf16
given fmt = get_format_by_name("GF16")
then fmt != null and fmt.?.name == "GF16" and fmt.?.bits == 16
test gffamily_get_format_by_bits_8
given fmt = get_format_by_bits(8)
then fmt != null and fmt.?.name == "GF8" and fmt.?.bits == 8
test gffamily_get_primary_format_is_gf16
given primary = get_primary_format()
then primary.name == "GF16" and primary.is_primary == true
test gffamily_family_size_17
given size = GOLDEN_FLOAT_FAMILY.len()
then size == 17
test gffamily_phi_ratio_target_is_phi_inverse
given target = PHI_RATIO_TARGET
and phi_inv = sacred_physics::PHI_INV
then abs(target - phi_inv) < 0.000001
test gffamily_gf4_has_correct_bit_counts
given fmt = get_format_by_name("GF4").?
then fmt.sign_bits == 1 and fmt.exp_bits == 1 and fmt.mant_bits == 2
test gffamily_gf32_has_correct_bit_counts
given fmt = get_format_by_name("GF32").?
then fmt.sign_bits == 1 and fmt.exp_bits == 12 and fmt.mant_bits == 19
test gffamily_gf64_has_correct_bit_counts
given fmt = get_format_by_name("GF64").?
then fmt.sign_bits == 1 and fmt.exp_bits == 24 and fmt.mant_bits == 39
test gffamily_gf256_has_correct_bit_counts
given fmt = get_format_by_name("GF256").?
then fmt.sign_bits == 1 and fmt.exp_bits == 97 and fmt.mant_bits == 158
test gffamily_only_gf16_is_primary
var count = 0
for (GOLDEN_FLOAT_FAMILY) |fmt| {
if (fmt.is_primary) { count = count + 1; }
}
then count == 1
test gffamily_verify_primary_is_gf16
given report = verify_golden_family()
then report.primary_is_gf16 == true
test gffamily_phi_distances_within_tolerance
given report = verify_golden_family()
then report.phi_distances_ok == true
test gffamily_best_phi_format_is_gf1024
// GF1024 has the smallest phi-distance (0.0006) of the ladder
// (GF64 was best in the 9-rung family pre-v1.2 at 0.003).
given report = verify_golden_family()
then report.best_phi_format == "GF1024"
test gffamily_memory_efficiency_gf8
given fmt = get_format_by_name("GF8").?
and eff = memory_efficiency(fmt)
then abs(eff - 0.25) < 0.01
test gffamily_memory_efficiency_gf16
given fmt = get_format_by_name("GF16").?
and eff = memory_efficiency(fmt)
then abs(eff - 0.5) < 0.01
test gffamily_max_value_positive
given fmt = get_format_by_name("GF8").?
and max_val = max_value(fmt)
then max_val > 0.0
test gffamily_min_positive_greater_than_zero
given fmt = get_format_by_name("GF8").?
and min_pos = min_positive(fmt)
then min_pos > 0.0
test gffamily_get_format_by_unknown_name
given fmt = get_format_by_name("GF999")
then fmt == null
test gffamily_get_format_by_unknown_bits
given fmt = get_format_by_bits(100)
then fmt == null
test gffamily_verify_all_valid
given report = verify_golden_family()
then report.all_valid == true
test gffamily_verify_format_count_is_9
given report = verify_golden_family()
then report.all_valid == true // implies format_count == 9
test gffamily_verify_names_unique
given report = verify_golden_family()
then report.all_valid == true // implies names are unique
test gffamily_verify_bit_sums_valid
given report = verify_golden_family()
then report.all_valid == true // implies bit sums are valid
test gffamily_verify_phi_distances_non_negative
given report = verify_golden_family()
then report.all_valid == true // implies phi_distances are non-negative
test gffamily_verify_exactly_one_primary
given report = verify_golden_family()
then report.all_valid == true // implies exactly 1 primary format
test gffamily_best_phi_distance_is_small
given report = verify_golden_family()
then report.best_phi_distance < 0.05
test gffamily_avg_phi_distance_reasonable
given report = verify_golden_family()
and avg = report.avg_phi_distance
then avg > 0.0 and avg < 0.2
invariant gffamily_phi_ratio_target_positive
assert PHI_RATIO_TARGET > 0.0
invariant gffamily_phi_ratio_target_less_than_one
assert PHI_RATIO_TARGET < 1.0
invariant gffamily_family_size_constant
assert GOLDEN_FLOAT_FAMILY.len() == 9
invariant gffamily_gf4_at_index_0
assert GOLDEN_FLOAT_FAMILY[0].name == "GF4"
invariant gffamily_gf256_at_index_8
assert GOLDEN_FLOAT_FAMILY[8].name == "GF256"
// (The three loop invariants below are in brace form: a `for` loop
// cannot open a keyword-style block, which the parser dropped.)
invariant gffamily_all_formats_have_sign_bits_1 {
for (GOLDEN_FLOAT_FAMILY) |fmt| {
assert fmt.sign_bits == 1;
}
}
invariant gffamily_all_formats_bits_sum_correct {
for (GOLDEN_FLOAT_FAMILY) |fmt| {
assert fmt.sign_bits + fmt.exp_bits + fmt.mant_bits == fmt.bits;
}
}
invariant gffamily_primary_is_gf16
assert GOLDEN_FLOAT_FAMILY[3].is_primary == true
invariant gffamily_phi_distances_non_negative {
for (GOLDEN_FLOAT_FAMILY) |fmt| {
assert fmt.phi_distance >= 0.0;
}
}
invariant gffamily_memory_efficiency_gf4
assert abs(memory_efficiency(GOLDEN_FLOAT_FAMILY[0]) - 0.125) < 0.01
invariant gffamily_memory_efficiency_gf64
assert abs(memory_efficiency(GOLDEN_FLOAT_FAMILY[7]) - 2.0) < 0.01
// (Benches were keyword-style `measure:` / `target:` lines, which no
// backend lowers; now brace form: both lines kept as comments and the
// measured call written as the bench statement.)
bench gffamily_get_format_by_name_latency {
// measure: nanoseconds to get_format_by_name("GF16")
// target: < 100ns
_ = get_format_by_name("GF16");
}
bench gffamily_get_format_by_bits_latency {
// measure: nanoseconds to get_format_by_bits(16)
// target: < 100ns
_ = get_format_by_bits(16);
}
bench gffamily_get_primary_format_latency {
// measure: nanoseconds to get_primary_format()
// target: < 50ns
_ = get_primary_format();
}
bench gffamily_verify_golden_family_latency {
// measure: nanoseconds to verify_golden_family()
// target: < 500ns
_ = verify_golden_family();
}
bench gffamily_memory_efficiency_latency {
// measure: nanoseconds to memory_efficiency(GOLDEN_FLOAT_FAMILY[3])
// target: < 100ns
_ = memory_efficiency(GOLDEN_FLOAT_FAMILY[3]);
}
}
Все уроки
Модуль 1 · Правило и его числа
Одно правило делит каждую ширину, отношение, к которому оно стремится, и числа Люка за тройкой 3.
Модуль 2 · Почему phi, почему три
Почему деление идёт по phi, почему основание три и как спека проверяет, что GF16 хранит phi.
Модуль 3 · Малые ступени: от GF4 до GF8
GF4, GF6 и GF8 — меньше всего битов, и округление до целых битов стоит здесь дороже всего.
Модуль 4 · От десяти до четырнадцати битов
GF10, GF12 и GF14 и то, как расстояние до 1 / phi меняется с ростом слова.
Модуль 5 · GF16 в работе
Основной 16-битный формат, скалярное произведение из двух слагаемых в GF-T16, затем GF20 и GF24.
Модуль 6 · От GF32 до GF64
GF32 рядом с IEEE single, GF48 без пары в IEEE, GF64 рядом с IEEE double.
Модуль 7 · От GF96 до GF256
GF96, GF128 и GF256, где спеки держат раскладку инвариантами.
Модуль 8 · Самые широкие ступени, затем триты
GF512 и GF1024, две самые широкие ступени, затем GF-T8, где порядок уходит в триты.
Модуль 9 · Ещё триты, затем декодирование
GF-T16 и GF-T32, затем почему фиксированные поля декодируются параллельно, а posit — нет.