1use 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)]
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 pub fn new() -> Self {
30 Self::from_vec(Vec::new())
31 }
32
33 pub fn with_capacity(n: usize) -> Self {
35 Self::from_vec(Vec::with_capacity(n))
36 }
37
38 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 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 pub fn len(&self) -> usize {
55 self.digits.len()
56 }
57
58 pub fn clear(&mut self) {
60 self.digits.clear()
61 }
62
63 pub fn resize(&mut self, n: usize) {
65 self.digits.resize(n, Zero::zero())
66 }
67
68 pub fn truncate(&mut self, n: usize) {
70 self.digits.truncate(n);
71 }
72
73 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 pub fn as_digit_slice(&self) -> DigitSlice<'_, R, E> {
89 DigitSlice::from_slice(&self.digits[..])
90 }
91
92 pub fn as_digit_slice_at(&self, n: usize) -> DigitSlice<'_, R, E> {
94 DigitSlice::from_slice(&self.digits[n..])
95 }
96
97 pub fn as_digit_slice_mut(&mut self) -> DigitSliceMut<'_, R, E> {
99 DigitSliceMut::from_slice(&mut self.digits[..])
100 }
101
102 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 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 pub fn count_significant_zeros(&self) -> usize {
122 E::count_significant_zeros(self.digits.as_slice())
123 }
124
125 pub fn is_all_zeros(&self) -> bool {
127 self.digits.iter().all(|&d| d.is_zero())
128 }
129
130 pub fn least_n_are_zero(&self, n: usize) -> bool {
132 self.iter_le().take(n).all(Zero::is_zero)
133 }
134
135 pub fn into_vec(self) -> Vec<R::Base> {
137 self.digits
138 }
139
140 pub fn add_value(&mut self, n: R::Base) {
145 self.add_value_at(0, n);
146 }
147
148 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 pub fn push_significant_digit(&mut self, n: R::Base) {
167 E::push_significant_digit(&mut self.digits, n);
168 }
169
170 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 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 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 pub fn into_bigint(self, sign: Sign) -> BigInt {
240 BigInt::from_biguint(sign, self.into())
241 }
242
243 #[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 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 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 tmp.clear();
362 result
363 }
364
365 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 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 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 pub fn into_bigint(self, sign: Sign) -> BigInt {
446 let uint = self.into_biguint();
447 BigInt::from_biguint(sign, uint)
448 }
449
450 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
589impl 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#[allow(dead_code)]
631impl DigitVec<RADIX_10_u8, LittleEndian> {
632 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 pub fn round_at_prec_inplace(
656 &mut self,
657 prec: NonZeroU64,
658 rounding: NonDigitRoundingData,
659 ) -> (DigitSlice<'_, RADIX_10_u8, LittleEndian>, usize) {
660 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)]
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 pub fn from_slice(d: &'a [R::Base]) -> Self {
731 Self {
732 digits: d,
733 _radix: PhantomData {},
734 _endian: PhantomData {},
735 }
736 }
737
738 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 pub fn len(&self) -> usize {
746 self.digits.len()
747 }
748
749 pub fn without_leading_zeros(&self) -> Self {
751 let (digits, _) = E::split_significant_zeros(self.digits);
752 Self::from_slice(digits)
753 }
754
755 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 pub fn count_significant_zeros(&self) -> usize {
763 E::count_significant_zeros(self.digits)
764 }
765
766 pub fn is_all_zeros(&self) -> bool {
768 self.digits.iter().all(|&d| d.is_zero())
769 }
770
771 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 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 #[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
825pub(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 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 pub fn len(&self) -> usize {
845 self.digits.len()
846 }
847
848 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 pub fn as_digit_slice(&'a self) -> DigitSlice<'a, R, E> {
855 DigitSlice::from_slice(self.digits)
856 }
857
858 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 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 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 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
937impl<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}