Skip to content

Number

The number codec handles numeric data encoding and decoding using JavaScript's DataView for precise binary representation. It supports integers and floating-point numbers with different byte lengths.

Overview

  • Type: 'number'
  • Returns: number
  • Dependencies: None (uses DataView directly)
  • Use Cases: Counters, IDs, sizes, offsets, measurements

Basic Usage

ts
import type { 
CodecSpec
} from 'binary-codec';
import {
deserialize
,
serialize
} from 'binary-codec';
const
spec
= {
byteLength
: 6,
fields
: [
{
name
: 'id',
type
: 'number',
numberType
: 'uint',
byteOffset
: 0,
byteLength
: 2
}, {
name
: 'count',
type
: 'number',
numberType
: 'uint',
byteOffset
: 2,
byteLength
: 4
} ] } as
const
satisfies
CodecSpec
;
// Serialize numbers to buffer const
data
= {
id
: 42,
count
: 1000
}; const
buffer
=
serialize
(
spec
,
data
);
// Deserialize back - hover over result to see the type const
result
=
deserialize
(
spec
,
buffer
);
console
.
log
(
result
.
id
); // 42
console
.
log
(
result
.
count
); // 1000

Field Properties

PropertyTypeRequiredDescription
namestringField identifier
type'number'Must be 'number'
byteOffsetnumberPosition in buffer (0-based)
byteLength1 | 2 | 4Number of bytes (determines range)
numberType'uint' | 'int' | 'float'Numeric representation type
littleEndianbooleanByte order (default: false for big-endian)
ts
import type { 
CodecSpec
} from 'binary-codec';
const
spec
= {
byteLength
: 8,
fields
: [
{
name
: 'value',
type
: 'number',
numberType
: 'uint', // Unsigned integer
byteOffset
: 0,
byteLength
: 4, // 4 bytes = 32-bit
littleEndian
: true // Little-endian byte order
} ] } as
const
satisfies
CodecSpec
;

Number Types

Unsigned Integers (uint)

Non-negative whole numbers with different ranges:

ts
import type { 
CodecSpec
} from 'binary-codec';
import {
serialize
} from 'binary-codec';
const
uintSpec
= {
byteLength
: 7,
fields
: [
{
name
: 'byte',
type
: 'number',
numberType
: 'uint',
byteOffset
: 0,
byteLength
: 1 // Range: 0 to 255
}, {
name
: 'short',
type
: 'number',
numberType
: 'uint',
byteOffset
: 1,
byteLength
: 2 // Range: 0 to 65,535
}, {
name
: 'long',
type
: 'number',
numberType
: 'uint',
byteOffset
: 3,
byteLength
: 4 // Range: 0 to 4,294,967,295
} ] } as
const
satisfies
CodecSpec
;
const
data
= {
byte
: 255,
short
: 65535,
long
: 4294967295
}; const
buffer
=
serialize
(
uintSpec
,
data
);

Signed Integers (int)

Positive and negative whole numbers:

ts
import type { 
CodecSpec
} from 'binary-codec';
const
intSpec
= {
byteLength
: 7,
fields
: [
{
name
: 'byte',
type
: 'number',
numberType
: 'int',
byteOffset
: 0,
byteLength
: 1 // Range: -128 to 127
}, {
name
: 'short',
type
: 'number',
numberType
: 'int',
byteOffset
: 1,
byteLength
: 2 // Range: -32,768 to 32,767
}, {
name
: 'long',
type
: 'number',
numberType
: 'int',
byteOffset
: 3,
byteLength
: 4 // Range: -2,147,483,648 to 2,147,483,647
} ] } as
const
satisfies
CodecSpec
;

Floating Point (float)

Decimal numbers with IEEE 754 representation:

ts
import type { 
CodecSpec
} from 'binary-codec';
const
floatSpec
= {
byteLength
: 4,
fields
: [
{
name
: 'temperature',
type
: 'number',
numberType
: 'float',
byteOffset
: 0,
byteLength
: 4 // 32-bit IEEE 754 float
} ] } as
const
satisfies
CodecSpec
;
// Type is automatically inferred as { temperature: number }

Byte Order (Endianness)

Control byte order for multi-byte numbers:

ts
import type { 
CodecSpec
} from 'binary-codec';
import {
serialize
} from 'binary-codec';
const
endianSpec
= {
byteLength
: 8,
fields
: [
{
name
: 'bigEndian',
type
: 'number',
numberType
: 'uint',
byteOffset
: 0,
byteLength
: 4,
littleEndian
: false // Big-endian (default)
}, {
name
: 'littleEndian',
type
: 'number',
numberType
: 'uint',
byteOffset
: 4,
byteLength
: 4,
littleEndian
: true // Little-endian
} ] } as
const
satisfies
CodecSpec
;
const
data
= {
bigEndian
: 0x12345678,
littleEndian
: 0x12345678
}; const
buffer
=
serialize
(
endianSpec
,
data
);
// Big-endian: [0x12, 0x34, 0x56, 0x78] // Little-endian: [0x78, 0x56, 0x34, 0x12]

Error Handling

The number codec performs validation at different stages:

Specification Validation

This validation occurs during both deserialization and serialization:

Error CodeLevelDescription
INVALID_NUMBER_TYPE_LENGTHFATALInvalid numberType and byteLength combination
ts
import type { 
CodecSpec
} from 'binary-codec';
// ❌ This spec will cause FATAL validation error in both operations const
invalidSpec
= {
byteLength
: 8,
fields
: [
{
name
: 'value',
type
: 'number',
numberType
: 'float',
byteOffset
: 0,
byteLength
: 8 as any // INVALID_NUMBER_TYPE_LENGTH: float only supports 4 bytes
} ] } as
const
satisfies
CodecSpec
;

Valid combinations:

  • uint: 1, 2, or 4 bytes
  • int: 1, 2, or 4 bytes
  • float: 4 bytes only

Data Validation

This validation occurs only during serialization:

Error CodeLevelDescription
INVALID_NUMBER_DATA_TYPEFATALData must be a number
INVALID_UINT_VALUEERRORValue must be non-negative integer for uint
UINT_VALUE_OUT_OF_RANGEERRORValue exceeds maximum for byte length
INVALID_INT_VALUEERRORValue must be integer for int
INT_VALUE_OUT_OF_RANGEERRORValue exceeds range for byte length
NON_FINITE_FLOAT_VALUEWARNINGFloat value is not finite
ts
import type { 
CodecSpec
} from 'binary-codec';
import {
serialize
} from 'binary-codec';
const
spec
= {
byteLength
: 4,
fields
: [
{
name
: 'value',
type
: 'number',
numberType
: 'uint',
byteOffset
: 0,
byteLength
: 2 // Range: 0 to 65,535
} ] } as
const
satisfies
CodecSpec
;
// ❌ INVALID_NUMBER_DATA_TYPE: not a number // const result1 = serialize(spec, { value: "123" }) // ❌ INVALID_UINT_VALUE: negative value for uint // const result2 = serialize(spec, { value: -1 }) // ❌ UINT_VALUE_OUT_OF_RANGE: exceeds 2-byte range // const result3 = serialize(spec, { value: 100000 }) // ✅ Valid data const
result
=
serialize
(
spec
, {
value
: 42
});

Real-World Examples

Protocol Header

ts
import type { 
CodecSpec
} from 'binary-codec';
import {
deserialize
} from 'binary-codec';
const
protocolSpec
= {
byteLength
: 8,
fields
: [
{
name
: 'version',
type
: 'number',
numberType
: 'uint',
byteOffset
: 0,
byteLength
: 1
}, {
name
: 'messageType',
type
: 'number',
numberType
: 'uint',
byteOffset
: 1,
byteLength
: 1
}, {
name
: 'sequenceId',
type
: 'number',
numberType
: 'uint',
byteOffset
: 2,
byteLength
: 4
}, {
name
: 'checksum',
type
: 'number',
numberType
: 'uint',
byteOffset
: 6,
byteLength
: 2
} ] } as
const
satisfies
CodecSpec
;
const
buffer
= new
Uint8Array
([0x01, 0x05, 0x00, 0x00, 0x03, 0xE8, 0x1A, 0x2B]);
const
header
=
deserialize
(
protocolSpec
,
buffer
);
console
.
log
(
header
.
version
); // 1
console
.
log
(
header
.
messageType
); // 5
console
.
log
(
header
.
sequenceId
); // 1000
console
.
log
(
header
.
checksum
); // 6699

Sensor Data

ts
import type { 
CodecSpec
} from 'binary-codec';
const
sensorSpec
= {
byteLength
: 12,
fields
: [
{
name
: 'timestamp',
type
: 'number',
numberType
: 'uint',
byteOffset
: 0,
byteLength
: 4
}, {
name
: 'temperature',
type
: 'number',
numberType
: 'float',
byteOffset
: 4,
byteLength
: 4
}, {
name
: 'humidity',
type
: 'number',
numberType
: 'float',
byteOffset
: 8,
byteLength
: 4
} ] } as
const
satisfies
CodecSpec
;
// Type is automatically inferred as: // { timestamp: number, temperature: number, humidity: number }

Next Steps

Now that you understand the number codec, continue with:

Released under the MIT License.