malachite_nz/natural/
mod.rs1use crate::natural::InnerNatural::{Large, Small};
10use crate::platform::Limb;
11use alloc::string::String;
12use alloc::vec::Vec;
13#[cfg(feature = "doc-images")]
14use embed_doc_image::embed_doc_image;
15use malachite_base::comparison::traits::Min;
16use malachite_base::named::Named;
17#[cfg(feature = "float_helpers")]
18use malachite_base::num::basic::integers::PrimitiveInt;
19use malachite_base::num::basic::traits::{One, Two, Zero};
20use malachite_base::slices::slice_trailing_zeros;
21
22#[cfg_attr(
27 feature = "doc-images",
28 embed_doc_image("natural-mem-layout", "images/natural-mem-layout.svg")
29)]
30#[derive(Clone, Eq, Hash, PartialEq)]
31#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
32#[cfg_attr(
33 feature = "serde",
34 serde(try_from = "SerdeNatural", into = "SerdeNatural")
35)]
36pub struct Natural(pub(crate) InnerNatural);
37
38#[derive(Clone, Eq, Hash, PartialEq)]
41pub(crate) enum InnerNatural {
42 Small(Limb),
43 Large(Vec<Limb>),
44}
45
46#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
47#[cfg_attr(feature = "serde", serde(transparent))]
48pub(crate) struct SerdeNatural(String);
49
50impl Natural {
51 fn demote_if_small(&mut self) {
53 if let Self(Large(limbs)) = self {
54 match limbs.len() {
55 0 => *self = Self::ZERO,
56 1 => *self = Self(Small(limbs[0])),
57 _ => {}
58 }
59 }
60 }
61
62 pub(crate) fn promote_in_place(&mut self) -> &mut Vec<Limb> {
64 if let Self(Small(x)) = self {
65 *self = Self(Large(vec![*x]));
66 }
67 if let Self(Large(xs)) = self {
68 xs
69 } else {
70 unreachable!();
71 }
72 }
73
74 pub(crate) fn trim(&mut self) {
75 if let Self(Large(limbs)) = self {
76 let trailing_zero_count = slice_trailing_zeros(limbs);
77 if trailing_zero_count != 0 {
78 let len = limbs.len();
79 limbs.truncate(len - trailing_zero_count);
80 }
81 }
82 self.demote_if_small();
83 }
84
85 #[cfg(feature = "test_build")]
90 pub fn is_valid(&self) -> bool {
91 match self {
92 Self(Small(_)) => true,
93 Self(Large(xs)) => xs.len() > 1 && *xs.last().unwrap() != 0,
94 }
95 }
96}
97
98impl Zero for Natural {
100 const ZERO: Self = Self(Small(0));
101}
102
103impl One for Natural {
105 const ONE: Self = Self(Small(1));
106}
107
108impl Two for Natural {
110 const TWO: Self = Self(Small(2));
111}
112
113impl Min for Natural {
115 const MIN: Self = Self::ZERO;
116}
117
118#[cfg(feature = "float_helpers")]
119impl Natural {
120 pub const HIGH_BIT: Self = Self(Small(1 << (Limb::WIDTH - 1)));
121}
122
123impl Default for Natural {
124 fn default() -> Self {
126 Self::ZERO
127 }
128}
129
130impl_named!(Natural);
132
133pub mod arithmetic;
135pub mod comparison;
137pub mod conversion;
140pub mod exhaustive;
142pub mod factorization;
144pub mod logic;
146#[cfg(feature = "random")]
147pub mod random;