big_int/
denormal.rs

1//! Denormalized numbers.
2//!
3//! A denormalized number may not be in a consistent form, and may behave in
4//! unexpected ways while performing mathematical operations. It is typically best
5//! practice to normalize a denormalized number before using it in other contexts.
6//!
7//! Sometimes, however, maintaining a number in a denormalized state is desirable for
8//! one reason or another; for example, performing normalization is a nonzero performance
9//! cost; you may save some computation by performing several consecutive operations in a row
10//! on a denormalized number before finally normalizing it at the end. Additionally, trailing
11//! zeros may be desirable to maintain, for data manipulation purposes.
12//!
13//! ```
14//! use big_int::prelude::*;
15//!
16//! let a: Tight<10> = 194.into();
17//! let a: DenormalTight<10> = a.sub_inner::<Tight<10>, Tight<10>>(100.into());
18//! assert_eq!(format!("{a}"), "094".to_string());
19//! let a: Tight<10> = a.unwrap();
20//! assert_eq!(format!("{a}"), "94".to_string());
21//! ```
22use crate::*;
23
24/// Represents a denormalized number.
25///
26/// A denormalized number may not be in a consistent form, and may behave in
27/// unexpected ways while performing mathematical operations. It is typically best
28/// practice to normalize a denormalized number before using it in other contexts.
29///
30/// Sometimes, however, maintaining a number in a denormalized state is desirable for
31/// one reason or another; for example, performing normalization is a nonzero performance
32/// cost; you may save some computation by performing several consecutive operations in a row
33/// on a denormalized number before finally normalizing it at the end. Additionally, trailing
34/// zeros may be desirable to maintain, for data manipulation purposes.
35///
36/// ```
37/// use big_int::prelude::*;
38///
39/// let a: Tight<10> = 194.into();
40/// let a: DenormalTight<10> = a.sub_inner::<Tight<10>, Tight<10>>(100.into());
41/// assert_eq!(format!("{a}"), "094".to_string());
42/// let a: Tight<10> = a.unwrap();
43/// assert_eq!(format!("{a}"), "94".to_string());
44/// ```
45#[derive(Debug, Clone)]
46pub struct Denormal<const BASE: usize, B: BigInt<{ BASE }>>(pub(crate) B);
47
48impl<const BASE: usize, B: BigInt<{ BASE }>> BigInt<BASE> for Denormal<BASE, B> {
49    type Builder = DenormalBuilder<BASE, B::Builder>;
50    type Denormal = Self;
51
52    // required methods
53
54    fn len(&self) -> usize {
55        self.0.len()
56    }
57
58    fn get_digit(&self, digit: usize) -> Option<Digit> {
59        self.0.get_digit(digit)
60    }
61
62    fn set_digit(&mut self, digit: usize, value: Digit) {
63        self.0.set_digit(digit, value)
64    }
65
66    fn zero() -> Self {
67        B::zero().into()
68    }
69
70    fn sign(&self) -> Sign {
71        self.0.sign()
72    }
73
74    fn with_sign(self, sign: Sign) -> Self {
75        self.0.with_sign(sign).into()
76    }
77
78    fn set_sign(&mut self, sign: Sign) {
79        self.0.set_sign(sign)
80    }
81
82    fn push_back(&mut self, digit: Digit) {
83        self.0.push_back(digit)
84    }
85
86    unsafe fn push_front(&mut self, digit: Digit) {
87        self.0.push_front(digit)
88    }
89
90    unsafe fn pop_back(&mut self) -> Option<Digit> {
91        self.0.pop_back()
92    }
93
94    unsafe fn pop_front(&mut self) -> Option<Digit> {
95        self.0.pop_front()
96    }
97
98    fn is_zero(&self) -> bool {
99        self.0.is_zero()
100    }
101
102    fn normalized(self) -> Self {
103        self.0.normalized().into()
104    }
105
106    fn normalize(&mut self) {
107        self.0.normalize();
108    }
109
110    unsafe fn shl_assign_inner(&mut self, amount: usize) {
111        self.0.shl_assign_inner(amount);
112    }
113
114    fn shl_inner(self, amount: usize) -> Self::Denormal {
115        unsafe { self.0.shl_inner(amount).unsafe_into() }.into()
116    }
117
118    unsafe fn shr_assign_inner(&mut self, amount: usize) {
119        self.0.shr_assign_inner(amount)
120    }
121
122    fn shr_inner(self, amount: usize) -> Self::Denormal {
123        unsafe { self.0.shr_inner(amount).unsafe_into() }.into()
124    }
125
126    fn div_rem<RHS: BigInt<{ BASE }>, OUT: BigInt<{ BASE }>>(
127        self,
128        rhs: RHS,
129    ) -> Result<(OUT, OUT), BigIntError> {
130        self.div_rem_inner::<RHS, OUT>(rhs)
131            .map(|(q, r)| unsafe { (q.unsafe_into(), r.unsafe_into()) })
132    }
133
134    fn exp<RHS: BigInt<{ BASE }>, OUT: BigInt<{ BASE }>>(
135        self,
136        rhs: RHS,
137    ) -> Result<OUT, BigIntError> {
138        self.exp_inner::<RHS, OUT>(rhs)
139            .map(|x| unsafe { x.unsafe_into() })
140    }
141
142    fn log<RHS: BigInt<{ BASE }>, OUT: BigInt<{ BASE }>>(
143        self,
144        rhs: RHS,
145    ) -> Result<OUT, BigIntError> {
146        self.log_inner::<RHS, OUT>(rhs)
147            .map(|x| unsafe { x.unsafe_into() })
148    }
149
150    fn root<RHS: BigInt<{ BASE }>, OUT: BigInt<{ BASE }>>(
151        self,
152        rhs: RHS,
153    ) -> Result<OUT, BigIntError> {
154        self.root_inner::<RHS, OUT>(rhs)
155            .map(|x| unsafe { x.unsafe_into() })
156    }
157
158    fn convert<const TO: usize, OUT: BigInt<{ TO }>>(self) -> OUT {
159        unsafe { self.convert_inner::<TO, OUT>().unsafe_into() }
160    }
161
162    fn get_back_inner(&self, index: usize) -> Option<Digit> {
163        self.0.get_back_inner(index)
164    }
165
166    fn default_inner() -> Self {
167        Self(B::default_inner())
168    }
169
170    fn fmt_inner(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
171        self.0.fmt_inner(f)
172    }
173
174    fn partial_cmp_inner<RHS: BigInt<{ BASE }>>(&self, other: &RHS) -> Option<Ordering> {
175        self.0.partial_cmp_inner(other)
176    }
177
178    fn cmp_inner<RHS: BigInt<{ BASE }>>(&self, other: &RHS) -> Ordering {
179        self.0.cmp_inner(other)
180    }
181
182    fn eq_inner<RHS: BigInt<{ BASE }>>(&self, other: &RHS) -> bool {
183        self.0.eq_inner(other)
184    }
185
186    fn neg_inner(self) -> Self::Denormal {
187        unsafe { self.0.neg_inner().unsafe_into() }.into()
188    }
189
190    fn add_inner<RHS: BigInt<{ BASE }>, OUT: BigInt<{ BASE }>>(self, rhs: RHS) -> OUT::Denormal {
191        unsafe { self.0.add_inner::<RHS, OUT>(rhs).unsafe_into() }.into()
192    }
193
194    unsafe fn add_assign_inner<RHS: BigInt<{ BASE }>>(&mut self, rhs: RHS) {
195        self.0.add_assign_inner(rhs)
196    }
197
198    fn sub_inner<RHS: BigInt<{ BASE }>, OUT: BigInt<{ BASE }>>(
199        self,
200        rhs: RHS,
201    ) -> OUT::Denormal {
202        unsafe { self.0.sub_inner::<RHS, OUT>(rhs).unsafe_into() }.into()
203    }
204
205    unsafe fn sub_assign_inner<RHS: BigInt<{ BASE }>>(&mut self, rhs: RHS) {
206        self.0.sub_assign_inner(rhs)
207    }
208
209    fn mul_inner<RHS: BigInt<{ BASE }>, OUT: BigInt<{ BASE }>>(
210        self,
211        rhs: RHS,
212    ) -> OUT::Denormal {
213        unsafe { self.0.mul_inner::<RHS, OUT>(rhs).unsafe_into() }.into()
214    }
215
216    unsafe fn mul_assign_inner<RHS: BigInt<{ BASE }>>(&mut self, rhs: RHS) {
217        self.0.mul_assign_inner(rhs)
218    }
219
220    fn div_inner<RHS: BigInt<{ BASE }>, OUT: BigInt<{ BASE }>>(self, rhs: RHS) -> OUT::Denormal {
221        unsafe { self.0.div_inner::<RHS, OUT>(rhs).unsafe_into() }.into()
222    }
223
224    unsafe fn div_assign_inner<RHS: BigInt<{ BASE }>>(&mut self, rhs: RHS) {
225        self.0.div_assign_inner(rhs)
226    }
227
228    fn from_str_inner(s: &str) -> Result<Self::Denormal, BigIntError> {
229        B::from_str_inner(s).map(|x| unsafe { x.unsafe_into() }.into())
230    }
231
232    fn from_iter_inner<T: IntoIterator<Item = Digit>>(iter: T) -> Self::Denormal {
233        unsafe { B::from_iter_inner(iter).unsafe_into() }.into()
234    }
235
236    fn from_u128_inner(value: u128) -> Self::Denormal {
237        unsafe { B::from_u128_inner(value).unsafe_into() }.into()
238    }
239
240    fn from_i128_inner(value: i128) -> Self::Denormal {
241        unsafe { B::from_i128_inner(value).unsafe_into() }.into()
242    }
243
244    fn into_u128_inner(self) -> u128 {
245        self.0.into_u128_inner()
246    }
247
248    fn into_i128_inner(self) -> i128 {
249        self.0.into_i128_inner()
250    }
251
252    fn div_rem_inner<RHS: BigInt<{ BASE }>, OUT: BigInt<{ BASE }>>(
253        self,
254        rhs: RHS,
255    ) -> Result<(OUT::Denormal, OUT::Denormal), BigIntError> {
256        self.0.div_rem_inner::<RHS, OUT>(rhs).map(|(q, r)| {
257            (
258                unsafe { q.unsafe_into() }.into(),
259                unsafe { r.unsafe_into() }.into(),
260            )
261        })
262    }
263
264    fn exp_inner<RHS: BigInt<{ BASE }>, OUT: BigInt<{ BASE }>>(
265        self,
266        rhs: RHS,
267    ) -> Result<OUT::Denormal, BigIntError> {
268        self.0
269            .exp_inner::<RHS, OUT>(rhs)
270            .map(|x| unsafe { x.unsafe_into() }.into())
271    }
272
273    fn log_inner<RHS: BigInt<{ BASE }>, OUT: BigInt<{ BASE }>>(
274        self,
275        rhs: RHS,
276    ) -> Result<OUT::Denormal, BigIntError> {
277        self.0
278            .log_inner::<RHS, OUT>(rhs)
279            .map(|x| unsafe { x.unsafe_into() }.into())
280    }
281    
282    fn root_inner<RHS: BigInt<{ BASE }>, OUT: BigInt<{ BASE }>>(
283        self,
284        rhs: RHS,
285    ) -> Result<OUT::Denormal, BigIntError> {
286        self.0
287            .root_inner::<RHS, OUT>(rhs)
288            .map(|x| unsafe { x.unsafe_into() }.into())
289    }
290
291    fn is_even(&self) -> bool {
292        self.0.is_even()
293    }
294
295    fn iter<'a>(&'a self) -> BigIntIter<'a, BASE, Self> {
296        BigIntIter {
297            index: 0,
298            back_index: self.len(),
299            int: self,
300        }
301    }
302
303    fn display(&self, alphabet: &str) -> Result<String, BigIntError> {
304        self.0.display(alphabet)
305    }
306
307    fn parse(value: &str, alphabet: &str) -> Result<Self::Denormal, ParseError> {
308        B::parse(value, alphabet).map(|x| unsafe { x.unsafe_into() }.into())
309    }
310
311    fn convert_inner<const TO: usize, OUT: BigInt<{ TO }>>(self) -> OUT::Denormal {
312        unsafe { self.0.convert_inner::<TO, OUT>().unsafe_into() }.into()
313    }
314
315    fn cmp_magnitude<RHS: BigInt<{ BASE }>>(&self, rhs: &RHS) -> Ordering {
316        self.0.cmp_magnitude(rhs)
317    }
318}
319
320impl<const BASE: usize, B: BigInt<{ BASE }>> ::big_int::get_back::GetBack for Denormal<BASE, B> {
321    type Item = ::big_int::Digit;
322
323    fn get_back(&self, index: usize) -> Option<::big_int::Digit> {
324        <Denormal<BASE, B> as ::big_int::BigInt<BASE>>::get_back_inner(self, index)
325    }
326}
327
328impl<const BASE: usize, B: BigInt<{ BASE }>> ::std::default::Default for Denormal<BASE, B> {
329    fn default() -> Self {
330        <Denormal<BASE, B> as ::big_int::BigInt<BASE>>::default_inner()
331    }
332}
333
334impl<const BASE: usize, B: BigInt<{ BASE }>> ::std::fmt::Display for Denormal<BASE, B> {
335    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
336        <Denormal<BASE, B> as ::big_int::BigInt<BASE>>::fmt_inner(self, f)
337    }
338}
339
340impl<const BASE: usize, B: BigInt<{ BASE }>> ::std::cmp::PartialOrd for Denormal<BASE, B> {
341    fn partial_cmp(&self, other: &Self) -> ::std::option::Option<::std::cmp::Ordering> {
342        <Denormal<BASE, B> as ::big_int::BigInt<BASE>>::partial_cmp_inner(self, other)
343    }
344}
345
346impl<const BASE: usize, B: BigInt<{ BASE }>> ::std::cmp::Ord for Denormal<BASE, B> {
347    fn cmp(&self, other: &Self) -> ::std::cmp::Ordering {
348        <Denormal<BASE, B> as ::big_int::BigInt<BASE>>::cmp_inner(self, other)
349    }
350}
351
352impl<const BASE: usize, B: BigInt<{ BASE }>> ::std::cmp::PartialEq for Denormal<BASE, B> {
353    fn eq(&self, other: &Self) -> bool {
354        <Denormal<BASE, B> as ::big_int::BigInt<BASE>>::eq_inner(self, other)
355    }
356}
357
358impl<const BASE: usize, B: BigInt<{ BASE }>> ::std::cmp::Eq for Denormal<BASE, B> {}
359
360impl<const BASE: usize, B: BigInt<{ BASE }>> ::std::ops::Neg for Denormal<BASE, B> {
361    type Output = Self;
362
363    fn neg(self) -> Self::Output {
364        <Denormal<BASE, B> as ::big_int::BigInt<BASE>>::neg_inner(self)
365    }
366}
367
368impl<const BASE: usize, B: BigInt<{ BASE }>> ::std::ops::Add for Denormal<BASE, B> {
369    type Output = Self;
370
371    fn add(self, rhs: Self) -> Self::Output {
372        unsafe {
373            <Denormal<BASE, B> as ::big_int::BigInt<BASE>>::add_inner::<_, B>(self, rhs)
374                .unsafe_into()
375        }
376        .into()
377    }
378}
379
380impl<const BASE: usize, B: BigInt<{ BASE }>> ::std::ops::AddAssign for Denormal<BASE, B> {
381    fn add_assign(&mut self, rhs: Self) {
382        unsafe {
383            <Denormal<BASE, B> as ::big_int::BigInt<BASE>>::add_assign_inner(self, rhs);
384        }
385    }
386}
387
388impl<const BASE: usize, B: BigInt<{ BASE }>> ::std::ops::Sub for Denormal<BASE, B> {
389    type Output = Self;
390
391    fn sub(self, rhs: Self) -> Self::Output {
392        unsafe {
393            <Denormal<BASE, B> as ::big_int::BigInt<BASE>>::sub_inner::<_, B>(self, rhs)
394                .unsafe_into()
395        }
396        .into()
397    }
398}
399
400impl<const BASE: usize, B: BigInt<{ BASE }>> ::std::ops::SubAssign for Denormal<BASE, B> {
401    fn sub_assign(&mut self, rhs: Self) {
402        unsafe { <Denormal<BASE, B> as ::big_int::BigInt<BASE>>::sub_assign_inner(self, rhs) }
403    }
404}
405
406impl<const BASE: usize, B: BigInt<{ BASE }>> ::std::ops::Mul for Denormal<BASE, B> {
407    type Output = Self;
408
409    fn mul(self, rhs: Self) -> Self::Output {
410        unsafe {
411            <Denormal<BASE, B> as ::big_int::BigInt<BASE>>::mul_inner::<_, B>(self, rhs)
412                .unsafe_into()
413        }
414        .into()
415    }
416}
417
418impl<const BASE: usize, B: BigInt<{ BASE }>> ::std::ops::MulAssign for Denormal<BASE, B> {
419    fn mul_assign(&mut self, rhs: Self) {
420        unsafe { <Denormal<BASE, B> as ::big_int::BigInt<BASE>>::mul_assign_inner(self, rhs) }
421    }
422}
423
424impl<const BASE: usize, B: BigInt<{ BASE }>> ::std::ops::Div for Denormal<BASE, B> {
425    type Output = Self;
426
427    fn div(self, rhs: Self) -> Self::Output {
428        unsafe {
429            <Denormal<BASE, B> as UnsafeInto<B>>::unsafe_into(
430                <Denormal<BASE, B> as ::big_int::BigInt<BASE>>::div_inner::<_, Self>(self, rhs),
431            )
432        }
433        .into()
434    }
435}
436
437impl<const BASE: usize, B: BigInt<{ BASE }>> ::std::ops::DivAssign for Denormal<BASE, B> {
438    fn div_assign(&mut self, rhs: Self) {
439        unsafe { <Denormal<BASE, B> as ::big_int::BigInt<BASE>>::div_assign_inner(self, rhs) }
440    }
441}
442
443impl<const BASE: usize, B: BigInt<{ BASE }>> ::std::ops::Shl for Denormal<BASE, B> {
444    type Output = Self;
445
446    fn shl(self, rhs: Self) -> Self::Output {
447        <Denormal<BASE, B> as ::big_int::BigInt<BASE>>::shl_inner(self, rhs.into())
448    }
449}
450
451impl<const BASE: usize, B: BigInt<{ BASE }>> ::std::ops::ShlAssign for Denormal<BASE, B> {
452    fn shl_assign(&mut self, rhs: Self) {
453        unsafe {
454            <Denormal<BASE, B> as ::big_int::BigInt<BASE>>::shl_assign_inner(self, rhs.into())
455        }
456    }
457}
458
459impl<const BASE: usize, B: BigInt<{ BASE }>> ::std::ops::Shr for Denormal<BASE, B> {
460    type Output = Self;
461
462    fn shr(self, rhs: Self) -> Self::Output {
463        <Denormal<BASE, B> as ::big_int::BigInt<BASE>>::shr_inner(self, rhs.into())
464    }
465}
466
467impl<const BASE: usize, B: BigInt<{ BASE }>> ::std::ops::ShrAssign for Denormal<BASE, B> {
468    fn shr_assign(&mut self, rhs: Self) {
469        unsafe {
470            <Denormal<BASE, B> as ::big_int::BigInt<BASE>>::shr_assign_inner(self, rhs.into())
471        }
472    }
473}
474
475impl<const BASE: usize, B: BigInt<{ BASE }>> ::std::str::FromStr for Denormal<BASE, B> {
476    type Err = ::big_int::error::BigIntError;
477
478    fn from_str(s: &str) -> ::std::result::Result<Self, Self::Err> {
479        <Denormal<BASE, B> as ::big_int::BigInt<BASE>>::from_str_inner(s)
480            .map(|i| unsafe { <Denormal<BASE, B> as UnsafeInto<B>>::unsafe_into(i) }.into())
481    }
482}
483
484impl<const BASE: usize, B: BigInt<{ BASE }>> ::std::iter::FromIterator<::big_int::Digit>
485    for Denormal<BASE, B>
486{
487    fn from_iter<T: IntoIterator<Item = ::big_int::Digit>>(iter: T) -> Self {
488        <Denormal<BASE, B> as ::big_int::BigInt<BASE>>::from_iter_inner(iter)
489    }
490}
491
492impl<const BASE: usize, B: BigInt<{ BASE }>> ::std::iter::IntoIterator for Denormal<BASE, B> {
493    type Item = ::big_int::Digit;
494    type IntoIter = ::big_int::BigIntIntoIter<BASE, Self>;
495
496    fn into_iter(self) -> Self::IntoIter {
497        ::big_int::BigIntIntoIter(self)
498    }
499}
500
501impl<const BASE: usize, B: BigInt<{ BASE }>> ::std::convert::From<::std::vec::Vec<::big_int::Digit>>
502    for Denormal<BASE, B>
503{
504    fn from(value: ::std::vec::Vec<::big_int::Digit>) -> Self {
505        value.into_iter().collect()
506    }
507}
508
509macro_rules! int_conversions {
510    ($(($from:ident, $into:ident, $from_target_type:ident, [$($int:ident),*])),*) => {
511        $(
512            $(
513                impl<const BASE: usize, B: BigInt<{BASE}>> ::std::convert::From<$int> for Denormal<BASE, B> {
514                    fn from(value: $int) -> Self {
515                        <Denormal<BASE, B> as ::big_int::BigInt<BASE>>::$from(value as $from_target_type)
516                    }
517                }
518
519                impl<const BASE: usize, B: BigInt<{BASE}>> ::std::convert::From<Denormal<BASE, B>> for $int {
520                    fn from(value: Denormal<BASE, B>) -> Self {
521                        <Denormal<BASE, B> as ::big_int::BigInt<BASE>>::$into(value) as $int
522                    }
523                }
524            )*
525        )*
526    };
527}
528
529int_conversions!(
530    (
531        from_i128_inner,
532        into_i128_inner,
533        i128,
534        [i128, i64, i32, i16, i8, isize]
535    ),
536    (
537        from_u128_inner,
538        into_u128_inner,
539        u128,
540        [u128, u64, u32, u16, u8, usize]
541    )
542);
543
544/// A builder for a denormal int.
545///
546/// Exists purely clerically as a consequence of the abstractions present. Unlikely
547/// to be used directly.
548#[derive(Debug, Clone)]
549pub struct DenormalBuilder<const BASE: usize, B: BigIntBuilder<{ BASE }>>(B);
550
551impl<const BASE: usize, B: BigIntBuilder<{ BASE }>> BigIntBuilder<BASE>
552    for DenormalBuilder<BASE, B>
553{
554    fn new() -> Self {
555        Self(B::new())
556    }
557
558    fn push_front(&mut self, digit: Digit) {
559        self.0.push_front(digit);
560    }
561
562    fn push_back(&mut self, digit: Digit) {
563        self.0.push_back(digit);
564    }
565
566    fn is_empty(&self) -> bool {
567        self.0.is_empty()
568    }
569
570    fn with_sign(self, sign: Sign) -> Self {
571        Self(self.0.with_sign(sign))
572    }
573}
574
575impl<const BASE: usize, B: BigIntBuilder<{ BASE }> + Into<BB::Denormal>, BB: BigInt<{ BASE }>>
576    From<DenormalBuilder<BASE, B>> for Denormal<BASE, BB>
577{
578    fn from(value: DenormalBuilder<BASE, B>) -> Self {
579        unsafe { value.unsafe_into() }.into()
580    }
581}
582
583impl<const BASE: usize, B: BigInt<{ BASE }>> From<B> for Denormal<BASE, B> {
584    fn from(value: B) -> Self {
585        Denormal(value)
586    }
587}
588
589impl<const BASE: usize, B: BigInt<{ BASE }>> UnsafeInto<B> for Denormal<BASE, B> {
590    unsafe fn unsafe_into(self) -> B {
591        self.0
592    }
593}
594
595impl<const BASE: usize, B: BigInt<{ BASE }>> Unwrap<B> for Denormal<BASE, B> {
596    fn unwrap(self) -> B {
597        self.0.normalized()
598    }
599}
600
601impl<const BASE: usize, B: BigInt<{ BASE }>> Unwrap<Self> for Denormal<BASE, B> {
602    fn unwrap(self) -> Self {
603        self
604    }
605}