#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(feature = "experimental-floats", feature(f16, f128))]
#![allow(
// Decimal width names overlap with type prefixes; the lint adds no
// signal here.
clippy::module_name_repetitions,
// We use unindented Markdown continuation in module docs.
clippy::doc_lazy_continuation,
// We routinely place a blank line between a method's `#[cfg]`
// attribute and its doc/body for readability.
clippy::empty_line_after_outer_attr,
// Big-integer arithmetic regularly casts between signed/unsigned
// and between widths. The wraps / truncations / sign flips are
// intentional — `unsigned_abs` paths, two's-complement tricks,
// narrowing the final result back to storage after a widened mul.
clippy::cast_possible_truncation,
clippy::cast_possible_wrap,
clippy::cast_sign_loss,
// We prefer `as` casts over `T::from(x)` in arithmetic-heavy
// inner loops for readability and to match the surrounding
// big-integer idiom.
clippy::cast_lossless,
// Float bridges (`to_f64`, `to_f32`) are explicitly lossy by
// contract. The lint is a tautology here.
clippy::cast_precision_loss,
// Literals like `1_000_000_000_000` carry the scale visually and
// are kept unseparated when they encode `10^SCALE`.
clippy::unreadable_literal,
// `if cond { panic!(…) }` is the crate's canonical bounds-check
// shape; `assert!(…)` would lose the dynamic message.
clippy::manual_assert,
// `Result<_, ()>` is the only honest error type for `const fn`
// digit-validity checks where no allocator is available.
clippy::result_unit_err,
// `if …; if …` chains read more cleanly than `if … && …` in the
// const-fn limb-arithmetic helpers.
clippy::collapsible_if,
// Big-int / fixed-point inner loops use `i`, `j`, `k`, `n`, `m`
// as conventional names. Renaming to `outer_index` etc. hurts
// readability without payoff.
clippy::similar_names,
clippy::many_single_char_names,
// Strict-transcendental kernels exceed 100 lines because they
// unroll a series-evaluation loop; splitting them just to please
// the line-count lint would scatter the algorithm.
clippy::too_many_lines,
// `#[inline(always)]` is set deliberately on small hot-path
clippy::inline_always,
clippy::float_cmp,
clippy::manual_let_else,
clippy::format_push_string,
clippy::comparison_chain,
clippy::must_use_candidate,
clippy::return_self_not_must_use,
clippy::missing_errors_doc,
clippy::missing_panics_doc,
clippy::doc_markdown,
)]
#[cfg(feature = "alloc")]
extern crate alloc;
mod arithmetic;
#[cfg(feature = "bench-alt")]
mod bench_alt;
#[cfg(feature = "bench-alt")]
#[doc(hidden)]
pub mod __bench_internals {
#[inline(never)]
pub fn limbs_mul(a: &[u128], b: &[u128], out: &mut [u128]) {
crate::wide_int::limbs_mul(a, b, out)
}
#[inline(never)]
pub fn limbs_mul_fast(a: &[u128], b: &[u128], out: &mut [u128]) {
crate::wide_int::limbs_mul_fast(a, b, out)
}
}
mod consts;
mod consts_wide;
mod core_type;
mod decimal_trait;
mod display;
mod equalities;
mod error;
mod macros;
mod num_traits;
mod log_exp_strict;
mod log_exp_fast;
mod rescale;
mod rounding;
mod mg_divide;
mod d_w128_kernels;
mod wide_int;
mod overflow_variants;
mod powers_strict;
mod powers_fast;
#[cfg(feature = "serde")]
pub mod serde_helpers;
#[cfg(any(not(feature = "fast"), feature = "std"))]
mod trig_strict;
mod trig_fast;
pub use consts::DecimalConsts;
pub use decimal_trait::Decimal;
pub use error::{ConvertError, ParseError};
pub use rounding::RoundingMode;
pub use core_type::{
D38, D38s0, D38s1, D38s2, D38s3, D38s4, D38s5, D38s6, D38s7, D38s8, D38s9, D38s10,
D38s11, D38s12, D38s13, D38s14, D38s15, D38s16, D38s17, D38s18, D38s19, D38s20,
D38s21, D38s22, D38s23, D38s24, D38s25, D38s26, D38s27, D38s28, D38s29, D38s30,
D38s31, D38s32, D38s33, D38s34, D38s35, D38s36, D38s37, D38s38,
};
pub use core_type::{
D9, D9s0, D9s1, D9s2, D9s3, D9s4, D9s5, D9s6, D9s7, D9s8, D9s9,
};
pub use core_type::{
D18, D18s0, D18s1, D18s2, D18s3, D18s4, D18s5, D18s6, D18s7, D18s8, D18s9, D18s10, D18s11,
D18s12, D18s13, D18s14, D18s15, D18s16, D18s17, D18s18,
};
#[cfg(any(feature = "d76", feature = "wide"))]
pub use core_type::{
D76, D76s0, D76s2, D76s6, D76s12, D76s18, D76s35, D76s50, D76s76,
};
#[cfg(any(feature = "d76", feature = "d153", feature = "d307", feature = "wide"))]
pub use wide_int::{
Int256, Int512, Int1024, Int2048, Int4096, Uint256, Uint512, Uint1024, Uint2048, Uint4096,
};
#[cfg(any(feature = "d153", feature = "wide"))]
pub use core_type::{D153, D153s0, D153s35, D153s75, D153s150, D153s153};
#[cfg(any(feature = "d307", feature = "wide"))]
pub use core_type::{D307, D307s0, D307s35, D307s150, D307s300, D307s307};
#[cfg(any(feature = "d56", feature = "wide"))]
pub use core_type::{
D56,
D56s0, D56s2, D56s4, D56s6, D56s9, D56s12, D56s18, D56s24,
D56s28, D56s32, D56s38, D56s42, D56s48, D56s52, D56s56, D56s57,
};
#[cfg(any(feature = "d56", feature = "wide"))]
pub use wide_int::{Int192, Uint192};
#[cfg(any(feature = "d114", feature = "wide"))]
pub use core_type::{
D114,
D114s0, D114s4, D114s8, D114s16, D114s24, D114s32, D114s38, D114s50,
D114s57, D114s64, D114s76, D114s90, D114s100, D114s110, D114s114, D114s115,
};
#[cfg(any(feature = "d114", feature = "wide"))]
pub use wide_int::{Int384, Uint384};
#[cfg(any(feature = "d230", feature = "wide"))]
pub use core_type::{
D230,
D230s0, D230s6, D230s18, D230s38, D230s57, D230s75, D230s100, D230s115,
D230s140, D230s153, D230s175, D230s200, D230s215, D230s225, D230s229, D230s230,
};
#[cfg(any(feature = "d230", feature = "wide"))]
pub use wide_int::{Int768, Uint768};
#[cfg(any(feature = "d461", feature = "x-wide"))]
pub use core_type::{
D461,
D461s0, D461s18, D461s38, D461s75, D461s115, D461s153, D461s200, D461s230,
D461s275, D461s307, D461s350, D461s400, D461s440, D461s460, D461s461, D461s462,
};
#[cfg(any(feature = "d461", feature = "x-wide"))]
pub use wide_int::{Int1536, Uint1536};
#[cfg(any(feature = "d615", feature = "x-wide"))]
pub use core_type::{
D615,
D615s0, D615s38, D615s75, D615s115, D615s153, D615s200, D615s230, D615s275,
D615s308, D615s380, D615s462, D615s500, D615s555, D615s600, D615s615, D615s616,
};
#[cfg(any(feature = "d923", feature = "xx-wide"))]
pub use core_type::{
D923,
D923s0, D923s75, D923s153, D923s230, D923s307, D923s400, D923s461, D923s462,
D923s500, D923s616, D923s700, D923s800, D923s860, D923s900, D923s920, D923s923, D923s924,
};
#[cfg(any(feature = "d923", feature = "xx-wide"))]
pub use wide_int::{Int3072, Int6144, Int12288, Uint3072, Uint6144, Uint12288};
#[cfg(any(feature = "d1231", feature = "xx-wide"))]
pub use core_type::{
D1231,
D1231s0, D1231s75, D1231s153, D1231s230, D1231s307, D1231s461, D1231s616,
D1231s700, D1231s800, D1231s900, D1231s924, D1231s1000, D1231s1100,
D1231s1180, D1231s1220, D1231s1230, D1231s1231, D1231s1232,
};
#[cfg(any(feature = "d1231", feature = "xx-wide"))]
pub use wide_int::{Int8192, Int16384, Uint8192, Uint16384};
#[cfg(feature = "macros")]
pub use decimal_scaled_macros::{d9, d18, d38};
#[cfg(all(feature = "macros", any(feature = "d76", feature = "wide")))]
pub use decimal_scaled_macros::d76;
#[cfg(all(feature = "macros", any(feature = "d153", feature = "wide")))]
pub use decimal_scaled_macros::d153;
#[cfg(all(feature = "macros", any(feature = "d307", feature = "wide", feature = "x-wide")))]
pub use decimal_scaled_macros::d307;
#[cfg(feature = "macros")] #[macro_export]
macro_rules! d9s0 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d9!($v, scale 0 $(, $($rest)*)?) }; }
#[cfg(feature = "macros")] #[macro_export]
macro_rules! d9s2 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d9!($v, scale 2 $(, $($rest)*)?) }; }
#[cfg(feature = "macros")] #[macro_export]
macro_rules! d9s4 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d9!($v, scale 4 $(, $($rest)*)?) }; }
#[cfg(feature = "macros")] #[macro_export]
macro_rules! d9s6 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d9!($v, scale 6 $(, $($rest)*)?) }; }
#[cfg(feature = "macros")] #[macro_export]
macro_rules! d9s9 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d9!($v, scale 9 $(, $($rest)*)?) }; }
#[cfg(feature = "macros")] #[macro_export]
macro_rules! d18s0 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d18!($v, scale 0 $(, $($rest)*)?) }; }
#[cfg(feature = "macros")] #[macro_export]
macro_rules! d18s2 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d18!($v, scale 2 $(, $($rest)*)?) }; }
#[cfg(feature = "macros")] #[macro_export]
macro_rules! d18s4 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d18!($v, scale 4 $(, $($rest)*)?) }; }
#[cfg(feature = "macros")] #[macro_export]
macro_rules! d18s6 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d18!($v, scale 6 $(, $($rest)*)?) }; }
#[cfg(feature = "macros")] #[macro_export]
macro_rules! d18s9 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d18!($v, scale 9 $(, $($rest)*)?) }; }
#[cfg(feature = "macros")] #[macro_export]
macro_rules! d18s12 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d18!($v, scale 12 $(, $($rest)*)?) }; }
#[cfg(feature = "macros")] #[macro_export]
macro_rules! d18s18 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d18!($v, scale 18 $(, $($rest)*)?) }; }
#[cfg(feature = "macros")] #[macro_export]
macro_rules! d38s0 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d38!($v, scale 0 $(, $($rest)*)?) }; }
#[cfg(feature = "macros")] #[macro_export]
macro_rules! d38s2 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d38!($v, scale 2 $(, $($rest)*)?) }; }
#[cfg(feature = "macros")] #[macro_export]
macro_rules! d38s4 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d38!($v, scale 4 $(, $($rest)*)?) }; }
#[cfg(feature = "macros")] #[macro_export]
macro_rules! d38s6 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d38!($v, scale 6 $(, $($rest)*)?) }; }
#[cfg(feature = "macros")] #[macro_export]
macro_rules! d38s8 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d38!($v, scale 8 $(, $($rest)*)?) }; }
#[cfg(feature = "macros")] #[macro_export]
macro_rules! d38s9 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d38!($v, scale 9 $(, $($rest)*)?) }; }
#[cfg(feature = "macros")] #[macro_export]
macro_rules! d38s12 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d38!($v, scale 12 $(, $($rest)*)?) }; }
#[cfg(feature = "macros")] #[macro_export]
macro_rules! d38s15 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d38!($v, scale 15 $(, $($rest)*)?) }; }
#[cfg(feature = "macros")] #[macro_export]
macro_rules! d38s18 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d38!($v, scale 18 $(, $($rest)*)?) }; }
#[cfg(feature = "macros")] #[macro_export]
macro_rules! d38s24 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d38!($v, scale 24 $(, $($rest)*)?) }; }
#[cfg(feature = "macros")] #[macro_export]
macro_rules! d38s35 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d38!($v, scale 35 $(, $($rest)*)?) }; }
#[cfg(feature = "macros")] #[macro_export]
macro_rules! d38s38 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d38!($v, scale 38 $(, $($rest)*)?) }; }
#[cfg(all(feature = "macros", any(feature = "d76", feature = "wide")))] #[macro_export]
macro_rules! d76s0 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d76!($v, scale 0 $(, $($rest)*)?) }; }
#[cfg(all(feature = "macros", any(feature = "d76", feature = "wide")))] #[macro_export]
macro_rules! d76s2 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d76!($v, scale 2 $(, $($rest)*)?) }; }
#[cfg(all(feature = "macros", any(feature = "d76", feature = "wide")))] #[macro_export]
macro_rules! d76s6 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d76!($v, scale 6 $(, $($rest)*)?) }; }
#[cfg(all(feature = "macros", any(feature = "d76", feature = "wide")))] #[macro_export]
macro_rules! d76s12 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d76!($v, scale 12 $(, $($rest)*)?) }; }
#[cfg(all(feature = "macros", any(feature = "d76", feature = "wide")))] #[macro_export]
macro_rules! d76s18 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d76!($v, scale 18 $(, $($rest)*)?) }; }
#[cfg(all(feature = "macros", any(feature = "d76", feature = "wide")))] #[macro_export]
macro_rules! d76s35 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d76!($v, scale 35 $(, $($rest)*)?) }; }
#[cfg(all(feature = "macros", any(feature = "d76", feature = "wide")))] #[macro_export]
macro_rules! d76s50 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d76!($v, scale 50 $(, $($rest)*)?) }; }
#[cfg(all(feature = "macros", any(feature = "d76", feature = "wide")))] #[macro_export]
macro_rules! d76s76 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d76!($v, scale 76 $(, $($rest)*)?) }; }
#[cfg(all(feature = "macros", any(feature = "d153", feature = "wide")))] #[macro_export]
macro_rules! d153s0 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d153!($v, scale 0 $(, $($rest)*)?) }; }
#[cfg(all(feature = "macros", any(feature = "d153", feature = "wide")))] #[macro_export]
macro_rules! d153s35 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d153!($v, scale 35 $(, $($rest)*)?) }; }
#[cfg(all(feature = "macros", any(feature = "d153", feature = "wide")))] #[macro_export]
macro_rules! d153s75 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d153!($v, scale 75 $(, $($rest)*)?) }; }
#[cfg(all(feature = "macros", any(feature = "d153", feature = "wide")))] #[macro_export]
macro_rules! d153s150 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d153!($v, scale 150 $(, $($rest)*)?) }; }
#[cfg(all(feature = "macros", any(feature = "d153", feature = "wide")))] #[macro_export]
macro_rules! d153s153 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d153!($v, scale 153 $(, $($rest)*)?) }; }
#[cfg(all(feature = "macros", any(feature = "d307", feature = "wide", feature = "x-wide")))] #[macro_export]
macro_rules! d307s0 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d307!($v, scale 0 $(, $($rest)*)?) }; }
#[cfg(all(feature = "macros", any(feature = "d307", feature = "wide", feature = "x-wide")))] #[macro_export]
macro_rules! d307s35 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d307!($v, scale 35 $(, $($rest)*)?) }; }
#[cfg(all(feature = "macros", any(feature = "d307", feature = "wide", feature = "x-wide")))] #[macro_export]
macro_rules! d307s150 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d307!($v, scale 150 $(, $($rest)*)?) }; }
#[cfg(all(feature = "macros", any(feature = "d307", feature = "wide", feature = "x-wide")))] #[macro_export]
macro_rules! d307s300 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d307!($v, scale 300 $(, $($rest)*)?) }; }
#[cfg(all(feature = "macros", any(feature = "d307", feature = "wide", feature = "x-wide")))] #[macro_export]
macro_rules! d307s307 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d307!($v, scale 307 $(, $($rest)*)?) }; }