1#![cfg_attr(not(feature = "std"), no_std)]
91#![cfg_attr(feature = "experimental-floats", feature(f16, f128))]
92#![cfg_attr(feature = "cross-scale-ops", feature(generic_const_exprs))]
93#![cfg_attr(feature = "cross-scale-ops", allow(incomplete_features))]
94#![allow(
101 clippy::module_name_repetitions,
104 clippy::doc_lazy_continuation,
106 clippy::empty_line_after_outer_attr,
109 clippy::cast_possible_truncation,
114 clippy::cast_possible_wrap,
115 clippy::cast_sign_loss,
116 clippy::cast_lossless,
120 clippy::cast_precision_loss,
123 clippy::unreadable_literal,
126 clippy::manual_assert,
129 clippy::result_unit_err,
132 clippy::collapsible_if,
135 clippy::similar_names,
139 clippy::many_single_char_names,
140 clippy::too_many_lines,
144 clippy::inline_always,
148 clippy::float_cmp,
152 clippy::manual_let_else,
156 clippy::format_push_string,
158 clippy::comparison_chain,
161 clippy::must_use_candidate,
165 clippy::return_self_not_must_use,
166 clippy::missing_errors_doc,
172 clippy::missing_panics_doc,
173 clippy::doc_markdown,
177)]
178
179#[cfg(feature = "alloc")]
180extern crate alloc;
181
182#[cfg(feature = "perf-trace")]
186#[doc(hidden)]
187pub use ::tracing;
188
189mod algos;
190mod identity;
191mod support;
192mod types;
193#[cfg(feature = "bench-alt")]
194#[doc(hidden)]
195pub mod __bench_internals {
196 #[inline(never)]
197 pub fn limbs_mul(a: &[u128], b: &[u128], out: &mut [u128]) {
198 crate::wide_int::limbs_mul(a, b, out)
199 }
200 #[inline(never)]
201 pub fn limbs_mul_fast(a: &[u128], b: &[u128], out: &mut [u128]) {
202 crate::wide_int::limbs_mul_fast(a, b, out)
203 }
204 #[inline(never)]
205 pub fn mul_slice(a: &[u64], b: &[u64], out: &mut [u64]) {
206 crate::wide_int::limbs_mul_u64(a, b, out)
207 }
208 #[inline(never)]
209 pub fn mul_fixed<const L: usize, const D: usize>(
210 a: &[u64; L],
211 b: &[u64; L],
212 out: &mut [u64; D],
213 ) {
214 crate::wide_int::limbs_mul_u64_fixed::<L, D>(a, b, out)
215 }
216 #[inline(never)]
217 pub fn mul_u64_into<const L: usize, const LP1: usize>(
218 a: &[u64; L],
219 n: u64,
220 out: &mut [u64; LP1],
221 ) {
222 crate::wide_int::limbs_mul_u64_into::<L, LP1>(a, n, out)
223 }
224
225 #[cfg(any(feature = "x-wide", feature = "xx-wide"))]
230 pub mod newton_vs_mg {
231 use crate::algos::newton_reciprocal::NewtonReciprocal as NR;
232 pub struct NewtonReciprocal(pub(crate) NR);
233 impl NewtonReciprocal {
234 #[inline(never)]
235 pub fn precompute(scale: u32, width_limbs: usize) -> Self {
236 Self(NR::precompute(scale, width_limbs))
237 }
238 }
239
240 macro_rules! shim {
241 ($pub_name:ident, $width:ty, $feat:literal) => {
242 #[cfg(any(feature = $feat))]
243 pub mod $pub_name {
244 use super::NewtonReciprocal;
245 use crate::RoundingMode;
246 use $width as W;
247
248 #[derive(Clone, Copy)]
250 pub struct Storage(W);
251
252 #[inline(never)]
254 pub fn build_numerator(top_limb_idx: usize) -> Storage {
255 use crate::wide_int::WideInt;
256 let mut mag = [0u128; 64];
257 mag[top_limb_idx] = 1u128 << 32;
258 mag[1] = 0xdeadbeef_cafef00d_u128;
259 Storage(W::from_mag_sign_u128(&mag, false))
260 }
261
262 #[inline(never)]
263 pub fn mg_chain(n: Storage, scale: u32) -> Storage {
264 Storage(crate::algos::mg_divide::div_wide_pow10_chain_with::<
265 W,
266 { <W as crate::wide_int::WideInt>::U128_LIMBS },
267 >(
268 n.0,
269 scale,
270 RoundingMode::HalfToEven,
271 ))
272 }
273
274 #[inline(never)]
275 pub fn mg_single(n: Storage, scale: u32) -> Storage {
276 Storage(crate::algos::mg_divide::div_wide_pow10_with::<
277 W,
278 { <W as crate::wide_int::WideInt>::U128_LIMBS },
279 >(
280 n.0,
281 scale,
282 RoundingMode::HalfToEven,
283 ))
284 }
285
286 #[inline(never)]
287 pub fn newton(
288 n: Storage,
289 scale: u32,
290 table: &NewtonReciprocal,
291 ) -> Storage {
292 Storage(crate::algos::newton_reciprocal::div_wide_pow10_newton_with::<W>(
293 n.0,
294 scale,
295 RoundingMode::HalfToEven,
296 &table.0,
297 ))
298 }
299 }
300 };
301 }
302 shim!(d307, crate::wide_int::I1024, "x-wide");
303 shim!(d616, crate::wide_int::I2048, "x-wide");
304 shim!(d924, crate::wide_int::I3072, "xx-wide");
305 shim!(d1232, crate::wide_int::I4096, "xx-wide");
306 }
307}
308mod macros;
309
310#[cfg(feature = "cross-scale-ops")]
311pub mod cross_scale;
312
313#[cfg(feature = "cross-scale-ops")]
316pub use crate::cross_scale as cross;
317
318mod wide_int;
332mod policy;
333
334#[cfg(feature = "serde")]
335pub use crate::support::serde_helpers;
336
337
338pub use crate::types::consts::DecimalConstants;
339pub use crate::types::traits::DecimalArithmetic;
340pub use crate::types::traits::DecimalConvert;
341pub use crate::types::unified::D;
342pub use crate::types::traits::Decimal;
343pub use crate::support::error::{ConvertError, ParseError};
344pub use crate::support::rounding::RoundingMode;
345pub use crate::types::traits::DecimalTranscendental;
346pub use crate::types::traits::WidthLE;
347
348#[cfg(feature = "dyn")]
349pub use crate::types::traits::dyn_decimal::{DecimalWidth, DynDecimal, RawStorage};
350
351pub use crate::types::widths::{
354 D38, D38s0, D38s1, D38s2, D38s3, D38s4, D38s5, D38s6, D38s7, D38s8, D38s9, D38s10,
355 D38s11, D38s12, D38s13, D38s14, D38s15, D38s16, D38s17, D38s18, D38s19, D38s20,
356 D38s21, D38s22, D38s23, D38s24, D38s25, D38s26, D38s27, D38s28, D38s29, D38s30,
357 D38s31, D38s32, D38s33, D38s34, D38s35, D38s36, D38s37,
358};
359
360pub use crate::types::widths::{
362 D9, D9s0, D9s1, D9s2, D9s3, D9s4, D9s5, D9s6, D9s7, D9s8,
363};
364
365pub use crate::types::widths::{
367 D18, D18s0, D18s1, D18s2, D18s3, D18s4, D18s5, D18s6, D18s7, D18s8, D18s9, D18s10, D18s11,
368 D18s12, D18s13, D18s14, D18s15, D18s16, D18s17,
369};
370
371#[cfg(any(feature = "d76", feature = "wide"))]
373pub use crate::types::widths::{
374 D76,
375 D76s0, D76s1, D76s2, D76s3, D76s4, D76s6, D76s9, D76s12, D76s15,
376 D76s18, D76s20, D76s24, D76s28, D76s32, D76s35, D76s38, D76s42,
377 D76s48, D76s50, D76s56, D76s64, D76s70, D76s75,
378};
379
380#[cfg(any(feature = "d76", feature = "d153", feature = "d307", feature = "wide"))]
383pub use wide_int::{
384 Int256, Int512, Int1024, Int2048, Int4096, Uint256, Uint512, Uint1024, Uint2048, Uint4096,
385};
386
387#[cfg(any(feature = "d153", feature = "wide"))]
389pub use crate::types::widths::{
390 D153,
391 D153s0, D153s1, D153s2, D153s4, D153s6, D153s9, D153s12, D153s15,
392 D153s18, D153s20, D153s24, D153s28, D153s32, D153s35, D153s38,
393 D153s50, D153s57, D153s75, D153s76, D153s100, D153s115, D153s140,
394 D153s150, D153s152,
395};
396
397#[cfg(any(feature = "d307", feature = "wide"))]
399pub use crate::types::widths::{
400 D307,
401 D307s0, D307s1, D307s2, D307s4, D307s6, D307s9, D307s12, D307s15,
402 D307s18, D307s20, D307s24, D307s28, D307s32, D307s35, D307s38,
403 D307s50, D307s75, D307s100, D307s115, D307s150, D307s153,
404 D307s200, D307s230, D307s275, D307s300, D307s306,
405};
406
407#[cfg(any(feature = "d57", feature = "wide"))]
411pub use crate::types::widths::{
412 D57,
413 D57s0, D57s1, D57s2, D57s4, D57s6, D57s9, D57s12, D57s18, D57s20, D57s24,
414 D57s28, D57s32, D57s38, D57s42, D57s48, D57s52, D57s56,
415};
416#[cfg(any(feature = "d57", feature = "wide"))]
417pub use wide_int::{Int192, Uint192};
418
419#[cfg(any(feature = "d115", feature = "wide"))]
421pub use crate::types::widths::{
422 D115,
423 D115s0, D115s1, D115s4, D115s8, D115s16, D115s24, D115s32, D115s38, D115s50,
424 D115s57, D115s64, D115s76, D115s90, D115s100, D115s110, D115s114,
425};
426#[cfg(any(feature = "d115", feature = "wide"))]
427pub use wide_int::{Int384, Uint384};
428
429#[cfg(any(feature = "d230", feature = "wide"))]
431pub use crate::types::widths::{
432 D230,
433 D230s0, D230s1, D230s6, D230s18, D230s38, D230s57, D230s75, D230s100, D230s115,
434 D230s140, D230s153, D230s175, D230s200, D230s215, D230s225, D230s229,
435};
436#[cfg(any(feature = "d230", feature = "wide"))]
437pub use wide_int::{Int768, Uint768};
438
439#[cfg(any(feature = "d462", feature = "x-wide"))]
441pub use crate::types::widths::{
442 D462,
443 D462s0, D462s1, D462s18, D462s38, D462s75, D462s115, D462s153, D462s200, D462s230,
444 D462s275, D462s307, D462s350, D462s400, D462s440, D462s460, D462s461,
445};
446#[cfg(any(feature = "d462", feature = "x-wide"))]
447pub use wide_int::{Int1536, Uint1536};
448
449#[cfg(any(feature = "d616", feature = "x-wide"))]
453pub use crate::types::widths::{
454 D616,
455 D616s0, D616s1, D616s38, D616s75, D616s115, D616s153, D616s200, D616s230, D616s275,
456 D616s308, D616s380, D616s462, D616s500, D616s555, D616s600, D616s615,
457};
458
459#[cfg(any(feature = "d924", feature = "xx-wide"))]
461pub use crate::types::widths::{
462 D924,
463 D924s0, D924s1, D924s75, D924s153, D924s230, D924s307, D924s400, D924s461, D924s462,
464 D924s500, D924s616, D924s700, D924s800, D924s860, D924s900, D924s920, D924s923,
465};
466#[cfg(any(feature = "d924", feature = "xx-wide"))]
467pub use wide_int::{Int3072, Int6144, Int12288, Uint3072, Uint6144, Uint12288};
468
469#[cfg(any(feature = "d1232", feature = "xx-wide"))]
471pub use crate::types::widths::{
472 D1232,
473 D1232s0, D1232s1, D1232s75, D1232s153, D1232s230, D1232s307, D1232s461, D1232s616,
474 D1232s700, D1232s800, D1232s900, D1232s924, D1232s1000, D1232s1100,
475 D1232s1180, D1232s1220, D1232s1230, D1232s1231,
476};
477#[cfg(any(feature = "d1232", feature = "xx-wide"))]
478pub use wide_int::{Int8192, Int16384, Uint8192, Uint16384};
479
480#[cfg(feature = "macros")]
486pub use decimal_scaled_macros::{d9, d18, d38};
487
488#[cfg(all(feature = "macros", any(feature = "d76", feature = "wide")))]
489pub use decimal_scaled_macros::d76;
490
491#[cfg(all(feature = "macros", any(feature = "d153", feature = "wide")))]
492pub use decimal_scaled_macros::d153;
493
494#[cfg(all(feature = "macros", any(feature = "d307", feature = "wide", feature = "x-wide")))]
495pub use decimal_scaled_macros::d307;
496
497#[cfg(all(feature = "macros", any(feature = "d57", feature = "wide")))]
498pub use decimal_scaled_macros::d57;
499
500#[cfg(all(feature = "macros", any(feature = "d115", feature = "wide")))]
501pub use decimal_scaled_macros::d115;
502
503#[cfg(all(feature = "macros", any(feature = "d230", feature = "wide")))]
504pub use decimal_scaled_macros::d230;
505
506#[cfg(all(feature = "macros", any(feature = "d462", feature = "x-wide")))]
507pub use decimal_scaled_macros::d462;
508
509#[cfg(all(feature = "macros", any(feature = "d616", feature = "x-wide")))]
510pub use decimal_scaled_macros::d616;
511
512#[cfg(all(feature = "macros", any(feature = "d924", feature = "xx-wide")))]
513pub use decimal_scaled_macros::d924;
514
515#[cfg(all(feature = "macros", any(feature = "d1232", feature = "xx-wide")))]
516pub use decimal_scaled_macros::d1232;
517
518#[cfg(feature = "macros")] #[macro_export]
532macro_rules! d9s0 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d9!($v, scale 0 $(, $($rest)*)?) }; }
533#[cfg(feature = "macros")] #[macro_export]
535macro_rules! d9s2 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d9!($v, scale 2 $(, $($rest)*)?) }; }
536#[cfg(feature = "macros")] #[macro_export]
538macro_rules! d9s4 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d9!($v, scale 4 $(, $($rest)*)?) }; }
539#[cfg(feature = "macros")] #[macro_export]
541macro_rules! d9s6 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d9!($v, scale 6 $(, $($rest)*)?) }; }
542
543#[cfg(feature = "macros")] #[macro_export]
546macro_rules! d18s0 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d18!($v, scale 0 $(, $($rest)*)?) }; }
547#[cfg(feature = "macros")] #[macro_export]
549macro_rules! d18s2 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d18!($v, scale 2 $(, $($rest)*)?) }; }
550#[cfg(feature = "macros")] #[macro_export]
552macro_rules! d18s4 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d18!($v, scale 4 $(, $($rest)*)?) }; }
553#[cfg(feature = "macros")] #[macro_export]
555macro_rules! d18s6 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d18!($v, scale 6 $(, $($rest)*)?) }; }
556#[cfg(feature = "macros")] #[macro_export]
558macro_rules! d18s9 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d18!($v, scale 9 $(, $($rest)*)?) }; }
559#[cfg(feature = "macros")] #[macro_export]
561macro_rules! d18s12 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d18!($v, scale 12 $(, $($rest)*)?) }; }
562
563#[cfg(feature = "macros")] #[macro_export]
566macro_rules! d38s0 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d38!($v, scale 0 $(, $($rest)*)?) }; }
567#[cfg(feature = "macros")] #[macro_export]
569macro_rules! d38s2 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d38!($v, scale 2 $(, $($rest)*)?) }; }
570#[cfg(feature = "macros")] #[macro_export]
572macro_rules! d38s4 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d38!($v, scale 4 $(, $($rest)*)?) }; }
573#[cfg(feature = "macros")] #[macro_export]
575macro_rules! d38s6 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d38!($v, scale 6 $(, $($rest)*)?) }; }
576#[cfg(feature = "macros")] #[macro_export]
578macro_rules! d38s8 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d38!($v, scale 8 $(, $($rest)*)?) }; }
579#[cfg(feature = "macros")] #[macro_export]
581macro_rules! d38s9 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d38!($v, scale 9 $(, $($rest)*)?) }; }
582#[cfg(feature = "macros")] #[macro_export]
584macro_rules! d38s12 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d38!($v, scale 12 $(, $($rest)*)?) }; }
585#[cfg(feature = "macros")] #[macro_export]
587macro_rules! d38s15 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d38!($v, scale 15 $(, $($rest)*)?) }; }
588#[cfg(feature = "macros")] #[macro_export]
590macro_rules! d38s18 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d38!($v, scale 18 $(, $($rest)*)?) }; }
591#[cfg(feature = "macros")] #[macro_export]
593macro_rules! d38s24 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d38!($v, scale 24 $(, $($rest)*)?) }; }
594#[cfg(feature = "macros")] #[macro_export]
596macro_rules! d38s35 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d38!($v, scale 35 $(, $($rest)*)?) }; }
597
598#[cfg(all(feature = "macros", any(feature = "d76", feature = "wide")))] #[macro_export]
601macro_rules! d76s0 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d76!($v, scale 0 $(, $($rest)*)?) }; }
602#[cfg(all(feature = "macros", any(feature = "d76", feature = "wide")))] #[macro_export]
604macro_rules! d76s2 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d76!($v, scale 2 $(, $($rest)*)?) }; }
605#[cfg(all(feature = "macros", any(feature = "d76", feature = "wide")))] #[macro_export]
607macro_rules! d76s6 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d76!($v, scale 6 $(, $($rest)*)?) }; }
608#[cfg(all(feature = "macros", any(feature = "d76", feature = "wide")))] #[macro_export]
610macro_rules! d76s12 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d76!($v, scale 12 $(, $($rest)*)?) }; }
611#[cfg(all(feature = "macros", any(feature = "d76", feature = "wide")))] #[macro_export]
613macro_rules! d76s18 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d76!($v, scale 18 $(, $($rest)*)?) }; }
614#[cfg(all(feature = "macros", any(feature = "d76", feature = "wide")))] #[macro_export]
616macro_rules! d76s35 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d76!($v, scale 35 $(, $($rest)*)?) }; }
617#[cfg(all(feature = "macros", any(feature = "d76", feature = "wide")))] #[macro_export]
619macro_rules! d76s50 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d76!($v, scale 50 $(, $($rest)*)?) }; }
620
621#[cfg(all(feature = "macros", any(feature = "d153", feature = "wide")))] #[macro_export]
624macro_rules! d153s0 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d153!($v, scale 0 $(, $($rest)*)?) }; }
625#[cfg(all(feature = "macros", any(feature = "d153", feature = "wide")))] #[macro_export]
627macro_rules! d153s35 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d153!($v, scale 35 $(, $($rest)*)?) }; }
628#[cfg(all(feature = "macros", any(feature = "d153", feature = "wide")))] #[macro_export]
630macro_rules! d153s75 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d153!($v, scale 75 $(, $($rest)*)?) }; }
631#[cfg(all(feature = "macros", any(feature = "d153", feature = "wide")))] #[macro_export]
633macro_rules! d153s150 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d153!($v, scale 150 $(, $($rest)*)?) }; }
634
635#[cfg(all(feature = "macros", any(feature = "d307", feature = "wide", feature = "x-wide")))] #[macro_export]
638macro_rules! d307s0 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d307!($v, scale 0 $(, $($rest)*)?) }; }
639#[cfg(all(feature = "macros", any(feature = "d307", feature = "wide", feature = "x-wide")))] #[macro_export]
641macro_rules! d307s35 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d307!($v, scale 35 $(, $($rest)*)?) }; }
642#[cfg(all(feature = "macros", any(feature = "d307", feature = "wide", feature = "x-wide")))] #[macro_export]
644macro_rules! d307s150 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d307!($v, scale 150 $(, $($rest)*)?) }; }
645#[cfg(all(feature = "macros", any(feature = "d307", feature = "wide", feature = "x-wide")))] #[macro_export]
647macro_rules! d307s300 { ($v:tt $(, $($rest:tt)*)?) => { $crate::d307!($v, scale 300 $(, $($rest)*)?) }; }