Modules

Float16

moduleSource
macOSLinuxWindowswasm

#import "Float16";

The 16-bit IEEE half-precision storage format, with conversions to and from float32 and the Math vector and matrix types.

A Float16 holds only the bits (1 sign, 5 exponent, 10 significand): it has no arithmetic of its own, so convert to float32, compute, and convert back. Half precision has about three decimal digits, a largest finite value of 65504, and subnormals down to 2^-24.

Show moreShow less

The module parameter ASSERT_ON_OVERFLOW (default false) turns a finite value too large for a half, which otherwise becomes infinity, into a failed assert: #import "Float16"(ASSERT_ON_OVERFLOW = true).

Procedures#

(h: Float16) -> float32

Converts a half to float32. Every half value is exactly representable, so the conversion is exact: subnormals, signed zero and infinities carry over, and a NaN stays a NaN with its payload.

assert(half_to_float_fast4(cast(Float16) 0x3c00) == 1.0);
assert(half_to_float_fast4(cast(Float16) 0xc000) == -2.0);
assert(half_to_float_fast4(cast(Float16) 0x7bff) == 65504.0);
assert(half_to_float_fast4(cast(Float16) 0x0001) == 5.9604644775390625e-8); // smallest subnormal
↗
(_f: float32) -> Float16

Converts a float32 to the nearest half, rounding ties to the even significand. Called float32_to_float16 too.

assert(cast(u16) float_to_half_fast3(1.0) == 0x3c00);
assert(cast(u16) float_to_half_fast3(-2.0) == 0xc000);
assert(cast(u16) float_to_half_fast3(65504.0) == 0x7bff);
assert(cast(u16) float_to_half_fast3(1.0 / 3.0) == 0x3555);
assert(cast(u16) float_to_half_fast3(100000.0) == 0x7c00); // overflow: infinity
assert(cast(u16) float_to_half_fast3(cast(float32) 1.00048828125) == 0x3c00); // tie rounds to even
↗

Types#

:: #type,isa u16

A half-precision float stored as its 16 bits. It is a distinct type based on u16, so a value cannot be mixed with integers or floats by accident; cast(u16) h gives the raw bits and cast(Float16) bits builds one from them.

one := float32_to_float16(1.0);
assert(cast(u16) one == 0x3c00);
assert(float16_to_float32(cast(Float16) 0x4000) == 2.0);
↗
:: struct

Two Float16 components. Convert with vector2_float32 and vector2_float16.

:: struct

Three Float16 components. Convert with vector3_float32 and vector3_float16.

:: struct

Four Float16 components. Convert with vector4_float32 and vector4_float16.

:: struct

A 3x3 matrix of Float16, with the same field names (_11 to _33) and the same row-major floats overlay as Math.Matrix3. Convert with matrix3_float32 and matrix3_float16.