1#![allow(dead_code)]
2
3pub mod util;
4pub mod iter;
5
6use std::collections::VecDeque;
7use std::convert::TryFrom;
8use std::ops::{Shl, Shr};
9use util::*;
10use iter::BorrowedNumberIter;
11
12pub type Digit = u8;
13pub type Pair = (Digit, Digit);
14pub type Bucket = usize;
15
16#[derive(Debug)]
17pub struct Base {
18 base: u32,
19 addition_table: Vec<Pair>,
20 multiplication_table: Vec<Pair>,
21 digit_width: usize,
22 digits_per_bucket: usize,
23 digit_bitmask: usize,
24}
25impl Base {
26 pub fn new(base: u32) -> Self {
27 let mut addition_table = Vec::new(); let mut multiplication_table = Vec::new();
29 for (add, mul) in ArithmeticPrecomputation::new(base) {
30 addition_table.push(add);
31 multiplication_table.push(mul);
32 }
33 let (digit_width, digits_per_bucket, digit_bitmask) = bitwise_parameters(base);
34 Self {
35 base,
36 addition_table,
37 multiplication_table,
38 digit_width,
39 digits_per_bucket,
40 digit_bitmask
41 }
42 }
43
44 pub fn add_digits(&self, a: Digit, b: Digit) -> Pair {
47 *self.addition_table.get(pair_index((a, b), self.base)).unwrap()
48 }
49 pub fn multiply_digits(&self, a: Digit, b: Digit) -> Pair {
52 *self.multiplication_table.get(pair_index((a, b), self.base)).unwrap()
53 }
54
55 pub fn digits_per_bucket(&self) -> usize {
56 self.digits_per_bucket
57 }
58 pub fn digit_width(&self) -> usize {
59 self.digit_width
60 }
61 pub fn digit_bitmask(&self) -> usize {
62 self.digit_bitmask
63 }
64
65 pub fn bucket_index(&self, idx: usize) -> usize {
68 idx / self.digits_per_bucket
69 }
70 pub fn digit_index(&self, idx: usize) -> usize {
73 idx % self.digits_per_bucket
74 }
75 pub fn indexes(&self, idx: usize) -> (usize, usize) {
78 (self.bucket_index(idx), self.digit_index(idx))
79 }
80}
81
82#[derive(Debug)]
83pub struct Number<'base> {
84 buckets: VecDeque<Bucket>,
85 digits: usize,
86 power: isize,
87 sign: Sign,
88 base: &'base Base
89}
90impl<'base> Number<'base> {
91 pub fn new(base: &'base Base) -> Self {
92 Self {
93 buckets: VecDeque::new(),
94 digits: 0,
95 power: 0,
96 sign: Sign::Positive,
97 base
98 }
99 }
100 pub fn with_capacity(base: &'base Base, digits: usize) -> Self {
101 let mut buckets = digits / base.digits_per_bucket();
102 if digits % base.digits_per_bucket() != 0 {
103 buckets += 1;
104 }
105 Self {
106 buckets: VecDeque::with_capacity(buckets),
107 digits: 0,
108 power: 0,
109 sign: Sign::Positive,
110 base
111 }
112 }
113
114 pub fn digits(&self) -> usize {
115 self.digits
116 }
117 pub fn power(&self) -> isize {
118 self.power
119 }
120 pub fn sign(&self) -> Sign {
121 self.sign
122 }
123 pub fn positive(&self) -> bool {
124 self.sign == Sign::Positive
125 }
126 pub fn negative(&self) -> bool {
127 self.sign == Sign::Negative
128 }
129
130 pub fn get(&self, idx: usize) -> Option<Digit> {
133 if idx > self.digits || self.digits == 0 {
134 return None;
135 }
136 let (bucket_idx, digit_idx) = self.base.indexes(idx);
137 Some(self.get_digit(bucket_idx, digit_idx))
138 }
139 pub fn set(&mut self, idx: usize, digit: Digit) {
140 if idx > self.digits {
141 panic!("Attempted to set inaccessible digit.");
142 }
144 if idx == self.digits {
145 self.push_high(digit);
146 return;
147 }
148 let (bucket_idx, digit_idx) = self.base.indexes(idx);
149 self.set_digit(bucket_idx, digit_idx, digit);
150 }
151 pub fn push_high(&mut self, digit: Digit) {
153 let (bucket_idx, digit_idx) = self.base.indexes(self.digits);
154 if digit_idx == 0 { self.buckets.push_back(digit as Bucket)
156 } else {
157 self.set_digit(bucket_idx, digit_idx, digit)
158 }
159 self.digits += 1;
160 }
161 pub fn pop_high(&mut self) -> Option<Digit> {
164 if self.digits == 0 {
165 return None;
166 }
167 let (bucket_idx, digit_idx) = self.base.indexes(self.digits - 1);
168 let digit = self.get_digit(bucket_idx, digit_idx);
169 self.digits -= 1;
170 if digit_idx == 0 {
171 self.buckets.pop_back();
172 }
173 Some(digit)
174 }
175 pub fn push_low(&mut self, digit: Digit) {
177 let (bucket_idx, digit_idx) = (0, 0);
178 if self.digits == 0 || self.base.digit_index(self.digits - 1) == self.base.digits_per_bucket - 1 { self.buckets.push_back(0)
181 }
182 self.shift_digits_high(1);
183 self.set_digit(bucket_idx, digit_idx, digit);
184 self.digits += 1;
185 }
186 pub fn pop_low(&mut self) -> Option<Digit> {
189 if self.digits == 0 {
190 return None;
191 }
192 let (bucket_idx, digit_idx) = (0, 0);
193 let digit = self.get_digit(bucket_idx, digit_idx);
194 self.shift_digits_low(1);
195 self.digits -= 1;
196 Some(digit)
197 }
198fn set_digit(&mut self, bucket_idx: usize, digit_idx: usize, digit: Digit) {
206 let bucket = self.buckets.get_mut(bucket_idx).expect("Attempted to set digit in uninitialzed bucket");
207 let shift = self.base.digit_width() * digit_idx;
208 *bucket = (*bucket & !(self.base.digit_bitmask() << shift)) | ((digit as usize) << shift);
209 }
210 fn get_digit(&self, bucket_idx: usize, digit_idx: usize) -> Digit {
211 let bucket = self.buckets.get(bucket_idx).expect("Attempted to fetch digit from uninitialzed bucket.");
212 let shift = self.base.digit_width() * digit_idx;
213 ((bucket & (self.base.digit_bitmask() << shift)) >> shift) as Digit
214 }
215 fn shift_digits_high(&mut self, shift: usize) {
217 if self.digits == 0 {
219 return;
220 }
221 for _ in 0..shift {
222 for idx in (0..self.digits).into_iter().rev() {
223 let (current_bucket_idx, current_digit_idx) = self.base.indexes(idx);
224 let digit = self.get_digit(current_bucket_idx, current_digit_idx);
225 let (new_bucket_idx, new_digit_idx) = self.base.indexes(idx + 1);
226 self.set_digit(new_bucket_idx, new_digit_idx, digit);
227
228 }
229 }
230 }
231 fn shift_digits_low(&mut self, shift: usize) {
234 if self.digits == 0 {
236 return;
237 }
238 for _ in 0..shift {
239 for idx in 1..self.digits {
240 let (current_bucket_idx, current_digit_idx) = self.base.indexes(idx);
241 let digit = self.get_digit(current_bucket_idx, current_digit_idx);
242 let (new_bucket_idx, new_digit_idx) = self.base.indexes(idx - 1);
243 self.set_digit(new_bucket_idx, new_digit_idx, digit);
244 }
245 }
246 }
247 fn add_buckets_high(&mut self, buckets: usize) {
248 self.buckets.reserve(buckets);
249 for _bucket in 0..buckets {
250 self.buckets.push_front(0);
251 }
252 }
253 fn add_buckets_low(&mut self, buckets: usize) {
254 self.buckets.reserve(buckets);
255 for _bucket in 0..buckets {
256 self.buckets.push_back(0);
257 }
258 }
259 fn pad_digits_high(&mut self, digits: usize) {
260 for _ in 0..digits {
261 self.push_high(0);
262 }
263 }
265 fn pad_digits_low(&mut self, digits: usize) {
266 for _ in 0..digits {
267 self.push_low(0);
268 }
270 self.power -= isize::try_from(digits).expect("Overflowed isize while adding low-order digits.");
271 }
272
273 fn power_idx(&self, power: isize) -> Result<usize, PowerIndexError> {
279 if self.digits == 0 {
280 if power == 0 {
281 return Err(PowerIndexError::InsufficientDigitsHigh(1));
282 } else if power > 0 {
283 return Err(PowerIndexError::InsufficientDigitsHigh(power as usize));
284 } else {
285 return Err(PowerIndexError::InsufficientDigitsLow(-power as usize));
286 }
287 }
288
289 let highest_digit = self.power + isize::try_from(self.digits - 1).expect("Couldn't convert digit count to isize");
290 if power > highest_digit {
293 return Err(PowerIndexError::InsufficientDigitsHigh((power - highest_digit) as usize));
294 } else if power < self.power {
295 return Err(PowerIndexError::InsufficientDigitsLow((self.power - power) as usize));
296 }
297
298 Ok((power - self.power) as usize)
299 }
300
301 fn arithmetic_setup(&mut self, power: isize) -> usize {
303 match self.power_idx(power) {
304 Ok(idx) => idx,
305 Err(PowerIndexError::InsufficientDigitsLow(digits_needed)) => {
306 self.pad_digits_low(digits_needed);
307 0 },
310 Err(PowerIndexError::InsufficientDigitsHigh(digits_needed)) => {
311 let idx = (self.digits - 1) + digits_needed;
312 self.pad_digits_high(digits_needed);
316 idx
317 }
318 }
319 }
320
321 pub fn add_digit(&mut self, digit: Digit, power: isize) {
322 let mut idx = self.arithmetic_setup(power);
324 let (bucket_idx, digit_idx) = self.base.indexes(idx);
325 let (new_digit, mut carry) = self.base.add_digits(digit, self.get_digit(bucket_idx, digit_idx));
326 self.set_digit(bucket_idx, digit_idx, new_digit);
327 idx += 1;
328
329 while idx < self.digits && carry != 0 {
330 let (bucket_idx, digit_idx) = self.base.indexes(idx);
331 let (new_digit, new_carry) = self.base.add_digits(carry, self.get_digit(bucket_idx, digit_idx));
333 carry = new_carry;
334 self.set_digit(bucket_idx, digit_idx, new_digit);
335 idx += 1;
336 }
337 if carry != 0 {
338 self.push_high(carry);
339 }
340 }
341pub fn negate(&mut self) {
346 self.sign = match self.sign {
347 Sign::Positive => Sign::Negative,
348 Sign::Negative => Sign::Positive
349 }
350 }
351
352 pub fn iter(&self) -> BorrowedNumberIter {
353 BorrowedNumberIter::new(self)
354 }
355}
356
357impl Shl<usize> for Number<'_> {
358 type Output = Self;
359
360 fn shl(mut self, rhs: usize) -> Self::Output {
361 self.power += isize::try_from(rhs).expect("Failed to convert into isize during left shift.");
362 self
363 }
364}
365
366impl Shr<usize> for Number<'_> {
367 type Output = Self;
368
369 fn shr(mut self, rhs: usize) -> Self::Output {
370 self.power -= isize::try_from(rhs).expect("Failed to convert into isize during right shift.");
371 self
372 }
373}
374
375#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
376pub enum Sign {
377 Positive,
378 Negative
379}
380
381enum PowerIndexError {
382 InsufficientDigitsHigh(usize),
383 InsufficientDigitsLow(usize)
384}
385
386fn bitwise_parameters(base: u32) -> (usize, usize, usize) {
387 let base = base as usize;
388 let highest_digit = base - 1;
389 let usize_bits = 0usize.leading_zeros();
391
392 let digits_width = usize_bits - highest_digit.leading_zeros();
393 let digits_per_bucket = usize_bits / digits_width;
394 let mask = !(usize::MAX << digits_width as usize);
395
396 (digits_width as usize, digits_per_bucket as usize, mask)
397}
398
399#[cfg(test)]
400pub mod test {
401 use super::*;
402
403 #[test]
406 fn push_high_puts_digit_on_left() {
407 let b = Base::new(10);
408 let mut n = Number::new(&b);
409 n.push_high(5);
410 n.push_high(1);
411 assert_eq!(n.iter().collect::<Vec<_>>(), vec!(1, 5));
412 }
413
414 #[test]
415 fn push_low_puts_digit_on_right() {
416 let b = Base::new(10);
417 let mut n = Number::new(&b);
418 n.push_low(1);
419 n.push_low(5);
420 assert_eq!(n.iter().collect::<Vec<_>>(), vec!(1, 5));
421 }
422
423 #[test]
424 fn pop_high_takes_digits_from_right() {
425 let b = Base::new(10);
426 let mut n = Number::new(&b);
427 n.push_high(5);
428 n.push_high(1);
429 assert_eq!(n.pop_high(), Some(1));
430 assert_eq!(n.pop_high(), Some(5));
431 assert_eq!(n.pop_high(), None);
432 }
433
434 #[test]
435 fn pop_low_takes_digits_from_left() {
436 let b = Base::new(10);
437 let mut n = Number::new(&b);
438 n.push_low(1);
439 n.push_low(5);
440 assert_eq!(n.pop_low(), Some(5));
441 assert_eq!(n.pop_low(), Some(1));
442 assert_eq!(n.pop_low(), None);
443 }
444
445 #[test]
446 fn push_high_and_pop_high_are_inverse() {
447 let b = Base::new(10);
448 let mut n = Number::new(&b);
449 n.push_high(5);
450 n.push_high(1);
451 assert_eq!(n.pop_high(), Some(1));
452 assert_eq!(n.iter().collect::<Vec<_>>(), vec!(5));
453 }
454
455 #[test]
456 fn push_low_and_pop_low_are_inverse() {
457 let b = Base::new(10);
458 let mut n = Number::new(&b);
459 n.push_low(5);
460 n.push_low(1);
461 assert_eq!(n.pop_low(), Some(1));
462 assert_eq!(n.iter().collect::<Vec<_>>(), vec!(5));
463 }
464
465 #[test]
466 fn pushing_increases_digits() {
467 let b = Base::new(10);
468 let mut n = Number::new(&b);
469 n.push_high(5);
470 assert_eq!(n.digits, 1);
471 n.push_low(1);
472 assert_eq!(n.digits, 2);
473 }
474
475 #[test]
476 fn popping_reduces_digits() {
477 let b = Base::new(10);
478 let mut n = Number::new(&b);
479 n.push_high(5);
480 n.push_low(1);
481 n.pop_high();
482 assert_eq!(n.digits, 1);
483 n.pop_low();
484 assert_eq!(n.digits, 0);
485 }
486
487 #[test]
488 fn alternating_pushing_high_and_low() {
489 let b = Base::new(10);
490 let mut n = Number::new(&b);
491 n.push_high(1);
492 assert_eq!(n.iter().collect::<Vec<_>>(), vec!(1));
493 n.push_low(2);
494 assert_eq!(n.iter().collect::<Vec<_>>(), vec!(1, 2));
495 n.push_high(3);
496 assert_eq!(n.iter().collect::<Vec<_>>(), vec!(3, 1, 2));
497 n.push_low(4);
498 assert_eq!(n.iter().collect::<Vec<_>>(), vec!(3, 1, 2, 4));
499 }
500
501 #[test]
502 fn alternating_popping_high_and_low() {
503 let b = Base::new(10);
504 let mut n = Number::new(&b);
505 for i in 1..=9 {
506 n.push_low(i);
507 }
508 assert_eq!(n.pop_high(), Some(1));
509 assert_eq!(n.pop_low(), Some(9));
510 assert_eq!(n.pop_high(), Some(2));
511 assert_eq!(n.pop_low(), Some(8));
512 assert_eq!(n.pop_high(), Some(3));
513 assert_eq!(n.pop_low(), Some(7));
514 assert_eq!(n.pop_high(), Some(4));
515 assert_eq!(n.pop_low(), Some(6));
516 assert_eq!(n.pop_high(), Some(5));
517
518 assert_eq!(n.pop_high(), None);
519 assert_eq!(n.pop_low(), None);
520 }
521
522 #[test]
523 fn pushing_high_past_bucket_boundary() {
524 let b = Base::new(10);
525 let mut n = Number::new(&b);
526 for _ in 0..(b.digits_per_bucket() + 1) {
527 n.push_high(1);
528 }
529 assert_eq!(
530 n.iter().collect::<Vec<_>>(),
531 (0..b.digits_per_bucket() + 1).map(|_| 1).collect::<Vec<_>>()
532 );
533 }
534
535 #[test]
536 fn pushing_low_past_bucket_boundary() {
537 let b = Base::new(10);
538 let mut n = Number::new(&b);
539 for _ in 0..(b.digits_per_bucket() + 1) {
540 n.push_low(1);
541 }
542 assert_eq!(
543 n.iter().collect::<Vec<_>>(),
544 (0..b.digits_per_bucket() + 1).map(|_| 1).collect::<Vec<_>>()
545 );
546 }
547
548 #[test]
549 fn popping_high_past_bucket_boundary() {
550 let b = Base::new(10);
551 let mut n = Number::new(&b);
552 for _ in 0..(b.digits_per_bucket() + 1) {
553 n.push_high(1);
554 }
555 for _ in 0..(b.digits_per_bucket() + 1) {
556 assert_eq!(n.pop_high(), Some(1));
557 }
558 assert_eq!(n.pop_high(), None);
559 }
560
561 #[test]
562 fn popping_low_past_bucket_boundary() {
563 let b = Base::new(10);
564 let mut n = Number::new(&b);
565 for _ in 0..(b.digits_per_bucket() + 1) {
566 n.push_high(1);
567 }
568 for _ in 0..(b.digits_per_bucket() + 1) {
569 assert_eq!(n.pop_low(), Some(1));
570 }
571 assert_eq!(n.pop_low(), None);
572 }
573
574 #[test]
575 fn get_returns_correct_digit() {
576 let b = Base::new(10);
577 let mut n = Number::new(&b);
578 for i in 1..=9 {
579 n.push_high(i);
580 }
581 for i in 0..8 {
582 assert_eq!(n.get(i), Some((i+1) as Digit));
583 }
584 }
585
586 #[test]
587 fn set_alters_correct_digit() {
588 let b = Base::new(10);
589 let mut n = Number::new(&b);
590 for i in 0..9 {
591 n.push_high(i);
592 }
593 for i in (0..9).into_iter().rev() {
594 n.set(i, (i+1) as Digit);
595 }
596 assert_eq!(n.iter().collect::<Vec<_>>(), vec!(9, 8, 7, 6, 5, 4, 3, 2, 1));
597 }
598
599 #[test]
600 fn set_can_alter_1_digit_past_last_digit() {
601 let b = Base::new(10);
602 let mut n = Number::new(&b);
603 for i in 0..9 {
604 n.push_high(i);
605 }
606 n.set(9, 9);
607 assert_eq!(n.iter().collect::<Vec<_>>(), vec!(9, 8, 7, 6, 5, 4, 3, 2, 1, 0));
608 }
610
611 #[test]
614 fn single_digit_addition() {
615 let b = Base::new(10);
616 let mut n = Number::new(&b);
617 n.push_high(1);
618 n.add_digit(1, 0);
619 assert_eq!(n.iter().collect::<Vec<_>>(), vec!(2));
620 }
621
622 #[test]
623 fn single_digit_addition_with_carry() {
624 let b = Base::new(10);
625 let mut n = Number::new(&b);
626 for _ in 0..3 {
627 n.push_high(9);
628 }
629 n.add_digit(1, 0);
630 assert_eq!(n.iter().collect::<Vec<_>>(), vec!(1,0,0,0));
631 }
632
633 #[test]
634 fn single_digit_addition_with_carry_across_bucket_boundary() {
635 let b = Base::new(10);
636 let mut n = Number::new(&b);
637 for _ in 0..b.digits_per_bucket() {
638 n.push_high(9);
639 }
640 n.add_digit(1, 0);
641 let mut expected = Vec::new();
642 expected.push(1);
643 for _ in 0..b.digits_per_bucket() {
644 expected.push(0);
645 }
646 assert_eq!(n.iter().collect::<Vec<_>>(), expected);
647 }
648
649 #[test]
650 fn single_digit_addition_with_carry_that_does_not_travel_all_the_way() {
651 let b = Base::new(10);
652 let mut n = Number::new(&b);
653 n.push_high(8);
654 n.push_high(9);
655 n.push_high(9);
656 n.push_high(1);
657 n.add_digit(2, 0);
658 assert_eq!(n.iter().collect::<Vec<_>>(), vec!(2, 0, 0, 0));
659 }
660
661 #[test]
662 fn single_digit_addition_with_new_digit_high() {
663 let b = Base::new(10);
664 let mut n = Number::new(&b);
665 n.push_high(1);
666 n.add_digit(2, 1);
667 assert_eq!(n.iter().collect::<Vec<_>>(), vec!(2, 1));
668 }
669
670 #[test]
671 fn single_digit_addition_with_new_digit_low() {
672 let b = Base::new(10);
673 let mut n = Number::new(&b);
674 n.push_high(1);
675 n.add_digit(2, -1);
676 assert_eq!(n.iter().collect::<Vec<_>>(), vec!(1, 2));
677 }
678
679 #[test]
680 fn shift_left_increases_power() {
681 let b = Base::new(10);
682 let mut n = Number::new(&b);
683 n = n << 1;
684 assert_eq!(n.power(), 1);
685 }
686
687 #[test]
688 fn shift_right_decreases_power() {
689 let b = Base::new(10);
690 let mut n = Number::new(&b);
691 n = n >> 1;
692 assert_eq!(n.power(), -1);
693 }
694}