index

Introduction

Spirix is a high-performance floating-point numeric system that utilizes two's complement for all components with adjustable range and precision. Spirix is designed to preserve mathematical identities and provide consistent behavior across the entire number line.

With Spirix, you can choose both fraction and exponent sizes independently, allowing for precision and range exactly where you need it. The system provides mathematically rigorous functionality and overcoming many limitations found in traditional floating-point representations.

  • Mathematical identity preservation: Operations follow mathematical rules even beyond normality
    non-Zero values never multiply to Zero, and finite values never become Infinity
  • Customizable precision: Choose the exact fraction and exponent sizes you want
  • Detailed error tracking: Distinct undefined states preserve information about what caused the undefined, making debugging quicker and more intuitive
  • Native complex number support: First-class complex arithmetic with the Circle, providing operations for complex numbers
  • Continuous representation: Values that grow too large or too small maintain their sign or angle when they escape normality
  • Singular ∞ and 0: multiplicative identities are preserved: a × b = 0 if and only if a = 0 or b = 0

Key Features

Deterministic icon

Exploded and vanished

Get usable results with escaped states even when values exceed range

Error tracking icon

Error tracking

Undefined states preserve first cause,
making debugging faster and easier

Mathematical icon

[0] [↓] ← [#] → [↑] [∞]

Values maintain orientation information even when magnitude is lost,
preserving mathematical continuity

Complex icon

Complex number support

First-class complex number type with all basic math operators

Performance icon

High performance

2x+ faster than comparable numeric types with similar precision

Memory icon

Memory efficient

Use exactly the precision and range you want

Continuous Number Line

A fundamental difference between Spirix and traditional floating-point systems is how numbers are represented at their core.

IEEE-754 & Other Floating-Point Representations

The IEEE-754 standard and other floating-point types use a sign-exponent-magnitude representation with a distinct positive magnitude and a sign bit. This creates a fundamental discontinuity at Zero, where every value has both a positive and negative representation that differs only by the sign bit.

Zero itself exists as both +0 and -0, despite attempting to represent the same mathematical value. This duplication creates confusing behavior, such as comparisons, for example in IEEE-754 -0=+0 returns 'TRUE' even tho they're distinct. The sign-magnitude approach introduces significant complexity in numerical operations, requiring separate paths for sign combinations, tedious rules for sign crossings, rounding, denormals and other combinations.

IEEE-754 Mantissa Plot

Spirix Two's Complement Representation

In contrast, Spirix achieves a continuous linear number space by utilizing two's complement where values wrap around naturally, maintaining linear relationships and eliminating the discontinuity at Zero.

With this approach, Zero becomes a point in the middle of the number line rather than a special case requiring separate handling. This continuity enables operations to cross the Zero boundary smoothly, allowing all basic operations (addition, subtraction, multiplication, division) without any sign-specific testing or branching. Rounding is appliend to all values uniformly, regardless of sign.

To understand the difference, consider these two interpretations of the same bit patterns:

Scalar Unsigned Fraction Plot

The chart above shows the traditional unsigned interpretation of fraction bits, where values range from 0 at the bottom to MAX (all bits set to 1) at the top.

The chart below shows the same bit patterns but using a two's complement interpretation. Notice how the number line is essentially rotated vertically. The MSB (leftmost bit) now determines sign, with positive values (starting with 0 bit) in the upper half and negative values (starting with 1 bit) in the lower half. Zero and -1 are positioned naturally in the center of this continuous numeric space.

Scalar Signed Fraction Plot

Spirix Ordering

The Spirix Scalar comparisons arrange states and signs logically with positive exploded values being greatest, negative exploded values being least, and a continuous spectrum of states in between:

Spirix ordering

[-↑] < [-#] < [-↓] < [0] < [+↓] < [+#] < [+↑]
≠ [∞]
≠ [℘?]

The Spirix number line arranges values logically with a continuous spectrum of states:

This continuous representation enables several benefits:

Number Representation

Spirix represents numbers using bit patterns that encode both the value's magnitude and state. The fundamental value calculation is straightforward: the numeric value equals the two's complement fraction multiplied by 2 raised to the exponent power (fraction × 2^exponent). The normalization level (N-1 for normal values, N-2 for vanished, etc.) determines the decimal point position within the binary fraction. For example, the number 42 encoded in a F3E3 Scalar would contain F=01010100, E=00000110. The value would be calculated as 0.1010100₂ × 2^00000110.₂ = 101010. (0.65625×2^6.=42.)

Bit Patterns and Number Types

Each state in Spirix is identified by specific bit patterns in the fraction component:

0
0
0
0
0
0
0
0
Zero [0]
0
0
1
?
?
?
?
?
Positive vanished [+↓]
1
1
0
?
?
?
?
?
Negative vanished [-↓]
0
1
?
?
?
?
?
?
Positive normal [+#]
1
0
?
?
?
?
?
?
Negative normal [-#]
0
1
?
?
?
?
?
?
Positive exploded [+↑]
1
0
?
?
?
?
?
?
Negative exploded [-↑]
1
1
1
1
1
1
1
1
Infinity [∞]
1
1
1
?
?
?
?
?
  or  
0
0
0
?
?
?
?
?
Undefined [℘]

Note that normal and exploded states share the same fraction pattern, entirely eliminating overflow handling in addition and subtraction and from the ambiguous exponent placement.

Ambiguous Values and the AMBIGUOUS_EXPONENT

A key innovation in Spirix is the use of a single reserved exponent value to identify all non-normal states. An ambiguous state is indicated by the exponent having a one followed by all Zeros (E=1000000...). This unified approach allows for single detection of abnormal cases and provides improved mathematical consistency across operations.

When an exponent is ambiguous, the fraction pattern determines which non-normal state it's in:

Implementation Benefits

Using an ambiguous exponent to identify all abnormal cases provides significant advantages:

System Overview

Spirix is a complete numeric system that offers customizable precision and range while improving mathematical rigor. Its design addresses many limitations found in standard floating-point representations.

Key Features

Spirix provides these benefits while maintaining high performance, with operations running more than twice as fast as IEEE-754 equivalents due to the simplified design.

Mathematical Identity Preservation

Spirix preserves mathematical relationships that IEEE 754 often violates:

use spirix::{Scalar, ScalarF5E4};

// In IEEE 754, very small values can underflow to Zero
// In Spirix, they become vanished and maintain orientation
let not_zero = ScalarF5E4::MIN_POS * ScalarF5E4::MIN_POS;
let zero = f64::MIN_POS * f64::MIN_POS;
assert!(not_zero != 0);  // Spirix does not truncate to Zero
assert!(zero == 0);  // IEEE truncates to +0

// Division by Zero produces Infinity, not NaN or exception
let infinity = not_zero / 0;
assert!(infinity.is_infinite());

// Infinity behaves mathematically consistently
let still_infinity = infinity * 7;
assert!(still_infinity.is_infinite());

// And works with escaped values!
let also_infinity = infinity * not_zero;
assert!(also_infinity.is_infinite());

Real-World Benefits

Scientific Computing

More accurate representation of very small and very large numbers without losing sign or orientation information. Identity preservation enables more reliable numerical methods.

Graphics & Game Development

Predictable behavior with ambiguous values allows calculations to continue even when results exceed normal ranges, improving numerical stability in simulations and reducing edge cases.

Embedded Systems

Ability to choose independent fraction and exponent bit sizes which can reduce memory usage while maintaining mathematical rigor. Smaller hardware footprint leads to more efficient systems.

Machine Learning & AI

Preserving orientation information in exceptionally small and exceptionally large values helps maintain gradient stability in training algorithms.

Implementation Notes

Spirix achieves its advantages thru:

use spirix::{Scalar, Circle, ScalarF5E4, CircleF5E4};

fn main() {
    // Let's create a Scalar!
    let mut scalar = ScalarF5E4::from(42);
    println!("Original value: {}", scalar);
    // Internally creates and normalizes to N-1 level with a normal exponent

    // Continuous Mathematics
    // Create values that exceed normal representation
    let exploded = ScalarF5E4::MAX * 2;
    let vanished = ScalarF5E4::MIN_POS / -2;
    
    assert!(exploded.exploded());
    assert!(!exploded.is_infinite());
    assert!(vanished.vanished());
    assert!(!vanished.is_zero());
    
    // Operations work continuously even with escaped values
    let tiny = vanished / exploded;
    assert!(tiny != 0);
    assert!(tiny.is_negative());
    assert!(tiny.vanished());

    // Phase preservation
    let neg_tiny = -tiny;
    assert!(neg_tiny.is_positive());
    
    // Reciprocals maintain orientation
    let reciprocal = 1 / neg_tiny;
    assert!(reciprocal.exploded());
    assert!(reciprocal.is_positive());

    // Bitwise Operations on floating-point values
    let a = ScalarF5E4::from(42.5);
    let b = ScalarF5E4::from(6.25);
    
    // Aligns fractions before applying bitwise operations
    //  101010.10 (42.5)
    //  000110.01 (6.25)
    // &000010.00 (2)
    let bitwise_and = a & b;
    assert!(bitwise_and == 2);
    
    // Shifts work as power-of-two multipliers or divisors
    let shifted = a << 2;  // Multiply by 4
    assert!(shifted == 170);

    // Native complex arithmetic
    let z1 = CircleF5E4::from((1.5, 2));  // 1.5 + 2*i
    assert!(z1.magnitude() == 2.5);
    let z2 = CircleF5E4::from((1, -2)); // 1 - 2*i
    
    // Complex operations
    let product = z1 * z2;
    assert!(product == CircleF5E4::from((5.5, -1)));
    
    // Circles can be infinite too!
    let infinity = 8 / CircleF5E4::ZERO;
    assert!(infinity.is_infinite());
    assert!(infinity.is_transfinite()); // infinity is transfinite
    assert!(!infinity.exploded()); // But not exploded!
}

Scalar and Circle States

Spirix uses normalization levels and an ambiguous exponent to track the state of each representation which enables Spirix to:

[0]   Zero

The True Origin Point

Zero in Spirix has a distinct representation with a unique bit pattern at the N-0 level. Unlike vanished values that approach but never equal Zero, this is the genuine, mathematical Zero that serves as the additive identity.

0
0
0
0
0
0
0
0
[0] Zero
use spirix::{Scalar, ScalarF4E4};

// Zero is the additive identity
let zero = ScalarF4E4::ZERO;
let value = ScalarF4E4::from(42);
assert!(value + zero == value);

// Zero * anything = Zero
assert!(zero * value == zero);

// Except for Infinity times Zero, that's undefined
let infinity = value / 0;
let undefined = infinity * 0;
assert!(undefined.is_undefined());

// Zero over Zero creates a different undefined state
let different_undefined = 0 / zero;
assert!(different_undefined.is_undefined());

[↓]   Vanished

Values That Go Below Representable Range

Vanished values are numbers that have become so small their magnitude can no longer be stored but they are not Zero. Scalars retain their sign information and Circles maintain their orientation. Unlike actual Zero, vanished values have a non-Zero magnitude and Spirix records their phase/orientation as they approach Zero.

0
0
1
x
x
x
x
x
[+↓] Positive vanished
1
1
0
x
x
x
x
x
[-↓] Negative vanished

Properties of vanished values:

  • Preserve sign: Maintains positive/negative direction even as magnitude approaches Zero
  • Relative operations treat vanished as Zero: Adding a normal number to a vanished value will return the normal number
  • Distinct from Zero: Zero is a single point with no orientation
use spirix::{Scalar, ScalarF5E3};

// Creating vanished values
let vanished_positive = ScalarF5E3::MIN_POS / 42;
assert!(vanished_positive.vanished());
assert!(vanished_positive.is_positive());
assert!(vanished_positive != 0);

let vanished_negative = ScalarF5E3::MIN_POS * ScalarF5E3::MAX_NEG;
assert!(vanished_negative.vanished());
assert!(vanished_negative.is_negative());

// Addition treats vanished as Zero
let pizza = ScalarF5E3::from(3.14);
assert!(pizza + vanished_positive == pizza);

// Division by vanished produces exploded
let exploded = 2.5 / vanished_positive;
assert!(exploded.exploded());
assert!(exploded.is_positive());

// Multiplying two vanished values maintains vanished state
let product = vanished_positive * vanished_negative;
assert!(product.vanished());
assert!(product.is_negative()); // Sign follows multiplication rules

[#]   Normal

Standard Finite Numbers

Normal values have a definite magnitude and participate fully in all arithmetic operations. These form the core representable range of Spirix, where arithmetic operations behave conventionally.

0
1
x
x
x
x
x
x
[+#] Positive normal
1
0
x
x
x
x
x
x
[-#] Negative normal

All normal values have:

  • A non-escaped exponent
  • A normalized fraction with exactly one leading same bit
  • Full participation in all arithmetic operations
use spirix::{Scalar, ScalarF5E3};
      
// Create normal values
let positive = ScalarF5E3::from(42);
let negative = ScalarF5E3::from(-3.14);

// Normal values participate in all operations as expected
let sum = positive + negative;
let product = positive * negative;
let quotient = positive / negative;

[↑]   Exploded

Values That Exceed Representable Range

Exploded values are numbers that have grown so large their magnitude can no longer be recorded but their magnitude is not infinite. Scalars maintain their sign and Circles maintain their orientation. They occur when magnitudes exceed the range determined by the exponent size.

0
1
x
x
x
x
x
x
[+↑] Positive exploded
1
0
x
x
x
x
x
x
[-↑] Negative exploded

Properties of exploded values:

  • Phase/orientation: Scalars maintain positive/negative directions and Circles maintain their complex escape angle
  • Absolute operations are permitted: Can participate in absolute operations like multiplication and division
  • Relative operations with exploded values produce undefined states: When performing relative operations like addition ond subtraction with exploded values, they return undefined
  • Nomal times exploded stays exploded: Multiplying a normal number by an exploded value will return an exploded value
  • Same bit pattern as normal values: Identified by having an ambiguous exponent
use spirix::{Scalar, ScalarF4E3};
      
// Creating exploded values
let exploded = ScalarF4E3::MAX * 2;
assert!(exploded.exploded());
assert!(exploded.is_positive());
assert!(!exploded.is_infinite());

let exploded_negative = -exploded;
assert!(exploded_negative.exploded());
assert!(exploded_negative.is_negative());

// Multiplication works with exploded values
let still_exploded = exploded * 3;
assert!(still_exploded.exploded());

// Division works with exploded values too!
let neg_exploded = still_exploded / -25;
assert!(neg_exploded.is_negative());
assert!(neg_exploded.exploded());

// Addition with normal produces undefined
let undefined = exploded + 42;
assert!(undefined.is_undefined());

[∞]   Infinity

A Mathematical Singularity (just ask Riemann)

Infinity in Spirix represents a singular state with a truly unbounded magnitude, not computational overflow. Unlike IEEE-754's signed infinities, Infinity is the result of genuine mathematical discontinuities like division by Zero. While exploded values indicate numbers too large to represent normally, Infinity represents a distinctly different concept.

1
1
1
1
1
1
1
1
[∞] Infinity

Properties of Infinity:

  • Genuine discontinuity: Appears only in cases of true mathematical discontinuities (like 1/0), not from overflow
  • Singular representation: Unlike IEEE-754's signed infinities, Spirix uses a single Infinity
  • Consistent behavior: Any non-Zero value multiplied by Infinity produces Infinity
  • Distinct from exploded: Exploded values maintain phase information and can participate in more operations than Infinity
use spirix::{Scalar, ScalarF5E7};

// Let's create an Infinity!
let infinity = 1 / ScalarF5E7::ZERO;
assert!(infinity.is_infinite());
assert!(!infinity.exploded()); // Infinity is not exploded
assert!(infinity.is_transfinite()); // But it is transfinite!

// Operations with Infinity
let still_infinity = infinity * 42;
assert!(still_infinity.is_infinite());

// Zero times Infinity is undefined, not Zero
let undefined = 0 * infinity;
assert!(undefined.is_undefined());

// Adding to Infinity produces undefined
let also_undefined = infinity + 1;
assert!(also_undefined.is_undefined());

// Even exploded values crumble to the weight of Infinity!
let massive = ScalarF5E7::MAX.pow(ScalarF5E7::MAX);
let zero = massive / infinity;
assert!(zero == 0);

...[℘ ⬆%], [℘ ⬆‰], [℘ %↓], [℘ ‰↓], [℘ %↑], [℘ ‰↑],
[℘ &], [℘ |], [℘ ⊻], [℘ !], [℘ ⬇×⬆], [℘ ⬆×⬇],
[℘ ⬆^], [℘ ⬇^], [℘ ^⬆], [℘ ^⬇], [℘ -^]...   Various Undefined States

Undefined states in Spirix have:

Error Propagation

Spirix returns unique undefined states that preserve information about what caused the undefined. This allows for faster debugging and tracing the root cause in calculations.

Unlike IEEE 754 where different NaN values are indistinguishable, Spirix provides a comprehensive catalog of undefined states that identify the specific mathematical operation that first produced the undefined:

Undefined Type Symbol Description
General Undefined [℘] General undefined or unimplemented
(IEEE-754 NaN maps to this)
Transfinite Plus Transfinite [℘ ⬆+⬆] Transfinite value addition with transfinite value
Transfinite Minus Transfinite [℘ ⬆-⬆] Transfinite value subtraction with transfinite value
Vanished Plus Vanished [℘ ↓+↓] Vanished value addition with vanished value
Vanished Minus Vanished [℘ ↓-↓] Vanished value subtraction with vanished value
Transfinite Plus Finite [℘ ⬆+] Transfinite value addition with finite value
Transfinite Minus Finite [℘ ⬆-] Transfinite value subtraction with finite value
Finite Plus Transfinite [℘ +⬆] Finite value addition with transfinite value
Finite Minus Transfinite [℘ -⬆] Finite value subtraction with transfinite value
Fractional Infinity [℘ ⨅∞] Fractional part of Infinity
Sign Indeterminate [℘ ±∅] Sign/direction of Zero or Infinity is indeterminate
Indeterminate [℘⊥⊙] Indeterminate Scalar → Circle conversion
Clamp Unordered [℘ ∩] Clamp with non-ordered ambiguous values
Max Unordered [℘ ⌈] Maximum of non-ordered ambiguous values
Min Unordered [℘ ⌊] Minimum of non-ordered ambiguous values
Transfinite Divide Transfinite [℘ ⬆/⬆] Transfinite value division by transfinite value
Negligible Divide Negligible [℘ ⬇/⬇] Negligible value division by negligible value
Transfinite Modulus [℘ ⬆%] Transfinite value modulus operation
Transfinite Modulo [℘ ⬆‰] Transfinite value modulo operation
Modulus Vanished [℘ %↓] Finite value modulus with vanished value
Modulo Vanished [℘ ‰↓] Finite value modulo with vanished value
Modulus Exploded [℘ %↑] Modulus with opposing sign exploded denominator
Modulo Exploded [℘ ‰↑] Modulo with opposing sign exploded denominator
Logical AND [℘ &] Logical AND with escaped value
Logical OR [℘ |] Logical OR with escaped value
Logical XOR [℘ ⊻] Logical XOR with escaped value
Logical NOT [℘ !] Logical NOT of escaped value
Negligible Multiply Transfinite [℘ ⬇×⬆] Negligible value multiplication with transfinite value
Transfinite Multiply Negligible [℘ ⬆×⬇] Transfinite value multiplication with negligible value
Transfinite Power [℘ ⬆^] Transfinite value raised to power
Negligible Power [℘ ⬇^] Vanished value raised to power
Power Transfinite [℘ ^⬆] Value raised to transfinite power
Power Negligible [℘ ^⬇] Value raised to vanished power
Negative Power [℘ -^] Negative value raised to irrational power
Log One [℘ @1] Logarithm base One
Square Root Negative [℘ √-] Square root of negative value
Square Root Exploded [℘ √↑] Square root of transfinite value
Square Root Vanished [℘ √↓] Square root of vanished value
Transfinite Log [℘ ⬆@] Logarithm of transfinite value
Negligible Log [℘ ⬇@] Logarithm of negligible value
Log Transfinite [℘ @⬆] Logarithm with transfinite base
Log Negligible [℘ @⬇] Logarithm with negligible base
Negative Log [℘ -@] Logarithm of negative value
Log Negative [℘ @-] Logarithm with negative base
Sine [℘ s] Sine of value with imprecise period position
Cosine [℘ c] Cosine of value with imprecise period position
Arcsine [℘ S] Arcsine of value outside domain [-1,1]
Arccosine [℘ C] Arccosine of value outside domain [-1,1]
Tangent [℘ t] Tangent of value with imprecise period position

Operation Efficiency

The difference in computational efficiency between IEEE-754 and Spirix is clear when examining how subtraction works in both systems:

IEEE-754 Subtraction

0

Special Value Detection

Check if either operand is NaN, ±∞, or ±0

Apply special case rules (e.g., NaN dominates, infinities of same sign yield NaN)

Early exit for special value combinations

1

Operand Decoding

Extract sign bits, exponents, and significands

Unbias the exponent (Subtract from RAW exponent value)

Identify denormalized inputs based on exponent value

2

Operation Determination

Based on sign bits, determine if subtraction becomes addition

Effective operation: A - B = A + (-B)

Use either add or subtract branch depending on input signs

3

Denormal Handling (First Pass)

Check for denormalized operands

For denormals: No implicit leading 1, exponent = 0

For normals: Add implicit leading 1 bit to significand

4

Exponent Comparison

Compare exponents to determine larger value

Swap operands if needed to ensure larger operand is first

5

Exponent Alignment

Calculate exponent difference

Use larger operand's exponent as result exponent (pre-normalization)

6

Significand Alignment

Right-shift smaller operand's significand by exponent difference

Save shifted-out bits for rounding later

7

Sign and Significand Operation

Perform actual operation with significands

Check if operation crossed Zero (-4 + 5)

Handle borrow if needed

Adjust sign if needed

8

Zero Result Detection

Check if result significand is Zero

Apply IEEE Zero sign rules if needed

9

Leading Zero Detection

Count leading Zeros in result significand

Determine if shift would denormalize significand

10

Normalization (First Pass)

Left-shift result significand to eliminate leading Zeros

Decrement exponent for each bit shifted

Handle various underflow/overflow combinations

11

Denormal Result Detection

Check if resulting exponent would be less than minimum

If so, prepare for denormalized result handling

12

Denormal Result Handling

If result would have exponent < emin, shift significand right

Adjust to produce denormalized with exponent = emin

13

Sticky Bit Calculation

Collect all bits shifted out during alignment and normalization

OR them together to form sticky bit for rounding

14

Guard and Round Bit Setup

Identify guard bit (first bit shifted out during alignment)

Identify round bit (second bit shifted out)

15

Rounding Decision

Apply selected rounding mode (default: round-to-nearest-even)

Determine if rounding up or down based on guard, round, sticky bits

16

Rounding Execution

Add 1 to LSB if rounding up

Leave as is if rounding down

Handle cases where rounding causes carry that affects normalization

17

Post-Rounding Normalization

Check if rounding caused carry that requires renormalization

If significand overflows, right-shift and increment exponent

18

Overflow/Underflow Detection

Check if final exponent exceeds allowed range

Overflow: exponent > emax

Underflow: exponent < emin with non-Zero significand

19

Overflow/Underflow Handling

Overflow: Set to appropriate infinity or largest representable value

Underflow: Set to Zero or smallest representable value

20

Exception Flag Setting

Set appropriate status flags (inexact, underflow, overflow, invalid)

These are preserved for later error handling

21

Final Result Assembly

Combine sign bit, unbias exponent

Remove implicit leading bit if needed

Final format compliance check

Spirix Subtraction

0

Ambiguous Exponent Check

Single check handles all abnormal cases

1

Exponent Comparison

Determine which value has larger exponent

Skip shifts if difference exceeds fraction bits

2

Radix Alignment

Shift smaller fraction by exponent difference

3

Subtraction

Subtract fractions! No sign handling needed.

4

Normalization

Normalize result (shift fraction left)

5

Exponent Adjustment

Adjust exponent by shift amount

6

Underflow Check

Check exponent for underflow

If underflow, set exponent ambiguous, shift fraction right 1

No overflow checks necessary since the ambiguous exponent is one greater than MAX_EXPONENT and normal shares N-1 with exploded

The Result?

Spirix operations run quite a bit faster than IEEE-754 equivalents with more predictable behavior, especially for complex arithmetic.

The simplicity of the Spirix design makes hardware implementation smaller and faster.

Types and Precision Options

Spirix provides two primary numeric types:

Scalar

pub struct Scalar<F: Integer, E: Integer> {
	/// The normalized fraction component representing the significand.
	/// The fraction size determines the precision of the value.
	/// The N (prefix bit) pattern determines the Scalar's state
	/// (normal, exploded, vanished, Zero or undefined/unimplemented).
	pub fraction: F,

	/// The exponent component determining the scale of the value/phase.
	/// The exponent size determines the range of the value/phase.
	/// When equal to AMBIGUOUS_EXPONENT (1000000...), indicates an abnormal state
	/// (exploded, vanished, undefined/unimplemented Infinity or Zero).
	pub exponent: E,
}

Circle

pub struct Circle<F: Integer, E: Integer> {
	/// The real phase representing the real part of the complex number.
	pub real: F,

	/// The imaginary phase representing the imaginary part of the complex number.
	pub imaginary: F,

	/// The shared exponent determining the scale of both phases.
	/// When equal to AMBIGUOUS_EXPONENT (1000000...), indicates an abnormal state.
	pub exponent: E,
}

Both types can utilize any of Rust's native signed integer types (i8, i16, i32, i64, i128) for their components, allowing you to select any precision you want.

let supa_light: ScalarF3E3 = Scalar::<i8, i8>::from(42);
let to_ieee_infinity_and_beyond = Scalar::<i8, i128>::MAX;
let very_precise: ScalarF7E3 = 1.202056903159594285399738161511449990764986292;

Type Aliases for Valid Configurations

For convenience, Spirix provides type aliases for all valid Rust fraction and exponent combinations. Here are some examples:

// Format: F#E# (Fraction bits, Exponent bits)
pub type ScalarF5E3 = Scalar<i32, i8> // 32-bit fraction, 8-bit exponent
pub type ScalarF4E4 = Scalar<i16, i16> // 16-bit fraction, 16-bit exponent
pub type ScalarF6E4 = Scalar<i64, i16> // 64-bit fraction, 16-bit exponent
pub type ScalarF6E6 = Scalar<i64, i64> // 64-bit fraction, 64-bit exponent
pub type CircleF7E7 = Circle<i128, i8> // Really good for the Mandelbrot set!

Similarly for complex numbers with CircleF5E3, CircleF4E4, etc.

Precision vs Range Matrix

Select your ideal balance between decimal digits of Precision and Range

F3
2.1 digits
(i8)

F4
4.5 digits
(i16)

F5
9.3 digits
(i32)

F6
18.9 digits
(i64)

F7
38.2 digits
(i128)

E3 Range
10^38.5
(i8)

F3E3
P: 2.1 digits
R: 10^38.5
F4E3
P: 4.5 digits
R: 10^38.5
F5E3
P: 9.3 digits
R: 10^38.5
F6E3
P: 18.9 digits
R: 10^38.5
F7E3
P: 38.2 digits
R: 10^38.5

E4 Range
10^9860
(i16)

F3E4
P: 2.1 digits
R: 10^9860
F4E4
P: 4.5 digits
R: 10^9860
F5E4
P: 9.3 digits
R: 10^9860
F6E4
P: 18.9 digits
R: 10^9860
F7E4
P: 38.2 digits
R: 10^9860

E5 Range
10^(10^8.81)
(i32)

F3E5
P: 2.1 digits
R: 10^(10^8.81)
F4E5
P: 4.5 digits
R: 10^(10^8.81)
F5E5
P: 9.3 digits
R: 10^(10^8.81)
F6E5
P: 18.9 digits
R: 10^(10^8.81)
F7E5
P: 38.2 digits
R: 10^(10^8.81)

E6 Range
10^(10^18.4)
(i64)

F3E6
P: 2.1 digits
R: 10^(10^18.4)
F4E6
P: 4.5 digits
R: 10^(10^18.4)
F5E6
P: 9.3 digits
R: 10^(10^18.4)
F6E6
P: 18.9 digits
R: 10^(10^18.4)
F7E6
P: 38.2 digits
R: 10^(10^18.4)

E7 Range
10^(10^37.7)
(i128)

F3E7
P: 2.1 digits
R: 10^(10^37.7)
F4E7
P: 4.5 digits
R: 10^(10^37.7)
F5E7
P: 9.3 digits
R: 10^(10^37.7)
F6E7
P: 18.9 digits
R: 10^(10^37.7)
F7E7
P: 38.2 digits
R: 10^(10^37.7)

Truth Tables

Addition

↓ Addend ↓
↓ Augend ↓
+ [0] [↓] [#] [↑] [∞] [℘?]
[0] [0] [↓] [#] [℘+⬆] [℘+⬆] [℘?]
[↓] [↓] [℘↓+↓] [#] [℘ +⬆] [℘ +⬆] [℘?]
[#] [#] [#] [0], [#],
[↓], [↑]
[℘ +⬆] [℘ +⬆] [℘?]
[↑] [℘ ⬆+] [℘ ⬆+] [℘ ⬆+] [℘ ⬆+⬆] [℘ ⬆+⬆] [℘?]
[∞] [℘ +⬆] [℘ +⬆] [℘ +⬆] [℘ ⬆+⬆] [℘ ⬆+⬆] [℘?]
[℘?] [℘?] [℘?] [℘?] [℘?] [℘?] [℘?]

Subtraction

↓ Minuend ↓
↓ Subtrahend ↓
- [0] [↓] [#] [↑] [∞] [℘?]
[0] [0] [↓] [#] [℘-⬆] [℘-⬆] [℘?]
[↓] [↓] [℘↓-↓] [#] [℘ -⬆] [℘ -⬆] [℘?]
[#] [#],
[↓], [↑]
[#],
[↓], [↑]
[0], [#],
[↓], [↑]
[℘ -⬆] [℘ -⬆] [℘?]
[↑] [℘ ⬆-] [℘ ⬆-] [℘ ⬆-] [℘ ⬆-⬆] [℘ ⬆-⬆] [℘?]
[∞] [℘ -⬆] [℘ -⬆] [℘ -⬆] [℘ ⬆-⬆] [℘ ⬆-⬆] [℘?]
[℘?] [℘?] [℘?] [℘?] [℘?] [℘?] [℘?]

Multiplication

↓ Multiplier ↓
↓ Multiplicand ↓
× [0] [↓] [#] [↑] [∞] [℘?]
[0] [0] [0] [0] [0] [℘⬆×⬇] [℘?]
[↓] [0] [↓] [↓] [℘⬆×⬇] [∞] [℘?]
[#] [0] [↓] [#],
[↓], [↑]
[↑] [∞] [℘?]
[↑] [0] [℘ ⬇-⬆] [↑] [↑] [∞] [℘?]
[∞] [℘ ⬇-⬆] [∞] [∞] [∞] [∞] [℘?]
[℘?] [℘?] [℘?] [℘?] [℘?] [℘?] [℘?]

Division

↓ Numerator ↓
↓ Denominator ↓
÷ [0] [↓] [#] [↑] [∞] [℘?]
[0] [℘ ⬇/⬇] [∞] [∞] [∞] [∞] [℘?]
[↓] [0] [℘ ⬇/⬇] [↑] [↑] [∞] [℘?]
[#] [0] [↓] [#],
[↓], [↑]
[↑] [∞] [℘?]
[↑] [0] [↓] [↓] [℘ ⬆/⬆] [∞] [℘?]
[∞] [0] [0] [0] [0] [℘ ⬆/⬆] [℘?]
[℘?] [℘?] [℘?] [℘?] [℘?] [℘?] [℘?]

Summary

Spirix represents a fundamental redesign of floating-point arithmetic built on two's complement representation thruout the entire calculation pipeline. The key technical advantages include:

Performance Gains

  • Instruction count reduction: Up to 13:1 improvement for complex operations
    • Complex division: 169 vs. 2,199 instructions
    • Scalar subtraction: 49 vs. 192 instructions
  • Branching efficiency: ~90% reduction in conditional branches
  • Pipeline efficiency: Simplified computation paths reduce stalls (SIMD!)

Mathematical Integrity

  • Multiplicative identity: a × b = 0 if and only if a = 0 or b = 0
  • Subtractive identity: a - b = 0 if and only if a = b
  • Phase preservation: Orientation information maintained even beyond normal range
  • Detailed error tracing: Specific undefined states preserve cause information

Implementation Pathway

Spirix was designed with practical implementation in mind. Its simplified operational pipeline makes it well-suited for both software libraries and hardware acceleration. The system is parameterized to allow flexible deployment across various hardware targets with different precision and range requirements.

The continuous number line and elimination of many special cases significantly reduce both the complexity and power requirements of arithmetic logic, creating opportunities for more efficient compute engines, particularly for complex number operations common in scientific computing, physical simulations, and spectral processing.

Performance

Dramatic reduction in instruction count and branching complexity translates to higher thruput and lower power consumption for all floating-point operations, with even greater gains for complex arithmetic.

Precision

Customizable fraction and exponent sizing enables optimized balance between range and precision for specific workloads, while maintaining mathematical consistency across operations.

Predictability

Mathematically coherent behavior at extreme values and singularities creates more reliable and predictable numerical algorithms, reducing the need for special case handling in software.

Spirix offers a technically sound alternative to IEEE-754 that addresses fundamental limitations in current floating-point implementations. Its two's complement approach simplifies the computational pipeline while simultaneously improving mathematical consistency. The performance improvements and reduced complexity demonstrated in the reference implementation indicate substantial potential benefits for next-generation computing architectures.

License

Spirix is licensed under a custom license that permits:

Prohibited:

For full license details, see the LICENSE file.

Contact

For questions, commercial licensing, or other language implementation approval: