1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
//! This crate defines specification-friendly natural integers with an upper bound. Operations on
//! these integers can be defined as modular (modulo the upper bound) or regular (with a panic
//! on underflow or overflow).
//!
//! As each integer gets its own Rust type, the compiler detects and prevent any mixing between
//! all the diffent integers you would have defined.
//!
//! # Defining a new integer type
//!
//! Here is the macro used to defined the `SizeNatExample` type of this crate:
//!
//! ```ignore
//! define_abstract_integer_checked!(SizeNatExample, 64);
//! ```
//!
//! `SizeNat` is the name of the newly-created type. `64` is the number of bits of the machine
//! representation of the type. From the number of bits is derived an upper bound for the integer
//! for which all operations are checked for overflow.
//!
//! The resulting integer type is copyable, and supports addition, substraction, multiplication,
//! integer division, remainder, comparison and equality. The `from_literal` method allows you to
//! convert integer literals into your new type.
//!
//! # Refining an integer type for modular arithmetic
//!
//! On top of a previously defined abstract integer, you can define another type that lets you
//! implement modular arithmetic. For instance, this crate defines the arithmetic field over the
//! 9th Mersenne prime with:
//!
//! ```ignore
//! define_refined_modular_integer!(
//! SizeNatFieldExample,
//! SizeNatExample,
//! SizeNatExample::pow2(61) - SizeNatExample::from_literal(1)
//! );
//! ```
//!
//! The first argument of this new macro is the name of the newly defined refined type. The second
//! argument is the name of the base abstract integer that will act as the representation. The
//! third example is the modulo for all operations, defined as a value of the base type.
//!
//!
//! # Example
//!
//! ```
//! use abstract_integers::*;
//!
//! abstract_public_nat_mod!(SizeNatFieldExample, SizeNatExample, 64, "1fffffffffffffff");
//!
//! let x1 = SizeNatExample::from_literal(687165654266415);
//! let x2 = SizeNatExample::from_literal(4298832000156);
//! let x3 = x1 + x2;
//! assert_eq!(SizeNatExample::from_literal(691464486266571), x3);
//! let x4 = SizeNatExample::from_literal(8151084996540);
//! let x5 = x3 - x4;
//! assert_eq!(SizeNatExample::from_literal(683313401270031), x5.into());
//! let x6 = x5 / SizeNatExample::from_literal(1541654268);
//! assert_eq!(SizeNatExample::from_literal(443233), x6.into());
//! let x7 : SizeNatFieldExample = SizeNatFieldExample::from_literal(2305843009213693951) + x6.into();
//! assert_eq!(x7, x6.into());
//! ```
//!
#![cfg_attr(not(feature = "std"), no_std)]
// Re-exports
pub use core::cmp::Ordering;
pub use core::num::ParseIntError;
pub use core::ops::*;
pub use num::{traits, traits::identities::*, CheckedSub, Zero};
pub use num_bigint::{BigInt, BigUint, Sign};
pub mod abstract_int;
pub mod nat_mod;