# bitint [![crates.io][crates-badge]][crates-url] [![docs.rs][docs-badge]][docs-url] [![CI Status][ci-badge]][ci-url] [crates-badge]: https://img.shields.io/crates/v/bitint [crates-url]: https://crates.io/crates/bitint [docs-badge]: https://img.shields.io/docsrs/bitint [docs-url]: https://docs.rs/bitint [ci-badge]: https://img.shields.io/github/actions/workflow/status/mvanbem/bitint/ci.yml?branch=main&label=CI&logo=github [ci-url]: https://github.com/mvanbem/bitint/actions?query=workflow%3ACI+branch%3Amain A bit-integer library for Rust. `bitint`s 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 ```rust // 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::().unwrap(), 5_U12); }; ``` ## Crate features * **unchecked_math** - Enables the `unchecked_*` methods on unsigned `bitint` types. Requires a nightly Rust compiler.