Skip to content
/ bitint Public

A Rust library for integer types that have a logical width measured in bits.

License

Notifications You must be signed in to change notification settings

mvanbem/bitint

Repository files navigation

bitint

crates.io docs.rs CI Status

A bit-integer library for Rust. bitints are like primitive integer types, but their logical width is measured in bits.

This crate provides the UBitint trait and 128 types named U1 through U128 that implement it. Each type wraps the smallest primitive unsigned integer type that can contain it. The types that are not the same width as their primitive type impose a validity constraint---the value is represented in the least significant bits and the upper bits are always clear.

Demo

// Recommended, but not required.
use bitint::prelude::*;

// Use the bitint! macro to write a bitint literal. Underscores are permitted
// anywhere in a Rust literal and are encouraged for readability.
let seven = bitint!(7_U12);

// Use the #[bitint_literals] attribute macro to write bitint literals anywhere
// inside an item. Here the item is a function, but it can also be useful on an
// impl block or inline module.
# demo();
#[bitint_literals]
fn demo() {
    let five = 5_U12;

    // Arithmetic ops accept Self or the primitive type and panic or wrap just
    // like primitive arithmetic ops.
    assert_eq!(five + five, 10_U12);
    assert_eq!(five - 1_U12, 4_U12);
    assert_eq!(five * 2_U12, 10_U12);
    assert_eq!(five / 3_U12, 1_U12);
    assert_eq!(five % 3_U12, 2_U12);
    // If built with overflow-checks = true, this would panic.
    // If built with overflow-checks = false, this would wrap.
    // five + U12::MAX

    // Checked arithmetic ops.
    assert_eq!(five.checked_add(10_U12), Some(15_U12));
    assert_eq!(five.checked_add(4095_U12), None);

    // Wrapping arithmetic ops.
    assert_eq!(five.wrapping_add(10_U12), 15_U12);
    assert_eq!(five.wrapping_add(4095_U12), 4_U12);

    // Zero-(extra)-cost unchecked arithmetic ops.
    #[cfg(feature = "unchecked_math")]
    {
        // SAFETY: 15 is in range for U12.
        assert_eq!(unsafe { five.unchecked_add(10_U12) }, 15_U12);
        // This would violate the safety condition and cause undefined behavior.
        // unsafe { five.unchecked_add(4095_U12) }
    }

    // Zero-cost conversion to a primitive type.
    assert_eq!(five.to_primitive(), 5);

    // Checked constructor.
    assert_eq!(U12::new(5), Some(five));
    assert_eq!(U12::new(4096), None);

    // Masking constructor.
    assert_eq!(U12::new_masked(5), five);
    assert_eq!(U12::new_masked(13 * 4096 + 5), five);

    // Zero-cost unsafe constructor.
    // SAFETY: 5 is in range for U12.
    assert_eq!(unsafe { U12::new_unchecked(5) }, five);
    // This would violate the safety condition and cause undefined behavior.
    // unsafe { U12::new_unchecked(65536) }

    // Zero-cost safe constructor, only for bitints that are the same width as a
    // primitive type.
    assert_eq!(U16::from_primitive(1234), 1234_U16);

    // String conversions.
    assert_eq!(format!("{five}"), "5");
    assert_eq!(five.to_string(), "5");
    assert_eq!("5".parse::<U12>().unwrap(), 5_U12);
};

Crate features

  • unchecked_math - Enables the unchecked_* methods on unsigned bitint types. Requires a nightly Rust compiler.

About

A Rust library for integer types that have a logical width measured in bits.

Resources

License

Stars

Watchers

Forks