Table of Contents

Class WireMath

Namespace
Typhon.Protocol
Assembly
Typhon.Protocol.dll

The codec arithmetic of 03-wire-protocol § 12 (decisions W1–W10): quantization, normalized values, angles, smallest-three quaternions, half floats and low-bit ticks, written so that C#, the TypeScript SDK and the engine produce bit-identical integer codes and bit-identical decoded doubles.

public static class WireMath
Inheritance
WireMath
Inherited Members

Remarks

The rules that make that true (W1). All arithmetic is binary64: a float32 input is widened first (exact) and a result is narrowed only after decoding. Ties round half away from zero — never Round(double)'s default to-even, never floor(x + 0.5). Values are clamped in double before any integer conversion. Only + − × ÷, Sqrt(double), Floor(double), Abs(double) and comparisons appear; powers of two come from Pow2(int), built by doubling, never from Pow(double, double). Nothing here may call FusedMultiplyAdd(double, double, double) or a MultiplyAddEstimate: a fused result differs in the last bit from the TypeScript one.

Operators evaluate left to right, one IEEE operation each, exactly as the formulas in § 12 are written. Reordering a product "for speed" changes the last bit and breaks the golden vectors — that is the point of having them.

Fields

CanonicalNaN

The one NaN a decoder produces: bits 0x7FF8000000000000. JavaScript has a single observable NaN, so a decoded NaN that kept its sign or payload could never be bit-exact across languages. NaN is not it — its sign bit is set.

public static readonly double CanonicalNaN

Field Value

double

Sqrt1Over2

√½, identical to TypeScript's Math.SQRT1_2.

public static readonly double Sqrt1Over2

Field Value

double

Tau

2π, as C#'s Tau and TypeScript's 2 * Math.PI both spell it.

public const double Tau = 6.283185307179586

Field Value

double

Methods

CanonicalizeNaN(double)

Replaces any NaN with CanonicalNaN.

public static double CanonicalizeNaN(double value)

Parameters

value double

A decoded value.

Returns

double

The value, or the canonical NaN.

DecodeAngle(int, int)

Decodes an angle: (q × 2π) / 2ᵇ.

public static double DecodeAngle(int q, int bits)

Parameters

q int

The signed code.

bits int

8, 16, 24 or 32.

Returns

double

Radians in [−π, π).

DecodeHalf(ushort)

Decodes IEEE half bits, widened exactly.

public static double DecodeHalf(ushort bits)

Parameters

bits ushort

The half's bits.

Returns

double

The value; every NaN pattern decodes as CanonicalNaN.

DecodeQuant(uint, double, double, int)

Decodes a quant code: min + q × step. Never clamps.

public static double DecodeQuant(uint q, double min, double max, int bits)

Parameters

q uint

The code.

min double

The declared minimum.

max double

The declared maximum.

bits int

8, 16, 24 or 32.

Returns

double

The value, in [min, max − step].

DecodeQuantWithStep(uint, double, double)

Decodes a quant code with its step precomputed by QuantStep(double, double, int): the same operations, so the same bits.

public static double DecodeQuantWithStep(uint q, double min, double step)

Parameters

q uint

The code.

min double

The declared minimum.

step double

(max − min) / 2ᵇ.

Returns

double

The value.

DecodeQuat3(uint, Span<double>)

Decodes a smallest-three rotation into xyzw.

public static void DecodeQuat3(uint bits, Span<double> xyzw)

Parameters

bits uint

The 32-bit code.

xyzw Span<double>

Receives x, y, z, w.

DecodeSnorm(int, int)

Decodes a snorm: max(q / (2ᵇ⁻¹ − 1), −1).

public static double DecodeSnorm(int q, int bits)

Parameters

q int

The signed code.

bits int

8, 16, 24 or 32.

Returns

double

A value in [−1, 1]; −1, 0 and 1 exact.

DecodeTickLo(ushort, uint)

Rebuilds an absolute tick from its low 16 bits against the frame's tick, assuming it is in the past and less than 2¹⁶ ticks old.

public static uint DecodeTickLo(ushort low, uint frameTick)

Parameters

low ushort

The low 16 bits.

frameTick uint

The tick of the frame that carried it.

Returns

uint

The absolute tick.

DecodeUnorm(uint, int)

Decodes a unorm: q / (2ᵇ − 1) — a division, not a multiplication by the reciprocal, which differs in the last bit.

public static double DecodeUnorm(uint q, int bits)

Parameters

q uint

The code.

bits int

8, 16, 24 or 32.

Returns

double

A value in [0, 1]; 0 and 1 exact.

DecodeVec(int, double, int)

Decodes one vec component; the code −2ᵇ⁻¹ reads as −(2ᵇ⁻¹ − 1).

public static double DecodeVec(int q, double scale, int bits)

Parameters

q int

The signed code.

scale double

The size of one step.

bits int

8, 16, 24 or 32.

Returns

double

The value.

DecodeVel(int, double, int, int)

Decodes one vel axis to world units per tick: (q × posStep) / quantaDiv.

public static double DecodeVel(int q, double posStep, int quantaDiv, int bits)

Parameters

q int

The signed code.

posStep double

The linked position codec's step on this axis.

quantaDiv int

The divisor.

bits int

8, 16, 24 or 32.

Returns

double

Displacement per tick.

EncodeAngle(double, int)

Encodes an angle as a two's-complement code over [−π, π).

public static int EncodeAngle(double theta, int bits)

Parameters

theta double

Radians; non-finite values, and values whose code would exceed 2⁵³ in magnitude, encode as 0.

bits int

8, 16, 24 or 32.

Returns

int

The signed code, in [−2ᵇ⁻¹, 2ᵇ⁻¹).

EncodeHalf(double)

Converts a double to IEEE half bits directly (ties to even, overflow to infinity), with NaN canonicalized to 0x7E00.

public static ushort EncodeHalf(double value)

Parameters

value double

The value, in its source precision.

Returns

ushort

The half's bits.

EncodeQuant(double, double, double, int)

Encodes a quant value (or one pos axis) over [min, max) at bits bits: step = (max − min) / 2ᵇ.

public static uint EncodeQuant(double v, double min, double max, int bits)

Parameters

v double

The value; NaN, −∞ and anything below min encode as 0, anything at or above max − step/2 clamps to the top code.

min double

The declared minimum (inclusive).

max double

The declared maximum (exclusive).

bits int

8, 16, 24 or 32.

Returns

uint

The code, in [0, 2ᵇ − 1].

EncodeQuat3(double, double, double, double)

Encodes a rotation as smallest-three in 32 bits: index in bits 0–1, then three 10-bit signed components, ascending axis order.

public static uint EncodeQuat3(double x, double y, double z, double w)

Parameters

x double

Quaternion x.

y double

Quaternion y.

z double

Quaternion z.

w double

Quaternion w.

Returns

uint

The 32-bit code.

EncodeSingle(double)

The single-precision bits a value encodes to: narrowing ties to even, NaN canonicalized to 0x7FC00000.

public static uint EncodeSingle(double value)

Parameters

value double

The value.

Returns

uint

The single's bits.

EncodeSnorm(double, int)

Encodes a snorm: q = rha(clamp(v, −1, 1) × (2ᵇ⁻¹ − 1)).

public static int EncodeSnorm(double v, int bits)

Parameters

v double

The value; NaN encodes as 0.

bits int

8, 16, 24 or 32.

Returns

int

The signed code.

EncodeUnorm(double, int)

Encodes a unorm: q = rhu(v × (2ᵇ − 1)), clamped to [0, 2ᵇ − 1].

public static uint EncodeUnorm(double v, int bits)

Parameters

v double

The value; NaN and anything ≤ 0 encode as 0.

bits int

8, 16, 24 or 32.

Returns

uint

The code.

EncodeVec(double, double, int)

Encodes one vec component: scale is one step; signed, clamped symmetrically to ±(2ᵇ⁻¹ − 1).

public static int EncodeVec(double v, double scale, int bits)

Parameters

v double

The value; NaN encodes as 0.

scale double

The size of one step.

bits int

8, 16, 24 or 32.

Returns

int

The signed code.

EncodeVel(double, double, int, int)

Encodes one vel axis: displacement per tick in units of the axis' position step ÷ quantaDiv, signed, symmetric clamp.

public static int EncodeVel(double d, double posStep, int quantaDiv, int bits)

Parameters

d double

Displacement per tick, in world units; NaN encodes as 0.

posStep double

The linked position codec's step on this axis.

quantaDiv int

The divisor, an integer ≥ 1.

bits int

8, 16, 24 or 32.

Returns

int

The signed code.

Pow2(int)

2ᵇ as an exact double, for b in [0, 64].

public static double Pow2(int b)

Parameters

b int

The exponent.

Returns

double

2ᵇ.

QuantStep(double, double, int)

The quantization step of a quant or pos axis: (max − min) / 2ᵇ.

public static double QuantStep(double min, double max, int bits)

Parameters

min double

The declared minimum.

max double

The declared maximum.

bits int

8, 16, 24 or 32.

Returns

double

The step.

RoundHalfAwayFromZero(double)

Rounds half away from zero (rha).

public static double RoundHalfAwayFromZero(double x)

Parameters

x double

The value.

Returns

double

The nearest integer, ties away from zero.

SymmetricLimit(int)

The largest magnitude of a symmetric signed code: 2ᵇ⁻¹ − 1.

public static int SymmetricLimit(int bits)

Parameters

bits int

8, 16, 24 or 32.

Returns

int

The limit.