Skip to main content

Python bindings for working with 24-bit integers.

Project description

i24: Integer Types for Rust (i24, u24)

i24 Logo

Crates.ioDocs.rsMSRV: 1.70+

The i24 crate provides specialized integer types for Rust: i24 (24-bit signed) and u24 (24-bit unsigned). These types fill precision gaps in Rust's integer types and are particularly useful in audio processing, embedded systems, network protocols, and other scenarios where specific bit-width precision is required.

Features

Integer Types

  • i24: 24-bit signed integer (range: -8,388,608 to 8,388,607)
  • u24: 24-bit unsigned integer (range: 0 to 16,777,215)

Core Functionality

  • Seamless conversion to/from standard Rust integer types
  • Complete arithmetic operations with overflow checking
  • Bitwise operations
  • Conversions from various byte representations (little-endian, big-endian, native)
  • Wire/packed format support for binary protocols
  • Compile-time macros: i24!() and u24!() for checked construction
  • Implements standard traits: Debug, Display, PartialEq, Eq, PartialOrd, Ord, Hash

This crate came about as a part of the Wavers project, which is a Wav file reader and writer for Rust. All integer types have Python bindings available via the pyo3 feature.

Usage

Add this to your`` Cargo.toml`:

 [dependencies]
 i24 = "2.2.4"

or just run

cargo add i24

to get the latest version.

Basic Usage

use i24::{i24, u24};

// Using macros for compile-time checked construction
let signed_24 = i24!(1000);
let unsigned_24 = u24!(2000);

// Arithmetic operations
let sum_24 = signed_24 + i24!(500);
assert_eq!(sum_24.to_i32(), 1500);

// Conversions
let as_i32: i32 = signed_24.into();
let as_u32: u32 = unsigned_24.into();

The i24!() and u24!() macros allow you to create values at compile time, ensuring they're within the valid range.

Binary Data and Wire Formats

For working with binary data, all types support reading/writing from byte arrays:

use i24::{i24, u24};

// Reading from bytes (little-endian, big-endian, native)
let bytes_le = [0x00, 0x01, 0x02]; // 3-byte representation
let value = i24::from_le_bytes(bytes_le);

// Writing to bytes
let bytes: [u8; 3] = value.to_be_bytes();

// Bulk operations for slices
let raw_data: &[u8] = &[0x00, 0x01, 0x02, 0x00, 0x01, 0xFF];
let values: Vec<i24> = i24::read_i24s_be(raw_data).expect("valid buffer");
let encoded: Vec<u8> = i24::write_i24s_be(&values);

Packed Structs

For binary protocols and serialization, use the PackedStruct trait:

use i24::{i24, packed::PackedStruct};

#[derive(Debug, Clone, PartialEq)]
struct WireFormat {
    header: u32,
    samples: [i24; 5],
}

impl PackedStruct for WireFormat {
    const PACKED_SIZE: usize = 4 + 5 * 3; // u32 + 5 * i24 = 19 bytes
    
    fn from_packed_bytes(bytes: &[u8]) -> Option<Self> {
        // Implementation for deserializing from bytes
        // ...
    }
    
    fn to_packed_bytes(&self) -> Vec<u8> {
        // Implementation for serializing to bytes
        // ...
    }
}

Safety and Limitations

All integer types strive to behave similarly to Rust's built-in integer types, with some important considerations:

Value Ranges

  • i24: [-8,388,608, 8,388,607]
  • u24: [0, 16,777,215]

Overflow Behavior

  • Arithmetic operations match the behavior of their closest standard Rust integer type
  • Bitwise operations are performed on the actual bit-width representation
  • Always use checked arithmetic operations when dealing with untrusted input

Memory Safety

All types align with bytemuck safety requirements (NoUninit, Zeroable, AnyBitPattern), ensuring safe byte-to-value conversions. The bulk I/O operations use bytemuck::cast_slice internally for efficient, safe conversions.

Feature Flags

  • pyo3: Enables Python bindings for all integer types (i24, u24)
  • serde: Enables Serialize and Deserialize traits for all integer types
  • alloc: Enables bulk I/O operations and PackedStruct functionality

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under MIT - see the LICENSE file for details.

Benchmarks

The crate was tested using the code found in the i24_benches directory of the repo. Unsurprisingly, the performance of both types matches the performance of the underlying 32-bit type.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

i24_type-2.3.0.tar.gz (1.6 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

i24_type-2.3.0-cp311-cp311-manylinux_2_34_x86_64.whl (258.5 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.34+ x86-64

File details

Details for the file i24_type-2.3.0.tar.gz.

File metadata

  • Download URL: i24_type-2.3.0.tar.gz
  • Upload date:
  • Size: 1.6 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.11.2

File hashes

Hashes for i24_type-2.3.0.tar.gz
Algorithm Hash digest
SHA256 e9efe7890735aa4d9b5dfe7fcf3def4282bbfa79888404faa24a2f07c6badf4a
MD5 8c70b044f88b7ea7fb0862773b0b79cf
BLAKE2b-256 08ffe08d555cee0414a08cad0fcb1c7b460d5f83a12b48653b7c55dce67f6bfa

See more details on using hashes here.

File details

Details for the file i24_type-2.3.0-cp311-cp311-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for i24_type-2.3.0-cp311-cp311-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 5390a86b9b0a5734c411451b46c53d86b5bc6fe22c760a7dab5f604b9ccb13c5
MD5 c354626a31fa946616a561f7a5db70ef
BLAKE2b-256 5dc46c68d8ddf95e692ae34a8303954c29a4ab0f2fbdba7cb7b10905bfadf759

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page