bnum
Fixed-size integer types with generic signedness, bit width and overflow behaviour.
0.14.4
14M downloads/mo
#2635 most downloaded on crates.io
isaacholt100/bnum
What this package is like to depend on
Last release 5 months ago
24 Mar 2026
Release timing varies
gaps range from 8 days to 12 months
Some releases are documented
notes for 10 of 21 stable releases
Nothing withdrawn
no release was ever pulled
4 years old
21 releases · first in 2022
5 releases in the last 12 months
see the full history below
Release timeline
21 releases · Jul 2022 to Mar 2026Releases
latest 21-
0.14.424 Mar 2026Release notes
Open source →Fixes #72, also fixes a bug in the
quickcheck::Arbitraryandrand::Distributionandrand::Filltraits where the padding bits of integers with non-multiple-of-8 bit widths were not set properly. -
0.14.319 Mar 2026Release notes
Open source →Patch release: update the Cargo.toml description and fix display of code examples in the README.
-
0.14.218 Mar 2026Release notes
Open source →This implements the fix #68 which caused the crate tests to not compile when the "alloc" feature was disabled.
-
0.14.117 Mar 2026Release notes
Open source →This version fixes #65.
Auto-generated release notes:
What's Changed
- fix: borsh feature compile error by @larry0x in #66
- v0.14.1 patch by @isaacholt100 in #67
New Contributors
Full Changelog: v0.14.0...v0.14.1
-
0.14.016 Mar 2026Release notes
Open source →This release is by far the most significant upgrade of the crate so far, with a greatly simplified API, performance improvements, increased customisability, and new functionality.
Significant changes
From 8 integer types to a single unified integer type
The biggest change is that instead of there being 4 unsigned integer types (
BUint,BUintD32,BUintD16,BUintD8) and 4 signed integer types (BInt,BIntD32,BIntD16,BIntD8), there is now a single typeInteger, which has a const-generic parameterSof typebool, which controls whether the type behaves as an unsigned or signed integer.In previous versions of the crate, there was a separate integer type for each of the 4 allowed underlying digit types:
u8,u16,u32, andu64. The reason for this was that narrower digit types allowed for more fine-grained bit widths, while wider digit types meant faster performance. Thus, there was a trade-off between bit width customisability, and speed.Integeravoids this trade-off entirely by being stored as an array ofu8digits, but iterating over wider digits (by "chunking" togetheru8digits) during computations. The performance of a given method onIntegerhas been benchmarked with each possible choice of chunked digit (u8,u16,u32,u64,u128), and the digit giving the fastest implementation was chosen.The types
UintandIntare aliasesInteger, with the const-generic parameterSspecified to befalseandtruerespectively.Arbitrary bit widths
Integerhas another const-generic parameterBof typeusizeto specify the bit width of the integer as any integer between2and2^32 - 1; in previous versions, the bit width of the integer was inferred from the byte width, so had to be a multiple of8.const-generic overflow behaviour
The final const-generic parameter
Integercontrols its behaviour when arithmetic overflow occurs. There are 3 possible behaviours: wrap around, panic, or saturate. By default, the behaviour is wrapping if theoverflow-checksflag is disabled, and is panicking ifoverflow-checksis enabled.The full set of generic parameters of
Integer<S, N, B, OM>are the signednessS, the byte widthN, the bit widthB, and the overflow modeOM. For example:type A = Integer<true, 3, 23, 0>; // signed 23-bit integer with wrapping overflow behaviour type B = Integer<false, 20, 155, 2>; // unsigned 155-bit integer with saturating overflow behaviour
Easy construction of integer types and values
In previous versions, in order to construct integers from a specified list of digits, the
from_str_radixhad to be used, e.g.let a = U256::from_str_radix("abcdef", 16).unwrap()
There was no way of constructing integers from Rust integer literals at compile time. In this release, the
n!macro is introduced, which takes an integer literal, and returns an integer whose value corresponds to the literal, e.g.let a = n!(0xabcdef_U256);
Similarly to how integer literals are handled for the primitive integer types, if literal is specified without a suffix, then type inference is performed, e.g.
let b: I512 = n!(1234);
is valid. As in the case of primitive integers, if an invalid literal is encountered, then a compile error is triggered, e.g.
let a = n!(1a23_U24)
would cause a compile error. The one difference is that
let c = 0assigns a type ofi32tocby default, whereaslet c = n!(0)would result in a compile error (unlesscwas subsequently used in a way that type inference forccould be performed by the compiler).bnumnow also supports construction of specific integer types via thet!macro. Thet!macro takes a "type descriptor" which is an identifier encoding the specific values of the const-generic parameters ofInteger. For example, if you wanted a 155-bit signed integer which has wrapping behaviour on overflow, you would writet!(I155w), which outputsInteger<true, 20, 155, 0>.let a: t!(I155w) = n!(1234); fn add_one(int: t!(I155w)) -> t!(I155w) { int + n!(1) } let b = add_one(a);
The
n!andt!macros are both declarative, not procedural, so add minimal compile-time overhead and do not introduce any dependencies tobnum(which is still zero-dependency by default).All other changes
Major changes
- Remove the
Add<Digit>,Div<Digit>andRem<Digit>impls for unsigned integers (use theAdd<Self>,Div<Self>andRem<Self>impls instead). - Remove the
parse_str_radixmethod (usefrom_str_radix(...).unwrap(), or then!macro if appropriate). - The optional
randdependency is now version0.10of that crate. - Remove the
Slicestruct andtry_fill_slicefunction from the crate'srandommodule (these are superseded by the implementation of theFilltrait fromrand0.10). - Remove the
parse_bytesmethod (usefrom_ascii_radixinstead). - Remove
as_bits,as_bits_mutfrom signed integers (either useas_bytesoras_bytes_mutinstead, methods likeset_bitare now defined for signed integers as well as unsigned). - Remove numeric associated constants (e.g.
ZERO,TWO,NEG_ONE) from integers, as these values can now be easily constructed with then!macro. - Remove
{to,from}_{be,le}methods from integers, as not portable (and it didn't make sense to have them anyway asbnumintegers are always stored in little-endian byte order). - Remove
from_digitmethod from unsigned integers (use theAstrait instead). - Remove
{from,to}_radix_{be,le}from signed integers (only makes sense to have this for unsigned integers). - Remove the
CastFromtrait from the prelude. - Remove the
bitsmethod from signed integers and rename thebitsmethod on unsigned integers tobit_width, which now takesselfinstead of&self. - Remove
BTryFromtrait (use theTryFrom<&Integer> for Integer,TryFrom<Int> for UintorTryFrom<Uint> for Intimpls instead). - Change
From<primitive_int>impls toTryFrom<primitive_int>(use theAstrait instead for infallible conversions). - Remove
Fromconversions betweenUintand[u8; N].
Minor changes
- Add implementations of the
FromBytes,ToBytes,ConstZero,ConstOneandOverflowingMultraits from thenum_traitscrate. - The
unchecked_...methods are nowconst. - Put features requiring the
alloccrate behind anallocfeature, which allows for usage inno-allocenvironments. - The crate now uses the 2024 edition of Rust.
- The minimum supported Rust version (MSRV) is now
1.87.0. - Add
from_asciiandfrom_ascii_radixmethods. - Add
unchecked_negmethod to signed integers. - Add
checked_signed_diff,overflowing_sub_signed,wrapping_sub_signed,checked_sub_signed,saturating_sub_signedmethods to unsigned integers. - Add a
Debugimpl for integers when theallocfeature is disabled, which formats the integer as a padded hex string. - Add compile-time assertions to validate the bit width of integers (must be in the range
[2, 2^32). - Add
TryFrom<&Integer> for Integer,TryFrom<Int> for UintorTryFrom<Uint> for Intimpls. - Implement the
core::error::Errortrait forTryFromIntError,TryFromCharError, andParseIntError.
Patches
- Fix behaviour of the
is_multiple_ofmethod (previously, it incorrectly panicked ifrhswas zero). - Fix behaviour of
mod_flooranddiv_floormethods of thenum_integer::Integerimpl for signed integers. - Fix behaviour of the
wrapping_sh{l, r}andoverflowing_sh{l,r}methods when shift exceeds the bit width of the integer.
- Remove the
-
0.13.008 Mar 2025Release notes
Open source →This release adds support for some more traits from the
num_traitscrate, implements a few new methods, fixes three methods which were incorrectly did not panic, and allows testing on stable.Minor changes
- It is now possible to run bnum's unit tests on stable Rust. This was not possible before since the tests included those for methods whose counterparts on Rust's primitives are only available on nightly. The tests for such methods are now gated behind the
nightlycrate feature (and nightly Rust is still required to test these specific methods). - Added implementation of the
OverflowingAddandOverflowingSubtraits from thenum_traitscrate. - Added
unbounded_shlandunbounded_shrmethods to signed and unsigned integers. - Added
as_bitsandas_bits_mutto signed integers.
Patches
- In previous versions of bnum, the documentation for
to_str_radix,to_radix_beandto_radix_lestated that these methods panicked on invalid radices, where in fact this was not the case. As of this version, they now panic correctly on invalid radices (as per the documentation). - The
set_bitmethod on unsigned ints is now branchless.
Auto-generated release notes:
What's Changed
- Add OverflowingAdd and OverflowingSub impls by @kaidokert in #49
- Use branchless implementation for set_bit by @krakow10 in #51
- Add as_bits & as_bits_mut Methods To BInt by @krakow10 in #52
- Latest by @isaacholt100 in #53
New Contributors
- @kaidokert made their first contribution in #49
Full Changelog: v0.12.1...v0.13.0
- It is now possible to run bnum's unit tests on stable Rust. This was not possible before since the tests included those for methods whose counterparts on Rust's primitives are only available on nightly. The tests for such methods are now gated behind the
-
0.12.101 Jan 2025Release notes
Open source →This release fixes a few incorrect implementations of some methods.
Patches
- Fixed #47, by making
midpointround to zero for signed integers. - Changed the
Debugimplementation ofParseIntErrorto match that ofcore::num::ParseIntError. - Fixed the
lcmmethod onnum-integer::Integerfor signed integers (now always returns non-negative values) - Corrected more cases where a
PosOverflowerror is returned instead of anInvalidDigiterror when parsing integers (however there some edge cases wherePosOverflowshould be returned and now isn't, this will be fixed at some point).
Auto-generated release notes:
What's Changed
- Latest by @isaacholt100 in #48
Full Changelog: v0.12.0...v0.12.1
- Fixed #47, by making
-
0.12.020 Sep 2024Release notes
Open source →This release introduces a number of new methods, as well as support for the
borshcrate.Major Changes
- The latest nightly compiler (
1.83.0) does not support user-definedconsttraits, and so thenightlycrate feature no longer makes theCastFromandAstraitsconst. This means the implementations of these traits on bnum integers are no longerconsteither.
Minor Changes
- Added (optional) support for the
borshcrate (this enables serialisation and deserialisation using this crate). - Added
digits_mutandset_bitmethods to unsigned integers, allowing for manipulation without copying the value. - Added
cast_signedmethod for unsigned integers andcast_unsignedmethod for signed integers. - Added
midpointmethod for all integers. - Added
carrying_addandborrowing_submethods for signed integers. - Added
strict_...arithmetic methods for all integers.
Patches
- Added
(bnum)prefix to panic messages that mistakenly did not include it.
Auto-generated release notes:
What's Changed
- feat(serde): borsh by @dzmitry-lahoda in #42
- add digits_mut to buint by @krakow10 in #45
- add set_bit to buint by @krakow10 in #44
- Latest by @isaacholt100 in #46
New Contributors
- @dzmitry-lahoda made their first contribution in #42
- @krakow10 made their first contribution in #45
Full Changelog: v0.11.0...v0.12.0
- The latest nightly compiler (
-
0.11.006 Mar 2024Release notes
Open source →This release fixes #39, and makes all
ilog*methods panic with the same message as Rust's primitive integers (with the(bnum)prefix, as for other bnum panic messages).Major Changes
ilog*methods now panic for invalid inputs in release mode as well as debug mode.
Patches
ilog*panic messages now match that of Rust's primitives.
What's Changed
- Latest by @isaacholt100 in #40
Full Changelog: v0.10.0...v0.11.0
-
0.10.023 Nov 2023Nothing published for this version
-
0.9.125 Oct 2023Nothing published for this version
-
0.9.028 Sep 2023Nothing published for this version
-
0.8.124 Nov 2023Release notes
Open source →This release fixes #36. For more info, see the release notes for
v0.10.0. -
0.8.023 Jul 2023Nothing published for this version
-
0.7.028 May 2023Nothing published for this version
-
0.6.007 Mar 2023Nothing published for this version
-
0.5.002 Jan 2023Nothing published for this version
-
0.4.024 Dec 2022Nothing published for this version
-
0.3.011 Sep 2022Nothing published for this version
-
0.2.009 Aug 2022Nothing published for this version
-
0.1.010 Jul 2022Nothing published for this version