bigdecimal/bigdigit/
digitvec.rs

1//! Digit vectors (and slices) of arbitrary radix and endianness
2
3use crate::*;
4
5use stdlib::marker::PhantomData;
6use stdlib::num::NonZeroU64;
7
8use super::radix::*;
9use super::endian::*;
10
11use crate::rounding::NonDigitRoundingData;
12
13
14/// Vector of integers, interpreted as bigdigits in an integer
15///
16/// Value of the integer is defined by the radix and endianness
17/// type parameters.
18///
19#[derive(#[automatically_derived]
impl<R: ::core::clone::Clone + RadixType, E: ::core::clone::Clone +
    Endianness> ::core::clone::Clone for DigitVec<R, E> where
    R::Base: ::core::clone::Clone {
    #[inline]
    fn clone(&self) -> DigitVec<R, E> {
        DigitVec {
            digits: ::core::clone::Clone::clone(&self.digits),
            _radix: ::core::clone::Clone::clone(&self._radix),
            _endian: ::core::clone::Clone::clone(&self._endian),
        }
    }
}Clone, #[automatically_derived]
impl<R: ::core::default::Default + RadixType, E: ::core::default::Default +
    Endianness> ::core::default::Default for DigitVec<R, E> where
    R::Base: ::core::default::Default {
    #[inline]
    fn default() -> DigitVec<R, E> {
        DigitVec {
            digits: ::core::default::Default::default(),
            _radix: ::core::default::Default::default(),
            _endian: ::core::default::Default::default(),
        }
    }
}Default)]
20pub(crate) struct DigitVec<R: RadixType, E: Endianness> {
21    pub digits: Vec<R::Base>,
22    _radix: PhantomData<R>,
23    _endian: PhantomData<E>,
24}
25
26#[allow(dead_code)]
27impl<R: RadixType, E: Endianness> DigitVec<R, E> {
28    /// Create new vector
29    pub fn new() -> Self {
30        Self::from_vec(Vec::new())
31    }
32
33    /// Create new vector with capacity
34    pub fn with_capacity(n: usize) -> Self {
35        Self::from_vec(Vec::with_capacity(n))
36    }
37
38    /// construct from vector of digits
39    pub fn from_vec(v: Vec<R::Base>) -> Self {
40        if true {
    if !R::validate_digits(v.iter()) {
        { ::std::rt::panic_fmt(format_args!("{0:?}", v)); }
    };
};debug_assert!(R::validate_digits(v.iter()), "{:?}", v);
41        Self {
42            digits: v,
43            _radix: PhantomData {},
44            _endian: PhantomData {},
45        }
46    }
47
48    /// allocate with n bigdigits and fill with zeros
49    pub fn from_zero_count(n: usize) -> Self {
50        Self::from_vec(::alloc::vec::from_elem(Zero::zero(), n)vec![Zero::zero(); n])
51    }
52
53    /// Number of bigdigits in the vector
54    pub fn len(&self) -> usize {
55        self.digits.len()
56    }
57
58    /// Remove all bigdigits
59    pub fn clear(&mut self) {
60        self.digits.clear()
61    }
62
63    /// Resize inner vector, filling new values with zero
64    pub fn resize(&mut self, n: usize) {
65        self.digits.resize(n, Zero::zero())
66    }
67
68    /// Shrink inner vectory to new size
69    pub fn truncate(&mut self, n: usize) {
70        self.digits.truncate(n);
71    }
72
73    /// Remove 'n' insignificant from the vector
74    ///
75    /// BigEndian vectors truncate. LittleEndian vectors shift and truncate, and
76    /// remove significant zeros to reduce potential copy space
77    ///
78    /// If 'n' is larger than the vector, the vector is cleared.
79    ///
80    pub fn remove_insignificant_digits(&mut self, n: usize) {
81        if n == 0 {
82            return;
83        }
84        E::remove_insignificant_digits(&mut self.digits, n)
85    }
86
87    /// Borrow inner vectory as immutable digit-slice
88    pub fn as_digit_slice(&self) -> DigitSlice<'_, R, E> {
89        DigitSlice::from_slice(&self.digits[..])
90    }
91
92    /// Return slice skipping first n bigdigits
93    pub fn as_digit_slice_at(&self, n: usize) -> DigitSlice<'_, R, E> {
94        DigitSlice::from_slice(&self.digits[n..])
95    }
96
97    /// Borrow inner vectory as mutable digit-slice
98    pub fn as_digit_slice_mut(&mut self) -> DigitSliceMut<'_, R, E> {
99        DigitSliceMut::from_slice(&mut self.digits[..])
100    }
101
102    /// Split slice at 'pos' least-significant digits
103    pub fn split_le_at(
104        &self,
105        pos: usize
106    ) -> (DigitSlice<'_, R, E>, DigitSlice<'_, R, E>) {
107        let (lo, hi) = E::split_least_significant(&self.digits[..], pos);
108        (DigitSlice::from_slice(lo), DigitSlice::from_slice(hi))
109    }
110
111    /// Split slice at 'pos' least-significant digits
112    pub fn split_le_at_mut(
113        &mut self,
114        pos: usize,
115    ) -> (DigitSliceMut<'_, R, E>, DigitSliceMut<'_, R, E>) {
116        let (lo, hi) = E::split_least_significant_mut(&mut self.digits[..], pos);
117        (DigitSliceMut::from_slice(lo), DigitSliceMut::from_slice(hi))
118    }
119
120    /// Return the number of significant zeros in vector
121    pub fn count_significant_zeros(&self) -> usize {
122        E::count_significant_zeros(self.digits.as_slice())
123    }
124
125    /// true if empty or all zeros
126    pub fn is_all_zeros(&self) -> bool {
127        self.digits.iter().all(|&d| d.is_zero())
128    }
129
130    /// Return self, ignoring any significant zeros
131    pub fn least_n_are_zero(&self, n: usize) -> bool {
132        self.iter_le().take(n).all(Zero::is_zero)
133    }
134
135    /// Convert to inner vector
136    pub fn into_vec(self) -> Vec<R::Base> {
137        self.digits
138    }
139
140    /// Add bigdigit into this vector, starting from index of least significance
141    ///
142    /// Any "overflow" is pushed to most significant end of the vector
143    ///
144    pub fn add_value(&mut self, n: R::Base) {
145        self.add_value_at(0, n);
146    }
147
148    /// Add bigdigit into this vector (idexing from least-significant digit)
149    ///
150    /// TODO: Should vector resize if index is larger than size of vector?
151    ///
152    pub fn add_value_at(&mut self, idx: usize, n: R::Base) {
153        if true {
    if !(idx <= self.digits.len()) {
        ::core::panicking::panic("assertion failed: idx <= self.digits.len()")
    };
};debug_assert!(idx <= self.digits.len());
154
155        if n.is_zero() {
156            return;
157        }
158
159        let overflow = self.as_digit_slice_mut().add_value_at(0, n);
160        if !overflow.is_zero() {
161            self.push_significant_digit(overflow);
162        }
163    }
164
165    /// Add bigdigit to the significant end of the vec
166    pub fn push_significant_digit(&mut self, n: R::Base) {
167        E::push_significant_digit(&mut self.digits, n);
168    }
169
170    /// remove significant zeros
171    pub fn remove_leading_zeros(&mut self) {
172        E::strip_significant_zeros(&mut self.digits)
173    }
174
175    #[cfg(rustc_1_75)]
176    pub fn iter_le(&self) -> impl LeBigDigitIterator<'_, &R::Base> {
177        E::iter_slice(&self.digits[..])
178    }
179
180    #[cfg(not(rustc_1_75))]
181    pub fn iter_le(&self) -> LittleEndianBigDigitIter<'_, &R::Base> {
182        E::iter_slice(&self.digits[..])
183    }
184
185    #[cfg(rustc_1_75)]
186    pub fn iter_le_mut(&mut self) -> impl LeBigDigitIterator<'_, &mut R::Base> {
187        E::iter_slice_mut(&mut self.digits[..])
188    }
189
190    #[cfg(not(rustc_1_75))]
191    pub fn iter_le_mut(&mut self) -> LittleEndianBigDigitIter<'_, &mut R::Base> {
192        E::iter_slice_mut(&mut self.digits[..])
193    }
194}
195
196impl<R: RadixPowerOfTen, E: Endianness> DigitVec<R, E> {
197    pub fn count_decimal_digits(&self) -> usize {
198        self.as_digit_slice().count_decimal_digits()
199    }
200}
201
202#[allow(dead_code)]
203impl<R: RadixType> DigitVec<R, LittleEndian> {
204    /// allocate with n bigdigits and fill with zeros
205    pub fn remove_significant_digits(&mut self) {
206        if let Some(idx) = self.digits.iter().rposition(|d| !d.is_zero()) {
207            self.digits.truncate(idx);
208        }
209    }
210}
211
212#[allow(dead_code)]
213impl<R: RadixType> DigitVec<R, BigEndian> {
214    pub fn remove_significant_digits(&mut self) {
215        if let Some(idx) = self.digits.iter().position(|d| !d.is_zero()) {
216            self.digits.copy_within(idx.., 0);
217            self.digits.truncate(self.len() - idx);
218        }
219    }
220}
221
222#[allow(dead_code)]
223impl<E: Endianness> DigitVec<RADIX_u64, E> {
224    /// multiply this vector by 'n'
225    fn mulassign_u64(&mut self, n: u64) {
226        let mut carry = 0u64;
227        for digit in self.iter_le_mut() {
228            RADIX_u64::mulassign_add_carry(digit, n, &mut carry);
229        }
230        if !carry.is_zero() {
231            E::push_significant_digit(&mut self.digits, carry);
232        }
233    }
234}
235
236#[allow(dead_code)]
237impl DigitVec<RADIX_u64, LittleEndian> {
238    /// Convert to signed big integer
239    pub fn into_bigint(self, sign: Sign) -> BigInt {
240        BigInt::from_biguint(sign, self.into())
241    }
242
243    /// Construct vector from iterator of base-10^{19} bigdigits
244    #[allow(dead_code)]
245    pub fn from_10p19_digits<I: Iterator<Item = u64>>(mut digits: I) -> Self {
246        type R2p64 = RADIX_u64;
247        type R10p19 = RADIX_10p19_u64;
248
249        let mut v = <[_]>::into_vec(::alloc::boxed::box_new([digits.next().unwrap_or(0)]))vec![digits.next().unwrap_or(0)];
250
251        if let Some(d) = digits.next() {
252            let mut carry = 0;
253            R2p64::carrying_mul_add_inplace(
254                d, R10p19::RADIX as u64, &mut v[0], &mut carry
255            );
256            if carry != 0 {
257                v.push(carry);
258            }
259        }
260
261        let mut d = match digits.next() {
262            Some(d) => d,
263            None => {
264                return Self::from_vec(v);
265            }
266        };
267
268        let mut shifter = BigUint::from(R10p19::RADIX * R10p19::RADIX);
269
270        loop {
271            v.push(0);
272
273            if d != 0 {
274                let mut carry = 0;
275                let mut dest_digits = v.iter_mut();
276                let mut shifter_digits = shifter.iter_u64_digits();
277
278                loop {
279                    match (dest_digits.next(), shifter_digits.next()) {
280                        (Some(p), Some(s)) => {
281                            R2p64::carrying_mul_add_inplace(d, s, p, &mut carry);
282                        }
283                        (None, Some(mut s)) => {
284                            loop {
285                                let (hi, lo) = R2p64::fused_mul_add(s, d, carry);
286                                v.push(lo);
287                                carry = hi;
288                                s = match shifter_digits.next() {
289                                    None => break,
290                                    Some(x) => x,
291                                };
292                            }
293                            break;
294                        }
295                        (Some(p), None) if carry != 0 => {
296                            R2p64::addassign_carry(p, &mut carry);
297                        }
298                        _ => {
299                            break;
300                        }
301                    }
302                }
303                if !carry.is_zero() {
304                    v.push(carry);
305                }
306            }
307
308            d = match digits.next() {
309                Some(d) => d,
310                None => {
311                    let zero_idx = v.iter().rposition(|&d| d != 0).unwrap_or(0);
312                    v.truncate(zero_idx + 1);
313                    return Self::from_vec(v);
314                }
315            };
316
317            shifter *= R10p19::RADIX as u64;
318        }
319    }
320}
321
322impl From<&num_bigint::BigUint> for DigitVec<RADIX_u64, LittleEndian> {
323    fn from(n: &num_bigint::BigUint) -> Self {
324        Self::from_vec(n.iter_u64_digits().collect())
325    }
326}
327
328impl From<DigitVec<RADIX_u64, LittleEndian>> for num_bigint::BigUint {
329    fn from(v: DigitVec<RADIX_u64, LittleEndian>) -> Self {
330        // TODO: Can we do this conversion in place?
331        let mut digits = Vec::with_capacity(v.len() * 2);
332        for d in v.digits.into_iter() {
333            digits.push(d as u32);
334            digits.push((d >> 32) as u32);
335        }
336        Self::new(digits)
337    }
338}
339
340impl From<&DigitVec<RADIX_u64, LittleEndian>> for num_bigint::BigUint {
341    fn from(v: &DigitVec<RADIX_u64, LittleEndian>) -> Self {
342        let mut digits = Vec::with_capacity(v.len() * 2);
343        for &d in v.digits.iter() {
344            digits.push(d as u32);
345            digits.push((d >> 32) as u32);
346        }
347        Self::new(digits)
348    }
349}
350
351impl DigitVec<RADIX_10p19_u64, LittleEndian> {
352    /// Convert a num biguint into DigitVec, using tmp as scratchpad
353    pub(crate) fn from_biguint_using_tmp(
354        n: &num_bigint::BigUint,
355        tmp: &mut Vec<u64>,
356    ) -> Self {
357        tmp.clear();
358        tmp.extend(n.iter_u64_digits());
359        let result = Self::from_2p64le_vec(tmp);
360        // clear tmp so any residual digits are not accessible
361        tmp.clear();
362        result
363    }
364
365    /// remove the bottom 'n' digits in the vector, returning the highest
366    pub fn shift_n_digits_returning_high(&mut self, n: usize) -> u8 {
367        use bigdigit::alignment::BigDigitSplitter;
368        type Splitter = BigDigitSplitter<RADIX_10p19_u64>;
369
370        if n == 0 {
371            return 0;
372        }
373
374        let (bd_count, d_count) = n.div_rem(&19);
375
376        if d_count == 0 {
377            // insig is top digit on previous bigdigit
378            let ret = self.digits[bd_count - 1] / (RADIX_10p19_u64::RADIX as u64 / 10);
379            self.digits.copy_within(bd_count.., 0);
380            self.digits.truncate(self.len() - bd_count);
381            return ret as u8;
382        }
383
384        let mask = Splitter::mask_low(d_count as u8);
385        let (d0, insig) = mask.div_rem(self.digits[bd_count]);
386        let ret = mask.div(insig * 10) as u8;
387
388        let mut prev = d0;
389
390        let mut j = 0;
391
392        loop {
393            if let Some(&d) = self.digits.get(bd_count + 1 + j) {
394                let (hi, lo) = mask.split_and_shift(d);
395                self.digits[j] = lo + prev;
396                prev = hi;
397
398                j += 1;
399            } else {
400                if prev != 0 {
401                    self.digits[j] = prev;
402                    j += 1;
403                }
404                self.digits.truncate(j);
405                return ret;
406            }
407        }
408    }
409
410    /// Convert a base-2^64 DigitVec to 10^19 DigitVec
411    fn from_2p64le_vec(src: &mut Vec<u64>) -> Self {
412        type R = RADIX_10p19_u64;
413
414        let mut result: Vec<u64>;
415        match src.split_last() {
416            None => {
417                return Self::default();
418            }
419            Some((&top_digit, &[])) => {
420                let result = if top_digit < R::RADIX as u64 {
421                    <[_]>::into_vec(::alloc::boxed::box_new([top_digit]))vec![top_digit]
422                } else {
423                    let (hi, lo) = top_digit.div_rem(&(R::RADIX as u64));
424                    <[_]>::into_vec(::alloc::boxed::box_new([lo, hi]))vec![lo, hi]
425                };
426                return Self::from_vec(result);
427            }
428            Some((&top_digit, digits)) => {
429                let bit_count = (64 * digits.len()) + (64 - top_digit.leading_zeros() as usize);
430                let base2p64_bigdigit_count = (bit_count as f64) / (LOG2_10 * R::DIGITS as f64);
431                result = Vec::with_capacity(base2p64_bigdigit_count.ceil() as usize);
432            }
433        }
434        while let Some(pos) = src.iter().rposition(|&d| d != 0) {
435            src.truncate(pos + 1);
436            let rem: u64 = src.iter_mut().rev().fold(0, |acc, d| {
437                R::rotating_div_u64_radix(acc, d)
438            });
439            result.push(rem);
440        }
441        Self::from_vec(result)
442    }
443
444    /// Convert to a num BigInt with given sign
445    pub fn into_bigint(self, sign: Sign) -> BigInt {
446        let uint = self.into_biguint();
447        BigInt::from_biguint(sign, uint)
448    }
449
450    /// Convert to BigUint
451    pub fn into_biguint(self) -> BigUint {
452        use num_integer::div_rem;
453        let radix = <RADIX_10p19_u64 as RadixType>::RADIX;
454
455        let mut digits = self.digits.into_iter();
456        let d0 = digits.next().unwrap_or(0);
457        let mut result = BigUint::from(d0);
458
459        let n = match digits.next() {
460            None => {
461                return result;
462            }
463            Some(n) => n,
464        };
465
466        let mut scale = BigUint::from(radix);
467        result += n * &scale;
468
469        for digit in digits {
470            scale *= radix;
471            match digit {
472                0 => {}
473                1 => {
474                    result += &scale;
475                }
476                n => {
477                    result += n * &scale;
478                }
479            }
480        }
481        return result;
482    }
483}
484
485impl From<DigitVec<RADIX_u32, LittleEndian>> for num_bigint::BigUint {
486    fn from(v: DigitVec<RADIX_u32, LittleEndian>) -> Self {
487        Self::new(v.digits)
488    }
489}
490
491
492impl From<DigitVec<RADIX_10p19_u64, LittleEndian>> for num_bigint::BigUint {
493    fn from(v: DigitVec<RADIX_10p19_u64, LittleEndian>) -> Self {
494        type R = RADIX_10p19_u64;
495        let radix = R::RADIX as u64;
496        match v.digits.as_slice() {
497            &[] => {
498                Self::zero()
499            }
500            &[d] => {
501                Self::from(d)
502            }
503            &[d0, d1] => {
504                let mut result = Self::from(d1);
505                result *= radix;
506                result += d0;
507                return result;
508            }
509            _ => {
510                let mut shifter = Self::one();
511                let mut digits = v.digits.iter().rev();
512
513                let mut result: Self = digits.next().copied().unwrap().into();
514
515                for &d in digits {
516                    shifter *= radix;
517                    result *= &shifter;
518                    result += d;
519                }
520                result
521            }
522        }
523    }
524}
525
526impl From<DigitSlice<'_, RADIX_u64, LittleEndian>> for DigitVec<RADIX_10p19_u64, LittleEndian> {
527    fn from(v: DigitSlice<'_, RADIX_u64, LittleEndian>) -> Self {
528        let mut src = Vec::from(v.digits);
529        Self::from_2p64le_vec(&mut src)
530    }
531}
532
533impl From<DigitVec<RADIX_10p19_u64, LittleEndian>> for DigitVec<RADIX_u64, LittleEndian> {
534    fn from(mut src: DigitVec<RADIX_10p19_u64, LittleEndian>) -> Self {
535        type R2p64 = RADIX_u64;
536
537        let radix = RADIX_10p19_u64::RADIX as u64;
538
539        match src.digits.len() {
540            0 | 1 => {
541                Self::from_vec(src.digits)
542            }
543            2 => {
544                let (hi, lo) = R2p64::expanding_mul(src.digits[1], radix);
545                let (sum, overflow) = src.digits[0].overflowing_add(lo);
546                src.digits[0] = sum;
547                src.digits[1] = hi + u64::from(overflow);
548                if src.digits[1] == 0 {
549                    src.digits.truncate(1);
550                }
551                Self::from_vec(src.digits)
552            }
553            _ => {
554                let mut result = ::alloc::vec::from_elem(0, src.len())vec![0; src.len()];
555                result[0] = src.digits[0];
556
557                let mut scaler = BigInt::from(radix);
558                let mut base10_digits = src.digits.iter().skip(1);
559                let mut base10_digit = base10_digits.next().copied().unwrap_or(0);
560                loop {
561                    for (i, base2_digit) in scaler.iter_u64_digits().enumerate() {
562                        let (hi, lo) = R2p64::expanding_mul(base10_digit, base2_digit);
563                        let (sum, overflow) = result[i].overflowing_add(lo);
564                        result[i] = sum;
565                        let mut j = i + 1;
566                        let (sum, overflow) = result[j].overflowing_add(hi + u64::from(overflow));
567                        result[j] = sum;
568                        let mut carry = u64::from(overflow);
569                        while carry != 0 {
570                            j += 1;
571                            let (sum, overflow) = result[j].overflowing_add(carry);
572                            result[j] = sum;
573                            carry = u64::from(overflow);
574                        }
575                    }
576
577                    match base10_digits.next() {
578                        None => break,
579                        Some(&d) => base10_digit = d,
580                    }
581                    scaler *= radix;
582                }
583                Self::from_vec(result)
584            }
585        }
586    }
587}
588
589/// Convert BigUint to base-10 digits
590impl From<&num_bigint::BigUint> for DigitVec<RADIX_10_u8, LittleEndian> {
591    fn from(n: &num_bigint::BigUint) -> Self {
592        Self::from_vec(n.to_radix_le(10))
593    }
594}
595
596#[cfg(test)]
597mod test_from_biguint_using_tmp {
598    use super::*;
599    use crate::bigdigit::radix::RADIX_10p19_u64;
600
601    macro_rules! impl_case {
602        ($name:ident: $input:literal => $result:expr) => {
603            #[test]
604            fn $name() {
605                let n: BigUint = $input.parse().unwrap();
606
607                let mut tmp = Vec::new();
608                let vec = DigitVec::from_biguint_using_tmp(&n, &mut tmp);
609                let expected: &[u64] = &$result;
610                assert_eq!(vec.digits.as_slice(), expected);
611            }
612        };
613    }
614
615    impl_case!(test_zero: "0" => []);
616    impl_case!(test_3888089293362626678: "3888089293362626678" => [3888089293362626678]);
617    impl_case!(test_10000000000000000000: "10000000000000000000" => [0, 1]);
618    impl_case!(test_141905914:
619        "1419059141115374799211309048234647259918822773497033524702964376392264024748829821875106774"
620        => [
621            4748829821875106774,
622            2470296437639226402,
623            2599188227734970335,
624            4799211309048234647,
625                141905914111537,
626        ]);
627}
628
629/// Vector of base-10 digits
630#[allow(dead_code)]
631impl DigitVec<RADIX_10_u8, LittleEndian> {
632    /// splits digits into `prec` significant digits, returning the lowest significant digit,
633    /// highest insignificant digit, and the remaining insignificant digits in little endian order
634    ///
635    pub fn get_rounding_digits_at_prec(
636        &self,
637        prec: NonZeroU64,
638    ) -> (u8, u8, DigitSlice<'_, RADIX_10_u8, LittleEndian>) {
639        let trimmed = self.digits.len().saturating_sub(prec.get() as usize);
640        if trimmed == 0 {
641            return (0, 0, DigitSlice::from_slice(&[]));
642        }
643
644        let (insig_digits, sig_digits) = self.digits.split_at(trimmed);
645        if true {
    match (&trimmed, &insig_digits.len()) {
        (left_val, right_val) => {
            if !(*left_val == *right_val) {
                let kind = ::core::panicking::AssertKind::Eq;
                ::core::panicking::assert_failed(kind, &*left_val,
                    &*right_val, ::core::option::Option::None);
            }
        }
    };
};debug_assert_eq!(trimmed, insig_digits.len());
646        let (insig_digit, trailing_digits) = insig_digits.split_last().unwrap_or((&0, &[]));
647        (sig_digits[0], *insig_digit, DigitSlice::from_slice(trailing_digits))
648    }
649
650    /// Round the digits in this vec, returning slice of the digits
651    ///
652    /// Note: this changes the value of 'self', and should be considered as
653    /// just a buffer of bytes after rounding in place.
654    ///
655    pub fn round_at_prec_inplace(
656        &mut self,
657        prec: NonZeroU64,
658        rounding: NonDigitRoundingData,
659    ) -> (DigitSlice<'_, RADIX_10_u8, LittleEndian>, usize) {
660        // count number of insignificant digits to remove
661        let mut trimmed = self.digits.len().saturating_sub(prec.get() as usize);
662        if trimmed == 0 {
663            return (DigitSlice::from_slice(&self.digits), 0);
664        }
665
666        let (insig_digits, sig_digits) = self.digits.split_at_mut(trimmed);
667        if true {
    match (&trimmed, &insig_digits.len()) {
        (left_val, right_val) => {
            if !(*left_val == *right_val) {
                let kind = ::core::panicking::AssertKind::Eq;
                ::core::panicking::assert_failed(kind, &*left_val,
                    &*right_val, ::core::option::Option::None);
            }
        }
    };
};debug_assert_eq!(trimmed, insig_digits.len());
668
669        let (&insig_digit, insig_digits) = insig_digits.split_last().unwrap_or((&0, &[]));
670        let trailing_zeros = insig_digits.iter().all(|&d| d == 0);
671        let round = rounding.round_pair((sig_digits[0], insig_digit), trailing_zeros);
672
673        if round != 10 {
674            sig_digits[0] = round;
675        } else {
676            match sig_digits.iter().position(|&d| d != 9) {
677                Some(idx) => {
678                    sig_digits[idx] += 1;
679                    fill_slice_with_zero(&mut sig_digits[..idx]);
680                }
681                None => {
682                    fill_slice_with_zero(sig_digits);
683                    *sig_digits.last_mut().unwrap() = 1;
684                    trimmed += 1;
685                }
686            }
687        }
688
689        if true {
    match (&(prec.get() as usize), &sig_digits.len()) {
        (left_val, right_val) => {
            if !(*left_val == *right_val) {
                let kind = ::core::panicking::AssertKind::Eq;
                ::core::panicking::assert_failed(kind, &*left_val,
                    &*right_val, ::core::option::Option::None);
            }
        }
    };
};debug_assert_eq!(prec.get() as usize, sig_digits.len());
690        return (DigitSlice::from_slice(sig_digits), trimmed);
691    }
692}
693
694#[cfg(rustc_1_50)]
695#[allow(clippy::incompatible_msrv)]
696#[allow(dead_code)]
697fn fill_slice_with_zero<D: Zero + Clone>(s: &mut [D]) {
698    s.fill(Zero::zero());
699}
700
701#[cfg(not(rustc_1_50))]
702#[allow(dead_code)]
703fn fill_slice_with_zero<D: Zero + Clone>(s: &mut [D]) {
704    for r in s.iter_mut() {
705        *r = Zero::zero();
706    }
707}
708
709
710/// Immutable slice of digits
711///
712/// Operations on the bigdigit values are defined by the
713/// radix and endianness traits.
714///
715#[derive(#[automatically_derived]
impl<'a, R: ::core::clone::Clone + RadixType, E: ::core::clone::Clone +
    Endianness> ::core::clone::Clone for DigitSlice<'a, R, E> where
    R::Base: ::core::clone::Clone {
    #[inline]
    fn clone(&self) -> DigitSlice<'a, R, E> {
        DigitSlice {
            digits: ::core::clone::Clone::clone(&self.digits),
            _radix: ::core::clone::Clone::clone(&self._radix),
            _endian: ::core::clone::Clone::clone(&self._endian),
        }
    }
}Clone, #[automatically_derived]
impl<'a, R: ::core::marker::Copy + RadixType, E: ::core::marker::Copy +
    Endianness> ::core::marker::Copy for DigitSlice<'a, R, E> where
    R::Base: ::core::marker::Copy {
}Copy)]
716pub(crate) struct DigitSlice<'a, R: RadixType, E: Endianness> {
717    pub digits: &'a [R::Base],
718    _radix: PhantomData<R>,
719    _endian: PhantomData<E>,
720}
721
722#[allow(dead_code)]
723impl<'a, R: RadixType, E: Endianness> DigitSlice<'a, R, E> {
724    /// Wrap slice of numbers as a slice of big-digits with given radix
725    /// and endianness
726    ///
727    /// This does no validation, so the digits may be outside the bounds
728    /// of the radix and may have leading significant zeros.
729    ///
730    pub fn from_slice(d: &'a [R::Base]) -> Self {
731        Self {
732            digits: d,
733            _radix: PhantomData {},
734            _endian: PhantomData {},
735        }
736    }
737
738    /// Wrap slice of numbers, ignoring significant zeros
739    pub fn from_sig_slice(d: &'a [R::Base]) -> Self {
740        let (nonzero, _) = E::split_significant_zeros(d);
741        Self::from_slice(nonzero)
742    }
743
744    /// Number of bigdigits in slice
745    pub fn len(&self) -> usize {
746        self.digits.len()
747    }
748
749    /// Return self, ignoring any significant zeros
750    pub fn without_leading_zeros(&self) -> Self {
751        let (digits, _) = E::split_significant_zeros(self.digits);
752        Self::from_slice(digits)
753    }
754
755    /// Split splice into 'pos' least-significant bigdigits, and remaining
756    pub fn split_le_at(&'a self, pos: usize) -> (Self, Self) {
757        let (lo, hi) = E::split_least_significant(self.digits, pos);
758        (Self::from_slice(lo), Self::from_slice(hi))
759    }
760
761    /// Return the number of significant zeros
762    pub fn count_significant_zeros(&self) -> usize {
763        E::count_significant_zeros(self.digits)
764    }
765
766    /// true if empty or all zeros
767    pub fn is_all_zeros(&self) -> bool {
768        self.digits.iter().all(|&d| d.is_zero())
769    }
770
771    /// Return self, ignoring any significant zeros
772    pub fn least_n_are_zero(&self, n: usize) -> bool {
773        self.iter_le().take(n).all(Zero::is_zero)
774    }
775
776    #[cfg(rustc_1_75)]
777    pub fn iter_le(&self) -> impl LeBigDigitIterator<'_, &R::Base> {
778        E::iter_slice(self.digits)
779    }
780
781    #[cfg(not(rustc_1_75))]
782    pub fn iter_le(&self) -> LittleEndianBigDigitIter<'_, &R::Base> {
783        E::iter_slice(self.digits)
784    }
785}
786
787#[allow(dead_code)]
788impl<R: RadixType> DigitSlice<'_, R, LittleEndian> {
789    /// Return subslice of digits with the 'n' least significant bigdigits removed
790    pub fn trim_insignificant(&self, n: usize) -> Self {
791        Self::from_slice(&self.digits[n..])
792    }
793
794    pub fn find_least_significant_nonzero(&self) -> Option<usize> {
795        self.digits.iter().position(|&d| !d.is_zero())
796    }
797}
798
799#[allow(dead_code)]
800impl<'a, E: Endianness> From<&'a DigitVec<RADIX_u64, E>> for DigitSlice<'a, RADIX_u64, E> {
801    fn from(v: &'a DigitVec<RADIX_u64, E>) -> Self {
802        v.as_digit_slice()
803    }
804}
805
806impl<'a, R: RadixPowerOfTen, E: Endianness> DigitSlice<'a, R, E> {
807    pub fn count_decimal_digits(&self) -> usize {
808        use crate::arithmetic::decimal::count_digits_u64;
809
810        let (top_digit, trailing) = E::split_most_significant_digit(self.digits);
811        R::DIGITS * trailing.len()
812            + count_digits_u64(top_digit.to_u64().unwrap())
813    }
814}
815
816impl DigitSlice<'_, RADIX_10_u8, LittleEndian> {
817    /// fill digitvec with value contained in this digit-slice
818    #[allow(dead_code)]
819    pub fn fill_vec_u64(&self, dest: &mut DigitVec<RADIX_u64, LittleEndian>) {
820        let n = num_bigint::BigUint::from_radix_le(self.digits, 10).unwrap();
821        *dest = (&n).into();
822    }
823}
824
825/// Mutable slice of bigdigit values
826pub(crate) struct DigitSliceMut<'a, R: RadixType, E: Endianness> {
827    pub digits: &'a mut [R::Base],
828    _radix: PhantomData<R>,
829    _endian: PhantomData<E>,
830}
831
832#[allow(dead_code)]
833impl<'a, R: RadixType, E: Endianness> DigitSliceMut<'a, R, E> {
834    /// Construct from mutable slice of numbers
835    pub fn from_slice(v: &'a mut [R::Base]) -> Self {
836        Self {
837            digits: v,
838            _radix: PhantomData {},
839            _endian: PhantomData {},
840        }
841    }
842
843    /// Number of bigdigits in slice
844    pub fn len(&self) -> usize {
845        self.digits.len()
846    }
847
848    /// From digitvec, offset from the true index (independent of endianness)
849    pub fn from_vec_offset(v: &'a mut DigitVec<R, E>, offset: usize) -> Self {
850        Self::from_slice(&mut v.digits[offset..])
851    }
852
853    /// Cast to immutable slice
854    pub fn as_digit_slice(&'a self) -> DigitSlice<'a, R, E> {
855        DigitSlice::from_slice(self.digits)
856    }
857
858    /// Split, returning 'pos' little-endian
859    pub fn split_le_at(&'a self, pos: usize) -> (DigitSlice<'a, R, E>, DigitSlice<'a, R, E>) {
860        let (lo, hi) = E::split_least_significant(&self.digits[..], pos);
861        (DigitSlice::from_slice(lo), DigitSlice::from_slice(hi))
862    }
863
864    /// Split, returning 'pos' little-endian
865    pub fn split_le_at_mut(&'a mut self, pos: usize) -> (Self, Self) {
866        let (lo, hi) = E::split_least_significant_mut(self.digits, pos);
867        (Self::from_slice(lo), Self::from_slice(hi))
868    }
869
870    /// Add bigdigit 'n' into this slice, returning overflow
871    pub fn add_value_at(&mut self, idx: usize, mut n: R::Base) -> R::Base {
872        if n.is_zero() {
873            return n;
874        }
875        E::addassign_carry_into_slice_at::<R>(self.digits, &mut n, idx);
876        n
877    }
878
879    /// Add bigdigit into vector, storing overflow back in c
880    pub fn addassign_carry(&mut self, c: &mut R::Base) {
881        E::addassign_carry_into_slice_at::<R>(self.digits, c, 0);
882    }
883
884    #[cfg(rustc_1_75)]
885    pub fn iter_le(&self) -> impl LeBigDigitIterator<'_, &R::Base> {
886        E::iter_slice(self.digits)
887    }
888
889    #[cfg(not(rustc_1_75))]
890    pub fn iter_le(&self) -> LittleEndianBigDigitIter<'_, &R::Base> {
891        E::iter_slice(self.digits)
892    }
893
894    #[cfg(rustc_1_75)]
895    pub fn iter_le_mut(&mut self) -> impl LeBigDigitIterator<'_, &mut R::Base> {
896        E::iter_slice_mut(self.digits)
897    }
898
899    #[cfg(not(rustc_1_75))]
900    pub fn iter_le_mut(&mut self) -> LittleEndianBigDigitIter<'_, &mut R::Base> {
901        E::iter_slice_mut(self.digits)
902    }
903}
904
905#[allow(dead_code)]
906impl<R: RadixPowerOfTen, E: Endianness> DigitSliceMut<'_, R, E> {
907    pub fn count_decimal_digits(&self) -> usize {
908        self.as_digit_slice().count_decimal_digits()
909    }
910}
911
912
913impl<'a, R: RadixType, E: Endianness> From<&'a mut Vec<R::Base>> for DigitSliceMut<'a, R, E> {
914    fn from(digits: &'a mut Vec<R::Base>) -> Self {
915        Self::from_slice(&mut digits[..])
916    }
917}
918
919impl<R: RadixType, E: Endianness> fmt::Debug for DigitVec<R, E> {
920    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
921        f.write_fmt(format_args!("DigitVec({0}, {1:?})", E::NAME, self.digits))write!(f, "DigitVec({}, {:?})", E::NAME, self.digits)
922    }
923}
924
925impl<R: RadixType, E: Endianness> fmt::Debug for DigitSlice<'_, R, E> {
926    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
927        f.write_fmt(format_args!("DigitSlice({0}, {1:?})", E::NAME, self.digits))write!(f, "DigitSlice({}, {:?})", E::NAME, self.digits)
928    }
929}
930
931impl<R: RadixType, E: Endianness> fmt::Debug for DigitSliceMut<'_, R, E> {
932    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
933        f.write_fmt(format_args!("DigitSliceMut({0}, {1:?})", E::NAME, self.digits))write!(f, "DigitSliceMut({}, {:?})", E::NAME, self.digits)
934    }
935}
936
937/// Add method to easily transform scaled DigitVec to scaled DigitSlice
938impl<R: RadixType, E: Endianness> crate::WithScale<DigitVec<R, E>> {
939    pub fn as_digit_slice(&self) -> crate::WithScale<DigitSlice<'_, R, E>> {
940        WithScale {
941            scale: self.scale,
942            value: self.value.as_digit_slice(),
943        }
944    }
945}