Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
strategy:
matrix:
rust: [
1.90.0, # MSRV
1.91.0, # MSRV
stable,
beta,
nightly,
Expand Down Expand Up @@ -52,7 +52,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@1.90.0
- uses: dtolnay/rust-toolchain@1.91.0
with:
components: rustfmt
- run: cargo fmt --all --check
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
[package]
name = "num-primitive"
version = "0.3.1"
version = "0.3.2"
description = "Traits for primitive numeric types"
repository = "https://github.com/rust-num/num-primitive"
license = "MIT OR Apache-2.0"
keywords = ["generic", "mathematics", "numerics", "primitive"]
categories = ["algorithms", "science", "no-std"]
edition = "2024"
rust-version = "1.90"
rust-version = "1.91"

[features]
default = ["std"]
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![crate](https://img.shields.io/crates/v/num-primitive.svg)](https://crates.io/crates/num-primitive)
[![documentation](https://docs.rs/num-primitive/badge.svg)](https://docs.rs/num-primitive)
[![minimum rustc 1.90](https://img.shields.io/badge/rustc-1.90+-red.svg)](https://rust-lang.github.io/rfcs/2495-min-rust-version.html)
[![minimum rustc 1.91](https://img.shields.io/badge/rustc-1.91+-red.svg)](https://rust-lang.github.io/rfcs/2495-min-rust-version.html)
[![build status](https://github.com/rust-num/num-primitive/workflows/CI/badge.svg)](https://github.com/rust-num/num-primitive/actions)

Traits for primitive numeric types in Rust.
Expand Down Expand Up @@ -61,7 +61,7 @@ Release notes are available in [RELEASES.md](RELEASES.md).

## Compatibility

The `num-primitive` crate is currently tested for Rust 1.90 and greater. This
The `num-primitive` crate is currently tested for Rust 1.91 and greater. This
minimum-supported Rust version (MSRV) may be increased at any time to add
support for newly-stabilized functionality from the standard library. Changes
will be documented prominently in the release notes.
Expand Down
8 changes: 8 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# Release 0.3.2 (2025-12-16)

- Updated to MSRV 1.91.
- Added `PrimitiveInteger::strict_{add,div,{div,rem}_euclid,mul,neg,pow,rem,shl,shr,sub}`
- Added `PrimitiveSigned::strict_{abs,{add,sub}_unsigned}`
- Added `PrimitiveUnsigned::strict_{abs,{add,sub}_signed}`
- Added `PrimitiveUnsigned::{borrowing_sub,carrying_{add,mul,mul_add},checked_signed_diff}`

# Release 0.3.1 (2025-12-16)

- Updated to MSRV 1.90.
Expand Down
52 changes: 51 additions & 1 deletion src/integer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,8 @@ pub trait PrimitiveInteger:
/// occurred.
fn checked_mul(self, rhs: Self) -> Option<Self>;

/// Checked negation. Computes -self, returning `None` if `self == MIN`.
/// Checked negation. Computes -self, returning `None` if `self == MIN` for signed integers,
/// or for any non-zero unsigned integer.
fn checked_neg(self) -> Option<Self>;

/// Checked exponentiation. Computes `self.pow(exp)`, returning `None` if overflow occurred.
Expand Down Expand Up @@ -367,6 +368,44 @@ pub trait PrimitiveInteger:
/// instead of overflowing.
fn saturating_sub(self, rhs: Self) -> Self;

/// Strict integer addition. Computes `self + rhs`, panicking if overflow occurred.
fn strict_add(self, rhs: Self) -> Self;

/// Strict integer division. Computes `self / rhs`, panicking if overflow occurred.
fn strict_div(self, rhs: Self) -> Self;

/// Strict Euclidean division. Computes `self.div_euclid(rhs)`, panicking if overflow occurred.
fn strict_div_euclid(self, rhs: Self) -> Self;

/// Strict integer multiplication. Computes `self * rhs`, panicking if overflow occurred.
fn strict_mul(self, rhs: Self) -> Self;

/// Strict negation. Computes `-self`, panicking if `self == MIN` for signed integers,
/// or for any non-zero unsigned integer.
fn strict_neg(self) -> Self;

/// Strict exponentiation. Computes `self.pow(exp)`, panicking if overflow occurred.
fn strict_pow(self, exp: u32) -> Self;

/// Strict integer remainder. Computes `self % rhs`, panicking if
/// the division results in overflow.
fn strict_rem(self, rhs: Self) -> Self;

/// Strict Euclidean remainder. Computes `self.rem_euclid(rhs)`, panicking if
/// the division results in overflow.
fn strict_rem_euclid(self, rhs: Self) -> Self;

/// Strict shift left. Computes `self << rhs`, panicking if `rhs` is larger
/// than or equal to the number of bits in `self`.
fn strict_shl(self, rhs: u32) -> Self;

/// Strict shift right. Computes `self >> rhs`, panicking if `rhs` is
/// larger than or equal to the number of bits in `self`.
fn strict_shr(self, rhs: u32) -> Self;

/// Strict integer subtraction. Computes `self - rhs`, panicking if overflow occurred.
fn strict_sub(self, rhs: Self) -> Self;

/// Reverses the byte order of the integer.
fn swap_bytes(self) -> Self;

Expand Down Expand Up @@ -589,6 +628,17 @@ macro_rules! impl_integer {
fn saturating_mul(self, rhs: Self) -> Self;
fn saturating_pow(self, exp: u32) -> Self;
fn saturating_sub(self, rhs: Self) -> Self;
fn strict_add(self, rhs: Self) -> Self;
fn strict_div(self, rhs: Self) -> Self;
fn strict_div_euclid(self, rhs: Self) -> Self;
fn strict_mul(self, rhs: Self) -> Self;
fn strict_neg(self) -> Self;
fn strict_pow(self, exp: u32) -> Self;
fn strict_rem(self, rhs: Self) -> Self;
fn strict_rem_euclid(self, rhs: Self) -> Self;
fn strict_shl(self, rhs: u32) -> Self;
fn strict_shr(self, rhs: u32) -> Self;
fn strict_sub(self, rhs: Self) -> Self;
fn swap_bytes(self) -> Self;
fn to_be(self) -> Self;
fn to_le(self) -> Self;
Expand Down
14 changes: 14 additions & 0 deletions src/signed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,17 @@ pub trait PrimitiveSigned: PrimitiveInteger + From<i8> + core::ops::Neg<Output =
/// Returns a number representing sign of `self`.
fn signum(self) -> Self;

/// Strict absolute value. Computes `self.abs()`, panicking if `self == MIN`.
fn strict_abs(self) -> Self;

/// Strict addition with an unsigned integer. Computes `self + rhs`,
/// panicking if overflow occurred.
fn strict_add_unsigned(self, rhs: Self::Unsigned) -> Self;

/// Strict subtraction with an unsigned integer. Computes `self - rhs`,
/// panicking if overflow occurred.
fn strict_sub_unsigned(self, rhs: Self::Unsigned) -> Self;

/// Computes the absolute value of `self` without any wrapping or panicking.
fn unsigned_abs(self) -> Self::Unsigned;

Expand Down Expand Up @@ -159,6 +170,9 @@ macro_rules! impl_signed {
fn saturating_neg(self) -> Self;
fn saturating_sub_unsigned(self, rhs: Self::Unsigned) -> Self;
fn signum(self) -> Self;
fn strict_abs(self) -> Self;
fn strict_add_unsigned(self, rhs: Self::Unsigned) -> Self;
fn strict_sub_unsigned(self, rhs: Self::Unsigned) -> Self;
fn unsigned_abs(self) -> Self::Unsigned;
fn wrapping_abs(self) -> Self;
fn wrapping_add_unsigned(self, rhs: Self::Unsigned) -> Self;
Expand Down
34 changes: 34 additions & 0 deletions src/unsigned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,21 @@ pub trait PrimitiveUnsigned: PrimitiveInteger + From<u8> {
/// Computes the absolute difference between `self` and `other`.
fn abs_diff(self, other: Self) -> Self;

/// Calculates `self` &minus; `rhs` &minus; `borrow` and returns a tuple
/// containing the difference and the output borrow.
fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool);

/// Calculates `self` + `rhs` + `carry` and returns a tuple containing
/// the sum and the output carry (in that order).
fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool);

/// Calculates the "full multiplication" `self * rhs + carry`
/// without the possibility to overflow.
fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self);

/// Calculates the "full multiplication" `self * rhs + carry + add`.
fn carrying_mul_add(self, rhs: Self, carry: Self, add: Self) -> (Self, Self);

/// Returns the bit pattern of `self` reinterpreted as a signed integer of the same size.
fn cast_signed(self) -> Self::Signed;

Expand All @@ -56,6 +71,10 @@ pub trait PrimitiveUnsigned: PrimitiveInteger + From<u8> {
/// wrapped in Some.
fn checked_next_power_of_two(self) -> Option<Self>;

/// Checked integer subtraction. Computes `self - rhs` and checks if the result fits into a
/// signed integer of the same size, returning `None` if overflow occurred.
fn checked_signed_diff(self, rhs: Self) -> Option<Self::Signed>;

/// Checked subtraction with a signed integer. Computes `self - rhs`,
/// returning `None` if overflow occurred.
fn checked_sub_signed(self, rhs: Self::Signed) -> Option<Self>;
Expand Down Expand Up @@ -91,6 +110,14 @@ pub trait PrimitiveUnsigned: PrimitiveInteger + From<u8> {
/// the numeric bounds instead of overflowing.
fn saturating_sub_signed(self, rhs: Self::Signed) -> Self;

/// Strict addition with a signed integer. Computes `self + rhs`,
/// panicking if overflow occurred.
fn strict_add_signed(self, rhs: Self::Signed) -> Self;

/// Strict subtraction with a signed integer. Computes `self - rhs`,
/// panicking if overflow occurred.
fn strict_sub_signed(self, rhs: Self::Signed) -> Self;

/// Wrapping (modular) addition with a signed integer. Computes `self + rhs`, wrapping around
/// at the boundary of the type.
fn wrapping_add_signed(self, rhs: Self::Signed) -> Self;
Expand All @@ -113,10 +140,15 @@ macro_rules! impl_unsigned {

forward! {
fn abs_diff(self, other: Self) -> Self;
fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool);
fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool);
fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self);
fn carrying_mul_add(self, rhs: Self, carry: Self, add: Self) -> (Self, Self);
fn cast_signed(self) -> Self::Signed;
fn checked_add_signed(self, rhs: Self::Signed) -> Option<Self>;
fn checked_next_multiple_of(self, rhs: Self) -> Option<Self>;
fn checked_next_power_of_two(self) -> Option<Self>;
fn checked_signed_diff(self, rhs: Self) -> Option<Self::Signed>;
fn checked_sub_signed(self, rhs: Self::Signed) -> Option<Self>;
fn div_ceil(self, rhs: Self) -> Self;
fn is_multiple_of(self, rhs: Self) -> bool;
Expand All @@ -127,6 +159,8 @@ macro_rules! impl_unsigned {
fn overflowing_sub_signed(self, rhs: Self::Signed) -> (Self, bool);
fn saturating_add_signed(self, rhs: Self::Signed) -> Self;
fn saturating_sub_signed(self, rhs: Self::Signed) -> Self;
fn strict_add_signed(self, rhs: Self::Signed) -> Self;
fn strict_sub_signed(self, rhs: Self::Signed) -> Self;
fn wrapping_add_signed(self, rhs: Self::Signed) -> Self;
fn wrapping_sub_signed(self, rhs: Self::Signed) -> Self;
}
Expand Down