numera/number/integer/z/
big.rs

1// numera::number::integer::z::big
2//
3//!
4//
5// TOC
6//
7// - definition
8// - impls
9//   - Sign
10//   - Bound
11//   - Count
12//   - Ident
13//   - Number
14
15use crate::{
16    error::{NumeraErrors, NumeraResult},
17    number::traits::{
18        Bound, ConstNegOne, ConstOne, ConstZero, Count, Countable, Ident, NegOne, Negative,
19        NonLowerBounded, NonUpperBounded, Number, One, Positive, Sign, Zero,
20    },
21};
22use core::{fmt, str::FromStr};
23use dashu_int::IBig;
24
25/* definition */
26
27/// A big integer number, from the set $\\Z$,
28/// also known as [`ZBig`][super::ZBig].
29#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
30pub struct IntegerBig(pub IBig);
31
32impl fmt::Display for IntegerBig {
33    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34        write!(f, "{}", self.0)
35    }
36}
37impl fmt::Debug for IntegerBig {
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39        write!(f, "ZBig({})", self.0)
40    }
41}
42
43impl IntegerBig {
44    /// Returns a new `IntegerBig`.
45    #[inline]
46    #[must_use]
47    pub fn new(value: i128) -> IntegerBig {
48        Self(IBig::from(value))
49    }
50
51    /// Returns a new `IntegerBig` from a string in base 10.
52    ///
53    /// # Errors
54    /// If the number is unparseable.
55    #[inline]
56    pub fn from_string(value: &str) -> NumeraResult<IntegerBig> {
57        Ok(Self(IBig::from_str_radix(value, 10)?))
58    }
59
60    /// Returns a new `IntegerBig` from a string in the given `base`,
61    /// which must be between 2 and 36, inclusive.
62    ///
63    /// `value` may contain an optional `+` prefix.
64    /// Digits 10-35 are represented by `a-z` or `A-Z`.
65    ///
66    ///
67    /// # Panics
68    /// If base is <2 or >36.
69    // FIXME: make this an error.
70    ///
71    /// # Errors
72    /// If the number is unparseable.
73    #[inline]
74    pub fn from_str_with_base(value: &str, base: u32) -> NumeraResult<IntegerBig> {
75        Ok(Self(IBig::from_str_radix(value, base)?))
76    }
77}
78
79impl FromStr for IntegerBig {
80    type Err = NumeraErrors;
81
82    fn from_str(s: &str) -> NumeraResult<IntegerBig> {
83        Self::from_string(s)
84    }
85}
86
87/* sign */
88
89#[rustfmt::skip]
90impl Sign for IntegerBig {
91    #[inline]
92    fn can_negative(&self) -> bool { true }
93    #[inline]
94    fn can_positive(&self) -> bool { true }
95    #[inline]
96    fn is_negative(&self) -> bool { self.0.is_negative() }
97    #[inline]
98    fn is_positive(&self) -> bool { self.0.is_positive() }
99}
100impl Positive for IntegerBig {}
101impl Negative for IntegerBig {}
102
103/* bound */
104
105#[rustfmt::skip]
106impl Bound for IntegerBig {
107    #[inline]
108    fn is_lower_bounded(&self) -> bool { false }
109    #[inline]
110    fn is_upper_bounded(&self) -> bool { false }
111    #[inline]
112    fn lower_bound(&self) -> Option<Self> { None }
113    #[inline]
114    fn upper_bound(&self) -> Option<Self> { None }
115}
116impl NonLowerBounded for IntegerBig {}
117impl NonUpperBounded for IntegerBig {}
118
119/* count */
120
121impl Count for IntegerBig {
122    #[inline]
123    fn is_countable(&self) -> bool {
124        true
125    }
126}
127
128impl Countable for IntegerBig {
129    #[inline]
130    fn next(&self) -> NumeraResult<Self> {
131        self.0.next().map(Self)
132    }
133    #[inline]
134    fn previous(&self) -> NumeraResult<Self> {
135        self.0.previous().map(Self)
136    }
137}
138
139/* ident */
140
141#[rustfmt::skip]
142impl Ident for IntegerBig {
143    #[inline]
144    fn can_zero(&self) -> bool { true }
145    #[inline]
146    fn can_one(&self) -> bool { true }
147    #[inline]
148    fn can_neg_one(&self) -> bool { true }
149
150    #[inline]
151    fn is_zero(&self) -> bool { self.0.is_zero() }
152    #[inline]
153    fn is_one(&self) -> bool { self.0.is_one() }
154    #[inline]
155    fn is_neg_one(&self) -> bool { self.0.is_neg_one() }
156}
157#[rustfmt::skip]
158impl ConstZero for IntegerBig { const ZERO: Self = Self(IBig::ZERO); }
159impl Zero for IntegerBig {
160    #[inline]
161    fn new_zero() -> Self {
162        Self::ZERO
163    }
164}
165#[rustfmt::skip]
166impl ConstOne for IntegerBig { const ONE: Self = Self(IBig::ONE); }
167impl One for IntegerBig {
168    #[inline]
169    fn new_one() -> Self {
170        Self::ONE
171    }
172}
173#[rustfmt::skip]
174impl ConstNegOne for IntegerBig { const NEG_ONE: Self = Self(IBig::NEG_ONE); }
175impl NegOne for IntegerBig {
176    #[inline]
177    fn new_neg_one() -> Self {
178        Self::NEG_ONE
179    }
180}
181
182/* Number */
183
184impl Number for IntegerBig {
185    type InnerRepr = IBig;
186    type InnermostRepr = IBig;
187
188    /// Returns a new `IntegerBig` from the inner representation.
189    ///
190    /// # Errors
191    /// This function can't fail.
192    #[inline]
193    fn from_inner_repr(value: Self::InnerRepr) -> NumeraResult<Self> {
194        Ok(Self(value))
195    }
196
197    /// Returns a new `IntegerBig` from the inner representation.
198    ///
199    /// # Safety
200    /// This function is safe.
201    #[inline]
202    #[cfg(not(feature = "safe"))]
203    #[cfg_attr(feature = "nightly", doc(cfg(feature = "not(safe)")))]
204    unsafe fn from_inner_repr_unchecked(value: Self::InnerRepr) -> Self {
205        Self(value)
206    }
207
208    /// Returns a new `IntegerBig` from the innermost representation.
209    ///
210    /// # Errors
211    /// This function can't fail.
212    #[inline]
213    fn from_innermost_repr(value: Self::InnermostRepr) -> NumeraResult<Self> {
214        Ok(Self(value))
215    }
216
217    /// Returns a new `IntegerBig` from the innermost representation.
218    ///
219    /// # Safety
220    /// This function is safe.
221    #[inline]
222    #[cfg(not(feature = "safe"))]
223    #[cfg_attr(feature = "nightly", doc(cfg(feature = "not(safe)")))]
224    unsafe fn from_innermost_repr_unchecked(value: Self::InnermostRepr) -> Self {
225        Self(value)
226    }
227
228    #[inline]
229    fn into_inner_repr(self) -> Self::InnerRepr {
230        self.0
231    }
232
233    #[inline]
234    fn into_innermost_repr(self) -> Self::InnermostRepr {
235        self.0
236    }
237}