first commit
This commit is contained in:
58
docs/foundation/flow/cbor/src/encoder/half-float.md
Normal file
58
docs/foundation/flow/cbor/src/encoder/half-float.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# `half-float` (encoder side)
|
||||
|
||||
## Purpose
|
||||
|
||||
Encodes a JavaScript `number` as IEEE 754 binary16 (CBOR major 7 / value 25)
|
||||
when the round-trip is exact, and otherwise indicates non-representability so
|
||||
the caller can pick a wider format. Also exports `selectFloatWidth`, which
|
||||
chooses between float32 and float64 based on exact-representability — the
|
||||
encoder's deterministic path uses this to skip half-float without giving up
|
||||
shortest-exact behaviour at the float32 / float64 boundary.
|
||||
|
||||
## Features
|
||||
|
||||
- Full IEEE 754 binary16 coverage: ±0, ±Infinity, NaN, normal values,
|
||||
subnormals, smallest-normal / largest-normal boundaries.
|
||||
- `tryEncodeFloat16(value)` returns the 2-byte big-endian sequence on exact
|
||||
round-trip; returns `undefined` on overflow / underflow / inexact-precision.
|
||||
- `selectFloatWidth(value)` picks float32 (4 bytes) when `getFloat32` round-
|
||||
trips the value exactly, otherwise float64 (8 bytes). NaN is treated as
|
||||
float32-exact since both float32 and float64 represent NaN.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { tryEncodeFloat16 } from "@suaveplan/cbor/encoder";
|
||||
|
||||
const bytes = tryEncodeFloat16(1.5); // Uint8Array(2) [0x3e, 0x00]
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import { selectFloatWidth, tryEncodeFloat16 } from "@suaveplan/cbor/encoder";
|
||||
|
||||
function pickFloat(value: number): { tag: number; bytes: Uint8Array } {
|
||||
const f16 = tryEncodeFloat16(value);
|
||||
if (f16) return { tag: 0xf9, bytes: f16 };
|
||||
const { width, bytes } = selectFloatWidth(value);
|
||||
return { tag: width === 4 ? 0xfa : 0xfb, bytes };
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `tryEncodeFloat16(value: number): Uint8Array | undefined` — exact-only.
|
||||
- `selectFloatWidth(value: number): { width: 4 | 8; bytes: Uint8Array }`.
|
||||
- `type FloatWidth = 4 | 8`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The exact-only contract is critical for deterministic encoding: a lossy
|
||||
half-float emission would produce different bytes for inputs that look
|
||||
"close" but differ in the last bit of the mantissa. The implementation
|
||||
verifies round-trip via reconstruction (`(1 + mant/1024) * 2^(exp-15)` for
|
||||
normals, `mant * 2^-24` for subnormals) and rejects when the rebuild does
|
||||
not equal the input under `===`. NaN is hard-coded to `7e00` (the canonical
|
||||
quiet-NaN form) — RFC 8949 §3.3 explicitly permits losing NaN payload bits,
|
||||
which JavaScript would do anyway since `Number` collapses payloads.
|
||||
Reference in New Issue
Block a user