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#[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 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(crate) fn from_u128(n: u128) -> Self {
75 let mut v = Self::new();
76 v.fill_with_u128(n);
77 v
78 }
79
80 pub(crate) fn fill_with_u128(&mut self, n: u128) {
82 E::fill_vec_with_u128::<R>(&mut self.digits, n);
83 }
84
85 pub fn remove_insignificant_digits(&mut self, n: usize) {
93 if n == 0 {
94 return;
95 }
96 E::remove_insignificant_digits(&mut self.digits, n)
97 }
98
99 pub fn as_digit_slice(&self) -> DigitSlice<'_, R, E> {
101 DigitSlice::from_slice(&self.digits[..])
102 }
103
104 pub fn as_digit_slice_at(&self, n: usize) -> DigitSlice<'_, R, E> {
106 DigitSlice::from_slice(&self.digits[n..])
107 }
108
109 pub fn as_digit_slice_mut(&mut self) -> DigitSliceMut<'_, R, E> {
111 DigitSliceMut::from_slice(&mut self.digits[..])
112 }
113
114 pub fn split_le_at(
116 &self,
117 pos: usize
118 ) -> (DigitSlice<'_, R, E>, DigitSlice<'_, R, E>) {
119 let (lo, hi) = E::split_least_significant(&self.digits[..], pos);
120 (DigitSlice::from_slice(lo), DigitSlice::from_slice(hi))
121 }
122
123 pub fn split_le_at_mut(
125 &mut self,
126 pos: usize,
127 ) -> (DigitSliceMut<'_, R, E>, DigitSliceMut<'_, R, E>) {
128 let (lo, hi) = E::split_least_significant_mut(&mut self.digits[..], pos);
129 (DigitSliceMut::from_slice(lo), DigitSliceMut::from_slice(hi))
130 }
131
132 pub fn count_significant_zeros(&self) -> usize {
134 E::count_significant_zeros(self.digits.as_slice())
135 }
136
137 pub fn is_all_zeros(&self) -> bool {
139 self.digits.iter().all(|&d| d.is_zero())
140 }
141
142 pub fn least_n_are_zero(&self, n: usize) -> bool {
144 self.iter_le().take(n).all(Zero::is_zero)
145 }
146
147 pub fn into_vec(self) -> Vec<R::Base> {
149 self.digits
150 }
151
152 pub fn add_value(&mut self, n: R::Base) {
157 self.add_value_at(0, n);
158 }
159
160 pub fn add_value_at(&mut self, idx: usize, n: R::Base) {
165 if true {
if !(idx <= self.digits.len()) {
::core::panicking::panic("assertion failed: idx <= self.digits.len()")
};
};debug_assert!(idx <= self.digits.len());
166
167 if n.is_zero() {
168 return;
169 }
170
171 let overflow = self.as_digit_slice_mut().add_value_at(idx, n);
172 if !overflow.is_zero() {
173 self.push_significant_digit(overflow);
174 }
175 }
176
177 pub fn push_significant_digit(&mut self, n: R::Base) {
179 E::push_significant_digit(&mut self.digits, n);
180 }
181
182 pub fn remove_leading_zeros(&mut self) {
184 E::strip_significant_zeros(&mut self.digits)
185 }
186
187 #[cfg(rustc_1_75)]
188 pub fn iter_le(&self) -> impl LeBigDigitIterator<'_, &R::Base> {
189 E::iter_slice(&self.digits[..])
190 }
191
192 #[cfg(not(rustc_1_75))]
193 pub fn iter_le(&self) -> LittleEndianBigDigitIter<'_, &R::Base> {
194 E::iter_slice(&self.digits[..])
195 }
196
197 #[cfg(rustc_1_75)]
198 pub fn iter_le_mut(&mut self) -> impl LeBigDigitIterator<'_, &mut R::Base> {
199 E::iter_slice_mut(&mut self.digits[..])
200 }
201
202 #[cfg(not(rustc_1_75))]
203 pub fn iter_le_mut(&mut self) -> LittleEndianBigDigitIter<'_, &mut R::Base> {
204 E::iter_slice_mut(&mut self.digits[..])
205 }
206}
207
208impl<R: RadixPowerOfTen, E: Endianness> DigitVec<R, E> {
209 pub fn count_decimal_digits(&self) -> usize {
210 self.as_digit_slice().count_decimal_digits()
211 }
212}
213
214#[allow(dead_code)]
215impl<R: RadixType> DigitVec<R, LittleEndian> {
216 pub fn remove_significant_digits(&mut self) {
218 if let Some(idx) = self.digits.iter().rposition(|d| !d.is_zero()) {
219 self.digits.truncate(idx);
220 }
221 }
222}
223
224#[allow(dead_code)]
225impl<R: RadixType> DigitVec<R, BigEndian> {
226 pub fn remove_significant_digits(&mut self) {
227 if let Some(idx) = self.digits.iter().position(|d| !d.is_zero()) {
228 self.digits.copy_within(idx.., 0);
229 self.digits.truncate(self.len() - idx);
230 }
231 }
232}
233
234#[allow(dead_code)]
235impl<E: Endianness> DigitVec<RADIX_u64, E> {
236 fn mulassign_u64(&mut self, n: u64) {
238 let mut carry = 0u64;
239 for digit in self.iter_le_mut() {
240 RADIX_u64::mulassign_add_carry(digit, n, &mut carry);
241 }
242 if !carry.is_zero() {
243 E::push_significant_digit(&mut self.digits, carry);
244 }
245 }
246}
247
248#[allow(dead_code)]
249impl DigitVec<RADIX_u64, LittleEndian> {
250 pub fn into_bigint(self, sign: Sign) -> BigInt {
252 BigInt::from_biguint(sign, self.into())
253 }
254
255 #[allow(dead_code)]
257 pub fn from_10p19_digits<I: Iterator<Item = u64>>(mut digits: I) -> Self {
258 type R2p64 = RADIX_u64;
259 type R10p19 = RADIX_10p19_u64;
260
261 let mut v = <[_]>::into_vec(::alloc::boxed::box_new([digits.next().unwrap_or(0)]))vec![digits.next().unwrap_or(0)];
262
263 if let Some(d) = digits.next() {
264 let mut carry = 0;
265 R2p64::carrying_mul_add_inplace(
266 d, R10p19::RADIX as u64, &mut v[0], &mut carry
267 );
268 if carry != 0 {
269 v.push(carry);
270 }
271 }
272
273 let mut d = match digits.next() {
274 Some(d) => d,
275 None => {
276 return Self::from_vec(v);
277 }
278 };
279
280 let mut shifter = BigUint::from(R10p19::RADIX * R10p19::RADIX);
281
282 loop {
283 v.push(0);
284
285 if d != 0 {
286 let mut carry = 0;
287 let mut dest_digits = v.iter_mut();
288 let mut shifter_digits = shifter.iter_u64_digits();
289
290 loop {
291 match (dest_digits.next(), shifter_digits.next()) {
292 (Some(p), Some(s)) => {
293 R2p64::carrying_mul_add_inplace(d, s, p, &mut carry);
294 }
295 (None, Some(mut s)) => {
296 loop {
297 let (hi, lo) = R2p64::fused_mul_add(s, d, carry);
298 v.push(lo);
299 carry = hi;
300 s = match shifter_digits.next() {
301 None => break,
302 Some(x) => x,
303 };
304 }
305 break;
306 }
307 (Some(p), None) if carry != 0 => {
308 R2p64::addassign_carry(p, &mut carry);
309 }
310 _ => {
311 break;
312 }
313 }
314 }
315 if !carry.is_zero() {
316 v.push(carry);
317 }
318 }
319
320 d = match digits.next() {
321 Some(d) => d,
322 None => {
323 let zero_idx = v.iter().rposition(|&d| d != 0).unwrap_or(0);
324 v.truncate(zero_idx + 1);
325 return Self::from_vec(v);
326 }
327 };
328
329 shifter *= R10p19::RADIX as u64;
330 }
331 }
332}
333
334impl From<&num_bigint::BigUint> for DigitVec<RADIX_u64, LittleEndian> {
335 fn from(n: &num_bigint::BigUint) -> Self {
336 Self::from_vec(n.iter_u64_digits().collect())
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);
344 for d in v.digits.into_iter() {
345 digits.push(d as u32);
346 digits.push((d >> 32) as u32);
347 }
348 Self::new(digits)
349 }
350}
351
352impl From<&DigitVec<RADIX_u64, LittleEndian>> for num_bigint::BigUint {
353 fn from(v: &DigitVec<RADIX_u64, LittleEndian>) -> Self {
354 let mut digits = Vec::with_capacity(v.len() * 2);
355 for &d in v.digits.iter() {
356 digits.push(d as u32);
357 digits.push((d >> 32) as u32);
358 }
359 Self::new(digits)
360 }
361}
362
363impl DigitVec<RADIX_10p19_u64, LittleEndian> {
364 pub(crate) fn from_biguint_using_tmp(
366 n: &num_bigint::BigUint,
367 tmp: &mut Vec<u64>,
368 ) -> Self {
369 tmp.clear();
370 tmp.extend(n.iter_u64_digits());
371 let result = Self::from_2p64le_vec(tmp);
372 tmp.clear();
374 result
375 }
376
377 pub fn shift_n_digits_returning_high(&mut self, n: usize) -> u8 {
379 use bigdigit::alignment::BigDigitSplitter;
380 type Splitter = BigDigitSplitter<RADIX_10p19_u64>;
381
382 if n == 0 {
383 return 0;
384 }
385
386 let (bd_count, d_count) = n.div_rem(&19);
387
388 if d_count == 0 {
389 let ret = self.digits[bd_count - 1] / (RADIX_10p19_u64::RADIX as u64 / 10);
391 self.digits.copy_within(bd_count.., 0);
392 self.digits.truncate(self.len() - bd_count);
393 return ret as u8;
394 }
395
396 let mask = Splitter::mask_low(d_count as u8);
397 let (d0, insig) = mask.div_rem(self.digits[bd_count]);
398 let ret = mask.div(insig * 10) as u8;
399
400 let mut prev = d0;
401
402 let mut j = 0;
403
404 loop {
405 if let Some(&d) = self.digits.get(bd_count + 1 + j) {
406 let (hi, lo) = mask.split_and_shift(d);
407 self.digits[j] = lo + prev;
408 prev = hi;
409
410 j += 1;
411 } else {
412 if prev != 0 {
413 self.digits[j] = prev;
414 j += 1;
415 }
416 self.digits.truncate(j);
417 return ret;
418 }
419 }
420 }
421
422 fn from_2p64le_vec(src: &mut Vec<u64>) -> Self {
424 type R = RADIX_10p19_u64;
425
426 let mut result: Vec<u64>;
427 match src.split_last() {
428 None => {
429 return Self::default();
430 }
431 Some((&top_digit, &[])) => {
432 let result = if top_digit < R::RADIX as u64 {
433 <[_]>::into_vec(::alloc::boxed::box_new([top_digit]))vec![top_digit]
434 } else {
435 let (hi, lo) = top_digit.div_rem(&(R::RADIX as u64));
436 <[_]>::into_vec(::alloc::boxed::box_new([lo, hi]))vec![lo, hi]
437 };
438 return Self::from_vec(result);
439 }
440 Some((&top_digit, digits)) => {
441 let bit_count = (64 * digits.len()) + (64 - top_digit.leading_zeros() as usize);
442 let base2p64_bigdigit_count = (bit_count as f64) / (LOG2_10 * R::DIGITS as f64);
443 result = Vec::with_capacity(base2p64_bigdigit_count.ceil() as usize);
444 }
445 }
446 while let Some(pos) = src.iter().rposition(|&d| d != 0) {
447 src.truncate(pos + 1);
448 let rem: u64 = src.iter_mut().rev().fold(0, |acc, d| {
449 R::rotating_div_u64_radix(acc, d)
450 });
451 result.push(rem);
452 }
453 Self::from_vec(result)
454 }
455
456 pub fn into_bigint(self, sign: Sign) -> BigInt {
458 let uint = self.into_biguint();
459 BigInt::from_biguint(sign, uint)
460 }
461
462 pub fn into_biguint(self) -> BigUint {
464 use num_integer::div_rem;
465 let radix = <RADIX_10p19_u64 as RadixType>::RADIX;
466
467 let mut digits = self.digits.into_iter();
468 let d0 = digits.next().unwrap_or(0);
469 let mut result = BigUint::from(d0);
470
471 let n = match digits.next() {
472 None => {
473 return result;
474 }
475 Some(n) => n,
476 };
477
478 let mut scale = BigUint::from(radix);
479 result += n * &scale;
480
481 for digit in digits {
482 scale *= radix;
483 match digit {
484 0 => {}
485 1 => {
486 result += &scale;
487 }
488 n => {
489 result += n * &scale;
490 }
491 }
492 }
493 return result;
494 }
495}
496
497impl From<DigitVec<RADIX_u32, LittleEndian>> for num_bigint::BigUint {
498 fn from(v: DigitVec<RADIX_u32, LittleEndian>) -> Self {
499 Self::new(v.digits)
500 }
501}
502
503
504impl From<DigitVec<RADIX_10p19_u64, LittleEndian>> for num_bigint::BigUint {
505 fn from(v: DigitVec<RADIX_10p19_u64, LittleEndian>) -> Self {
506 type R = RADIX_10p19_u64;
507 let radix = R::RADIX as u64;
508 match v.digits.as_slice() {
509 &[] => {
510 Self::zero()
511 }
512 &[d] => {
513 Self::from(d)
514 }
515 &[d0, d1] => {
516 let mut result = Self::from(d1);
517 result *= radix;
518 result += d0;
519 return result;
520 }
521 _ => {
522 let mut shifter = Self::one();
523 let mut digits = v.digits.iter().rev();
524
525 let mut result: Self = digits.next().copied().unwrap().into();
526
527 for &d in digits {
528 shifter *= radix;
529 result *= &shifter;
530 result += d;
531 }
532 result
533 }
534 }
535 }
536}
537
538impl From<DigitSlice<'_, RADIX_u64, LittleEndian>> for DigitVec<RADIX_10p19_u64, LittleEndian> {
539 fn from(v: DigitSlice<'_, RADIX_u64, LittleEndian>) -> Self {
540 let mut src = Vec::from(v.digits);
541 Self::from_2p64le_vec(&mut src)
542 }
543}
544
545impl From<DigitVec<RADIX_10p19_u64, LittleEndian>> for DigitVec<RADIX_u64, LittleEndian> {
546 fn from(mut src: DigitVec<RADIX_10p19_u64, LittleEndian>) -> Self {
547 type R2p64 = RADIX_u64;
548
549 let radix = RADIX_10p19_u64::RADIX as u64;
550
551 match src.digits.len() {
552 0 | 1 => {
553 Self::from_vec(src.digits)
554 }
555 2 => {
556 let (hi, lo) = R2p64::expanding_mul(src.digits[1], radix);
557 let (sum, overflow) = src.digits[0].overflowing_add(lo);
558 src.digits[0] = sum;
559 src.digits[1] = hi + u64::from(overflow);
560 if src.digits[1] == 0 {
561 src.digits.truncate(1);
562 }
563 Self::from_vec(src.digits)
564 }
565 _ => {
566 let mut result = ::alloc::vec::from_elem(0, src.len())vec![0; src.len()];
567 result[0] = src.digits[0];
568
569 let mut scaler = BigInt::from(radix);
570 let mut base10_digits = src.digits.iter().skip(1);
571 let mut base10_digit = base10_digits.next().copied().unwrap_or(0);
572 loop {
573 for (i, base2_digit) in scaler.iter_u64_digits().enumerate() {
574 let (hi, lo) = R2p64::expanding_mul(base10_digit, base2_digit);
575 let (sum, overflow) = result[i].overflowing_add(lo);
576 result[i] = sum;
577 let mut j = i + 1;
578 let (sum, overflow) = result[j].overflowing_add(hi + u64::from(overflow));
579 result[j] = sum;
580 let mut carry = u64::from(overflow);
581 while carry != 0 {
582 j += 1;
583 let (sum, overflow) = result[j].overflowing_add(carry);
584 result[j] = sum;
585 carry = u64::from(overflow);
586 }
587 }
588
589 match base10_digits.next() {
590 None => break,
591 Some(&d) => base10_digit = d,
592 }
593 scaler *= radix;
594 }
595 Self::from_vec(result)
596 }
597 }
598 }
599}
600
601impl From<&num_bigint::BigUint> for DigitVec<RADIX_10_u8, LittleEndian> {
603 fn from(n: &num_bigint::BigUint) -> Self {
604 Self::from_vec(n.to_radix_le(10))
605 }
606}
607
608#[cfg(test)]
609mod test_from_biguint_using_tmp {
610 use super::*;
611 use crate::bigdigit::radix::RADIX_10p19_u64;
612
613 macro_rules! impl_case {
614 ($name:ident: $input:literal => $result:expr) => {
615 #[test]
616 fn $name() {
617 let n: BigUint = $input.parse().unwrap();
618
619 let mut tmp = Vec::new();
620 let vec = DigitVec::from_biguint_using_tmp(&n, &mut tmp);
621 let expected: &[u64] = &$result;
622 assert_eq!(vec.digits.as_slice(), expected);
623 }
624 };
625 }
626
627 impl_case!(test_zero: "0" => []);
628 impl_case!(test_3888089293362626678: "3888089293362626678" => [3888089293362626678]);
629 impl_case!(test_10000000000000000000: "10000000000000000000" => [0, 1]);
630 impl_case!(test_141905914:
631 "1419059141115374799211309048234647259918822773497033524702964376392264024748829821875106774"
632 => [
633 4748829821875106774,
634 2470296437639226402,
635 2599188227734970335,
636 4799211309048234647,
637 141905914111537,
638 ]);
639}
640
641#[allow(dead_code)]
643impl DigitVec<RADIX_10_u8, LittleEndian> {
644 pub fn get_rounding_digits_at_prec(
648 &self,
649 prec: NonZeroU64,
650 ) -> (u8, u8, DigitSlice<'_, RADIX_10_u8, LittleEndian>) {
651 let trimmed = self.digits.len().saturating_sub(prec.get() as usize);
652 if trimmed == 0 {
653 return (0, 0, DigitSlice::from_slice(&[]));
654 }
655
656 let (insig_digits, sig_digits) = self.digits.split_at(trimmed);
657 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());
658 let (insig_digit, trailing_digits) = insig_digits.split_last().unwrap_or((&0, &[]));
659 (sig_digits[0], *insig_digit, DigitSlice::from_slice(trailing_digits))
660 }
661
662 pub fn round_at_prec_inplace(
668 &mut self,
669 prec: NonZeroU64,
670 rounding: NonDigitRoundingData,
671 ) -> (DigitSlice<'_, RADIX_10_u8, LittleEndian>, usize) {
672 let mut trimmed = self.digits.len().saturating_sub(prec.get() as usize);
674 if trimmed == 0 {
675 return (DigitSlice::from_slice(&self.digits), 0);
676 }
677
678 let (insig_digits, sig_digits) = self.digits.split_at_mut(trimmed);
679 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());
680
681 let (&insig_digit, insig_digits) = insig_digits.split_last().unwrap_or((&0, &[]));
682 let trailing_zeros = insig_digits.iter().all(|&d| d == 0);
683 let round = rounding.round_pair((sig_digits[0], insig_digit), trailing_zeros);
684
685 if round != 10 {
686 sig_digits[0] = round;
687 } else {
688 match sig_digits.iter().position(|&d| d != 9) {
689 Some(idx) => {
690 sig_digits[idx] += 1;
691 fill_slice_with_zero(&mut sig_digits[..idx]);
692 }
693 None => {
694 fill_slice_with_zero(sig_digits);
695 *sig_digits.last_mut().unwrap() = 1;
696 trimmed += 1;
697 }
698 }
699 }
700
701 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());
702 return (DigitSlice::from_slice(sig_digits), trimmed);
703 }
704}
705
706#[cfg(rustc_1_50)]
707#[allow(clippy::incompatible_msrv)]
708#[allow(dead_code)]
709fn fill_slice_with_zero<D: Zero + Clone>(s: &mut [D]) {
710 s.fill(Zero::zero());
711}
712
713#[cfg(not(rustc_1_50))]
714#[allow(dead_code)]
715fn fill_slice_with_zero<D: Zero + Clone>(s: &mut [D]) {
716 for r in s.iter_mut() {
717 *r = Zero::zero();
718 }
719}
720
721
722#[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)]
728pub(crate) struct DigitSlice<'a, R: RadixType, E: Endianness> {
729 pub digits: &'a [R::Base],
730 _radix: PhantomData<R>,
731 _endian: PhantomData<E>,
732}
733
734#[allow(dead_code)]
735impl<'a, R: RadixType, E: Endianness> DigitSlice<'a, R, E> {
736 pub fn from_slice(d: &'a [R::Base]) -> Self {
743 Self {
744 digits: d,
745 _radix: PhantomData {},
746 _endian: PhantomData {},
747 }
748 }
749
750 pub fn from_sig_slice(d: &'a [R::Base]) -> Self {
752 let (nonzero, _) = E::split_significant_zeros(d);
753 Self::from_slice(nonzero)
754 }
755
756 pub fn len(&self) -> usize {
758 self.digits.len()
759 }
760
761 pub fn without_leading_zeros(&self) -> Self {
763 let (digits, _) = E::split_significant_zeros(self.digits);
764 Self::from_slice(digits)
765 }
766
767 pub fn split_le_at(&'a self, pos: usize) -> (Self, Self) {
769 let (lo, hi) = E::split_least_significant(self.digits, pos);
770 (Self::from_slice(lo), Self::from_slice(hi))
771 }
772
773 pub fn count_significant_zeros(&self) -> usize {
775 E::count_significant_zeros(self.digits)
776 }
777
778 pub fn is_all_zeros(&self) -> bool {
780 self.digits.iter().all(|&d| d.is_zero())
781 }
782
783 pub fn least_n_are_zero(&self, n: usize) -> bool {
785 self.iter_le().take(n).all(Zero::is_zero)
786 }
787
788 #[cfg(rustc_1_75)]
789 pub fn iter_le(&self) -> impl LeBigDigitIterator<'_, &R::Base> {
790 E::iter_slice(self.digits)
791 }
792
793 #[cfg(not(rustc_1_75))]
794 pub fn iter_le(&self) -> LittleEndianBigDigitIter<'_, &R::Base> {
795 E::iter_slice(self.digits)
796 }
797}
798
799#[allow(dead_code)]
800impl<R: RadixType> DigitSlice<'_, R, LittleEndian> {
801 pub fn trim_insignificant(&self, n: usize) -> Self {
803 Self::from_slice(&self.digits[n..])
804 }
805
806 pub fn find_least_significant_nonzero(&self) -> Option<usize> {
807 self.digits.iter().position(|&d| !d.is_zero())
808 }
809}
810
811#[allow(dead_code)]
812impl<'a, E: Endianness> From<&'a DigitVec<RADIX_u64, E>> for DigitSlice<'a, RADIX_u64, E> {
813 fn from(v: &'a DigitVec<RADIX_u64, E>) -> Self {
814 v.as_digit_slice()
815 }
816}
817
818impl<'a, R: RadixPowerOfTen, E: Endianness> DigitSlice<'a, R, E> {
819 pub fn count_decimal_digits(&self) -> usize {
820 use crate::arithmetic::decimal::count_digits_u64;
821
822 let (top_digit, trailing) = E::split_most_significant_digit(self.digits);
823 R::DIGITS * trailing.len()
824 + count_digits_u64(top_digit.to_u64().unwrap())
825 }
826}
827
828impl DigitSlice<'_, RADIX_10_u8, LittleEndian> {
829 #[allow(dead_code)]
831 pub fn fill_vec_u64(&self, dest: &mut DigitVec<RADIX_u64, LittleEndian>) {
832 let n = num_bigint::BigUint::from_radix_le(self.digits, 10).unwrap();
833 *dest = (&n).into();
834 }
835}
836
837pub(crate) struct DigitSliceMut<'a, R: RadixType, E: Endianness> {
839 pub digits: &'a mut [R::Base],
840 _radix: PhantomData<R>,
841 _endian: PhantomData<E>,
842}
843
844#[allow(dead_code)]
845impl<'a, R: RadixType, E: Endianness> DigitSliceMut<'a, R, E> {
846 pub fn from_slice(v: &'a mut [R::Base]) -> Self {
848 Self {
849 digits: v,
850 _radix: PhantomData {},
851 _endian: PhantomData {},
852 }
853 }
854
855 pub fn len(&self) -> usize {
857 self.digits.len()
858 }
859
860 pub fn from_vec_offset(v: &'a mut DigitVec<R, E>, offset: usize) -> Self {
862 Self::from_slice(&mut v.digits[offset..])
863 }
864
865 pub fn as_digit_slice(&'a self) -> DigitSlice<'a, R, E> {
867 DigitSlice::from_slice(self.digits)
868 }
869
870 pub fn split_le_at(&'a self, pos: usize) -> (DigitSlice<'a, R, E>, DigitSlice<'a, R, E>) {
872 let (lo, hi) = E::split_least_significant(&self.digits[..], pos);
873 (DigitSlice::from_slice(lo), DigitSlice::from_slice(hi))
874 }
875
876 pub fn split_le_at_mut(&'a mut self, pos: usize) -> (Self, Self) {
878 let (lo, hi) = E::split_least_significant_mut(self.digits, pos);
879 (Self::from_slice(lo), Self::from_slice(hi))
880 }
881
882 pub fn add_value_at(&mut self, idx: usize, mut n: R::Base) -> R::Base {
884 if n.is_zero() {
885 return n;
886 }
887 E::addassign_carry_into_slice_at::<R>(self.digits, &mut n, idx);
888 n
889 }
890
891 pub fn addassign_carry(&mut self, c: &mut R::Base) {
893 E::addassign_carry_into_slice_at::<R>(self.digits, c, 0);
894 }
895
896 #[cfg(rustc_1_75)]
897 pub fn iter_le(&self) -> impl LeBigDigitIterator<'_, &R::Base> {
898 E::iter_slice(self.digits)
899 }
900
901 #[cfg(not(rustc_1_75))]
902 pub fn iter_le(&self) -> LittleEndianBigDigitIter<'_, &R::Base> {
903 E::iter_slice(self.digits)
904 }
905
906 #[cfg(rustc_1_75)]
907 pub fn iter_le_mut(&mut self) -> impl LeBigDigitIterator<'_, &mut R::Base> {
908 E::iter_slice_mut(self.digits)
909 }
910
911 #[cfg(not(rustc_1_75))]
912 pub fn iter_le_mut(&mut self) -> LittleEndianBigDigitIter<'_, &mut R::Base> {
913 E::iter_slice_mut(self.digits)
914 }
915}
916
917#[allow(dead_code)]
918impl<R: RadixPowerOfTen, E: Endianness> DigitSliceMut<'_, R, E> {
919 pub fn count_decimal_digits(&self) -> usize {
920 self.as_digit_slice().count_decimal_digits()
921 }
922}
923
924
925impl<'a, R: RadixType, E: Endianness> From<&'a mut Vec<R::Base>> for DigitSliceMut<'a, R, E> {
926 fn from(digits: &'a mut Vec<R::Base>) -> Self {
927 Self::from_slice(&mut digits[..])
928 }
929}
930
931impl<R: RadixType, E: Endianness> fmt::Debug for DigitVec<R, E> {
932 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
933 f.write_fmt(format_args!("DigitVec({0}, {1:?})", E::NAME, self.digits))write!(f, "DigitVec({}, {:?})", E::NAME, self.digits)
934 }
935}
936
937impl<R: RadixType, E: Endianness> fmt::Debug for DigitSlice<'_, R, E> {
938 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
939 f.write_fmt(format_args!("DigitSlice({0}, {1:?})", E::NAME, self.digits))write!(f, "DigitSlice({}, {:?})", E::NAME, self.digits)
940 }
941}
942
943impl<R: RadixType, E: Endianness> fmt::Debug for DigitSliceMut<'_, R, E> {
944 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
945 f.write_fmt(format_args!("DigitSliceMut({0}, {1:?})", E::NAME, self.digits))write!(f, "DigitSliceMut({}, {:?})", E::NAME, self.digits)
946 }
947}
948
949impl<R: RadixType, E: Endianness> crate::WithScale<DigitVec<R, E>> {
951 pub fn as_digit_slice(&self) -> crate::WithScale<DigitSlice<'_, R, E>> {
952 WithScale {
953 scale: self.scale,
954 value: self.value.as_digit_slice(),
955 }
956 }
957}