1type RawRow = Vec<u8>;
4type Row = PlacesRow;
5
6#[macro_use]
7mod macroinstruction;
8mod nth_root;
9
10pub use nth_root::root;
11
12#[derive(Clone, PartialEq, Debug)]
14pub struct PlacesRow {
15 row: RawRow,
16}
17
18use core::{cmp::Ordering, ops::Deref};
19impl Deref for PlacesRow {
20 type Target = [u8];
21
22 fn deref(&self) -> &[u8] {
24 self.row.as_slice()
25 }
26}
27
28impl PlacesRow {
29 pub fn new_from_vec(mut row: Vec<u8>) -> Result<Self, Option<usize>> {
40 if row.len() == 0 {
41 return Err(None);
42 }
43
44 let row_len = len_without_leading_raw(&row, 0, 1);
45
46 let mut ix = 0;
47 while ix < row_len {
48 if row[ix] > 9 {
49 return Err(Some(ix));
50 }
51
52 ix += 1;
53 }
54
55 row.truncate(row_len);
56 Ok(Row { row })
57 }
58
59 pub fn new_from_u8(num: u8) -> Self {
61 new_from_num!(num)
62 }
63
64 pub fn new_from_u16(num: u16) -> Self {
66 new_from_num!(num)
67 }
68
69 pub fn new_from_u32(num: u32) -> Self {
71 new_from_num!(num)
72 }
73
74 pub fn new_from_u64(num: u64) -> Self {
76 new_from_num!(num)
77 }
78
79 pub fn new_from_u128(num: u128) -> Self {
81 new_from_num!(num)
82 }
83
84 pub fn new_from_usize(num: usize) -> Self {
86 new_from_num!(num)
87 }
88
89 pub fn try_into_u8(&self) -> Option<u8> {
93 try_into_num!(&self.row, u8, &mut 0)
94 }
95
96 pub fn try_into_u16(&self) -> Option<u16> {
100 try_into_num!(&self.row, u16, &mut 0)
101 }
102
103 pub fn try_into_u32(&self) -> Option<u32> {
107 try_into_num!(&self.row, u32, &mut 0)
108 }
109
110 pub fn try_into_u64(&self) -> Option<u64> {
114 try_into_num!(&self.row, u64, &mut 0)
115 }
116
117 pub fn try_into_u128(&self) -> Option<u128> {
121 try_into_num!(&self.row, u128, &mut 0)
122 }
123
124 pub fn try_into_usize(&self) -> Option<usize> {
128 try_into_num!(&self.row, usize, &mut 0)
129 }
130
131 pub fn try_into_i8(&self) -> Option<i8> {
135 try_into_num!(&self.row, i8, &mut 0)
136 }
137
138 pub fn try_into_i16(&self) -> Option<i16> {
142 try_into_num!(&self.row, i16, &mut 0)
143 }
144
145 pub fn try_into_i32(&self) -> Option<i32> {
149 try_into_num!(&self.row, i32, &mut 0)
150 }
151
152 pub fn try_into_i64(&self) -> Option<i64> {
156 try_into_num!(&self.row, i64, &mut 0)
157 }
158
159 pub fn try_into_i128(&self) -> Option<i128> {
163 try_into_num!(&self.row, i128, &mut 0)
164 }
165
166 pub fn try_into_isize(&self) -> Option<isize> {
170 try_into_num!(&self.row, isize, &mut 0)
171 }
172
173 pub fn new_from_str(s: &str) -> Result<Self, Option<usize>> {
180 let row = new_from_str_raw(s);
181 if let Ok(row) = row {
182 Ok(Self { row })
183 } else {
184 Err(row.unwrap_err())
185 }
186 }
187
188 pub fn to_number(&self) -> String {
190 let row = &self.row;
191 let len = row.len();
192 let mut number = String::new();
193 number.reserve_exact(len);
194 for i in row.iter().rev() {
195 let digit = to_digit(*i);
196 number.push(digit);
197 }
198
199 number
200 }
201
202 pub fn is_unity(&self) -> bool {
204 is_unity_raw(&self.row)
205 }
206
207 pub fn is_nought(&self) -> bool {
209 is_nought_raw(&self.row)
210 }
211
212 pub fn unity() -> PlacesRow {
214 Row { row: unity_raw() }
215 }
216
217 pub fn nought() -> PlacesRow {
219 Row { row: nought_raw() }
220 }
221
222 #[deprecated(since = "2.2.0", note = "Pick `fn nought` instead.")]
223 pub fn zero() -> PlacesRow {
225 Self::nought()
226 }
227
228 pub fn places(&self) -> usize {
232 dec_pla_cnt_raw(&self.row)
233 }
234}
235
236fn new_from_str_raw(mut s: &str) -> Result<RawRow, Option<usize>> {
237 let s_len_orig = s.len();
238 if s_len_orig == 0 {
239 return Err(None);
240 }
241
242 s = s.trim_start_matches('0');
243 let s_len = s.len();
244
245 let row = if s_len == 0 {
246 nought_raw()
247 } else {
248 let mut row = Vec::new();
249 row.reserve_exact(s_len);
250
251 let mut err_inx = s_len_orig;
252 for (c, sc) in s.chars().rev().zip(row.spare_capacity_mut()) {
253 err_inx -= 1;
254 if c.is_ascii_digit() {
255 let n = from_digit(c);
256 sc.write(n);
257 } else {
258 return Err(Some(err_inx));
259 }
260 }
261
262 unsafe { row.set_len(s_len) }
263 row
264 };
265
266 Ok(row)
267}
268
269fn truncate_leading_raw(row: &mut RawRow, lead: u8, ex_to: usize) {
270 let new_len = len_without_leading_raw(row, lead, ex_to);
271 row.truncate(new_len);
272}
273
274fn len_without_leading_raw(row: &[u8], lead: u8, ex_to: usize) -> usize {
275 let mut row_len = row.len();
276 while row_len > ex_to {
277 row_len -= 1;
278 if lead != row[row_len] {
279 row_len += 1;
280 break;
281 }
282 }
283
284 row_len
285}
286
287fn unity_raw() -> RawRow {
288 vec![1; 1]
289}
290
291fn nought_raw() -> RawRow {
292 vec![0; 1]
293}
294
295const fn is_unity_raw(row: &[u8]) -> bool {
296 is_one_raw(row, 1)
297}
298
299const fn is_nought_raw(row: &[u8]) -> bool {
300 is_one_raw(row, 0)
301}
302
303const fn is_one_raw(row: &[u8], one: u8) -> bool {
304 row.len() == 1 && row[0] == one
305}
306
307fn from_digit(c: char) -> u8 {
308 match c {
309 '0' => 0,
310 '1' => 1,
311 '2' => 2,
312 '3' => 3,
313 '4' => 4,
314 '5' => 5,
315 '6' => 6,
316 '7' => 7,
317 '8' => 8,
318 '9' => 9,
319 _ => panic!("Unsupported char `{c}` conversion."),
320 }
321}
322
323fn to_digit(n: u8) -> char {
324 match n {
325 0 => '0',
326 1 => '1',
327 2 => '2',
328 3 => '3',
329 4 => '4',
330 5 => '5',
331 6 => '6',
332 7 => '7',
333 8 => '8',
334 9 => '9',
335 _ => panic!("Only number < 10 supported."),
336 }
337}
338
339impl std::string::ToString for PlacesRow {
340 fn to_string(&self) -> String {
342 self.to_number()
343 }
344}
345
346use core::convert::From;
347use std::cmp::max;
348use std::time::{Duration, Instant};
349
350impl From<u8> for PlacesRow {
351 fn from(value: u8) -> Self {
353 Self::new_from_u8(value)
354 }
355}
356
357impl From<u16> for PlacesRow {
358 fn from(value: u16) -> Self {
360 Self::new_from_u16(value)
361 }
362}
363
364impl From<u32> for PlacesRow {
365 fn from(value: u32) -> Self {
367 Self::new_from_u32(value)
368 }
369}
370
371impl From<u64> for PlacesRow {
372 fn from(value: u64) -> Self {
374 Self::new_from_u64(value)
375 }
376}
377
378impl From<u128> for PlacesRow {
379 fn from(value: u128) -> Self {
381 Self::new_from_u128(value)
382 }
383}
384
385impl From<usize> for PlacesRow {
386 fn from(value: usize) -> Self {
388 Self::new_from_usize(value)
389 }
390}
391
392pub const SQUARE_ROOT_TEN_COMPARATOR: &str = "3162277660168379331998893544432718533719555139325216826857504852792594438639238221344248108379300295187347284152840055148548856030453880014690519596700153903344921657179259940659150153474113339484124085316929577090471576461044369257879062037808609941828371711548406328552999118596824564203326961604691314336128949791890266529543612676178781350061388186278580463683134952478031143769334671973819513185678403231241795402218308045872844614600253577579702828644029024407977896034543989163349222652612067792651676031048436697793756926155720500369894909469421850007358348844643882731109289109042348054235653403907274019786543725939641726001306990000955784463109626790694418336130181302894541703315807731626386395193793704654765220632063686587197822049312426053454111609356979828132452297000798883523759585328579251362964686511497675217123459559238039375625125369855194955325099947038843990336466165470647234999796132343403021857052187836676345789510732982875157945215771652139626324438399018484560935762602";
396
397#[derive(Clone, PartialEq, Debug)]
399pub enum OomClass {
400 Strict,
404 Loose,
406}
407
408#[derive(Clone, PartialEq, Debug)]
410pub enum Oom {
411 Undefined,
413 Precise(usize),
417 Approx(usize),
422}
423
424pub fn ord_of_mag(num: &PlacesRow, class: OomClass) -> Oom {
439 let row = &num.row;
440 if is_nought_raw(row) {
441 return Oom::Undefined;
442 }
443
444 let cmp = match class {
445 OomClass::Strict => SQUARE_ROOT_TEN_COMPARATOR.chars().map(from_digit).collect(),
446 OomClass::Loose => vec![5],
447 };
448
449 let row_len = row.len();
450 let cmp_len = cmp.len();
451
452 let mut row_ix = row_len;
453 let mut cmp_ix = 0;
454
455 let mut num_less = None;
456
457 loop {
458 if row_ix == 0 || cmp_ix == cmp_len {
459 break;
460 }
461
462 row_ix = row_ix - 1;
463
464 if row[row_ix] < cmp[cmp_ix] {
465 num_less = Some(true);
466 break;
467 }
468
469 if row[row_ix] > cmp[cmp_ix] {
470 num_less = Some(false);
471 break;
472 }
473
474 cmp_ix = cmp_ix + 1;
475 }
476
477 let (num_less, precise) = if let Some(l) = num_less {
478 (l, true)
479 } else {
480 let ord = row_len.cmp(&cmp_len);
481 match ord {
482 Ordering::Greater => (false, class == OomClass::Loose),
483 Ordering::Less => (true, true),
484 _ => (false, true),
485 }
486 };
487
488 let oom = if num_less { row_len - 1 } else { row_len };
489
490 match precise {
491 true => Oom::Precise(oom),
492 false => Oom::Approx(oom),
493 }
494}
495
496#[derive(Debug, PartialEq, Clone)]
509pub enum Rel {
510 Greater(Option<DecCnt>),
512 Equal,
514 Lesser(Option<DecCnt>),
516}
517
518pub fn rel(num: &PlacesRow, comparand: &PlacesRow) -> Rel {
522 let r1 = &num.row;
523 let r2 = &comparand.row;
524
525 rel_raw(r1, r2)
526}
527
528const fn rel_raw(r1: &[u8], r2: &[u8]) -> Rel {
529 match rel_dec_raw(r1, r2) {
530 RelDec::Greater(c) => Rel::Greater(Some(c)),
531 RelDec::Lesser(c) => Rel::Lesser(Some(c)),
532 RelDec::Equal(mut inx) => {
533 let mut rel = Rel::Equal;
534
535 while inx > 0 {
536 inx -= 1;
537 if r1[inx] > r2[inx] {
538 rel = Rel::Greater(None);
539 break;
540 } else if r1[inx] < r2[inx] {
541 rel = Rel::Lesser(None);
542 break;
543 }
544 }
545
546 rel
547 }
548 }
549}
550
551pub type DecCnt = (usize, usize, usize);
569
570#[derive(Debug, PartialEq, Clone)]
585pub enum RelDec {
586 Greater(DecCnt),
588 Equal(usize),
590 Lesser(DecCnt),
592}
593
594pub fn rel_dec(num: &PlacesRow, comparand: &PlacesRow) -> RelDec {
601 let r1 = &num.row;
602 let r2 = &comparand.row;
603
604 rel_dec_raw(r1, r2)
605}
606
607const fn rel_dec_raw(r1: &[u8], r2: &[u8]) -> RelDec {
612 let r1_cnt = dec_pla_cnt_raw(r1);
613 let r2_cnt = dec_pla_cnt_raw(r2);
614
615 if r1_cnt == r2_cnt {
616 return RelDec::Equal(r1_cnt);
617 }
618
619 let mut cnts = (r1_cnt, r2_cnt, 0);
620
621 return if r1_cnt > r2_cnt {
622 cnts.2 = r1_cnt - r2_cnt;
623 RelDec::Greater(cnts)
624 } else {
625 cnts.2 = r2_cnt - r1_cnt;
626 RelDec::Lesser(cnts)
627 };
628}
629
630const fn dec_pla_cnt_raw(r: &[u8]) -> usize {
631 if is_nought_raw(r) {
632 0
633 } else {
634 r.len()
635 }
636}
637
638pub fn add(addend1: &PlacesRow, addend2: &PlacesRow) -> PlacesRow {
642 let r1 = &addend1.row;
643 let r2 = &addend2.row;
644
645 let max_len = max(r1.len(), r2.len());
646
647 let mut sum = Vec::new();
650 sum.reserve_exact(max_len + 1);
651
652 #[cfg(test)]
653 let sum_ptr = sum.as_ptr();
654
655 addition_two(r1, r2, &mut sum);
656
657 #[cfg(test)]
658 assert!(sum_ptr == sum.as_ptr());
659
660 Row { row: sum }
661}
662
663pub fn sub(minuend: &PlacesRow, subtrahend: &PlacesRow) -> Option<PlacesRow> {
667 let minuend = &minuend.row;
668 let subtrahend = &subtrahend.row;
669
670 match rel_raw(minuend, subtrahend) {
671 Rel::Equal => return Some(Row::nought()),
672 Rel::Lesser(_) => return None,
673 _ => {}
674 };
675
676 let mut minuend = minuend.clone();
677 _ = subtraction_arithmetical(&mut minuend, &subtrahend);
678
679 minuend.shrink_to_fit();
680
681 Some(Row { row: minuend })
682}
683
684pub fn mul(factor1: &PlacesRow, factor2: &PlacesRow) -> PlacesRow {
688 let factor1 = &factor1.row;
689 let factor2 = &factor2.row;
690
691 let row = mul_raw(factor1, factor2, true);
692 PlacesRow { row }
693}
694
695fn mul_raw(factor1: &[u8], factor2: &[u8], shrink: bool) -> RawRow {
696 if let Some(row) = mul_shortcut(factor1, factor2) {
697 row
698 } else {
699 let mut row = multiplication(factor1, factor2);
700
701 if shrink {
702 row.shrink_to_fit();
703 }
704
705 row
706 }
707}
708
709fn mul_shortcut(factor1: &[u8], factor2: &[u8]) -> Option<RawRow> {
715 if is_nought_raw(factor1) || is_nought_raw(factor2) {
716 Some(nought_raw())
717 } else if is_unity_raw(factor1) {
718 Some(factor2.to_vec())
719 } else if is_unity_raw(factor2) {
720 Some(factor1.to_vec())
721 } else {
722 None
723 }
724}
725
726pub fn pow(base: &PlacesRow, power: u16) -> PlacesRow {
730 let base = &base.row;
731
732 let row = pow_raw(base, power, true);
733 Row { row }
734}
735
736fn pow_raw(base: &RawRow, pow: u16, shrink: bool) -> RawRow {
737 if let Some(pow) = pow_shortcut(base, pow) {
738 return pow;
739 }
740
741 let mut pow = power(base, pow);
742 if shrink {
743 pow.shrink_to_fit();
744 }
745
746 pow
747}
748
749fn pow_shortcut(base: &[u8], pow: u16) -> Option<RawRow> {
754 if pow == 0 {
755 Some(unity_raw())
756 } else if pow == 1 {
757 Some(base.to_vec())
758 } else if is_nought_raw(base) {
759 Some(nought_raw())
760 } else if is_unity_raw(base) {
761 Some(unity_raw())
762 } else {
763 None
764 }
765}
766
767pub fn divrem(dividend: &PlacesRow, divisor: &PlacesRow) -> Option<(PlacesRow, PlacesRow)> {
771 let dividend = ÷nd.row;
772 let divisor = &divisor.row;
773
774 match divrem_shortcut(dividend, divisor) {
775 Some(res) => return res,
776 None => {}
777 }
778
779 let remratio = division(
780 ÷nd,
781 &divisor,
782 #[cfg(test)]
783 &mut vec![],
784 );
785
786 let mut rem = remratio.0;
787 rem.shrink_to_fit();
788
789 Some((Row { row: remratio.1 }, Row { row: rem }))
790}
791
792fn divrem_shortcut(dividend: &RawRow, divisor: &RawRow) -> Option<Option<(Row, Row)>> {
796 if is_nought_raw(divisor) {
797 return Some(None);
798 }
799
800 let end_clone = || Row {
801 row: dividend.clone(),
802 };
803
804 let shortcut = if is_unity_raw(divisor) {
805 (end_clone(), Row::nought())
806 } else {
807 match rel_raw(dividend, divisor) {
808 Rel::Lesser(_) => (Row::nought(), end_clone()),
809 _ => return None,
810 }
811 };
812
813 Some(Some(shortcut))
814}
815
816#[cfg(test)]
817use tests_of_units::prime_ck::{PrimeCkEscCode, PrimeCkTestGauges};
818
819pub fn prime_ck(
831 num: &PlacesRow,
832 lim: Option<Duration>,
833 #[cfg(test)] tg: &mut PrimeCkTestGauges,
834) -> Option<bool> {
835 let row = &num.row;
836
837 {
838 if is_one_raw(row, 2) || is_one_raw(row, 3) || is_one_raw(row, 5) || is_one_raw(row, 7) {
839 #[cfg(test)]
840 {
841 tg.esc = PrimeCkEscCode::Ar;
842 }
843 return Some(true);
844 }
845
846 let one = row[0];
847 if one % 2 == 0 || one == 5 || is_unity_raw(&row) {
848 #[cfg(test)]
849 {
850 tg.esc = PrimeCkEscCode::Ob;
851 }
852 return Some(false);
853 }
854 }
855
856 {
857 let mut sum = nought_raw();
858 let mut ix = 0;
859
860 let len = row.len();
861 while ix < len {
862 addition_sum(&vec![row[ix]], &mut sum, 0);
863 ix += 1;
864 }
865
866 let rem = division_dynamo(
867 sum,
868 &vec![3],
869 #[cfg(test)]
870 &mut vec![],
871 )
872 .0;
873
874 if is_nought_raw(&rem) {
875 #[cfg(test)]
876 {
877 tg.esc = PrimeCkEscCode::Dt;
878 }
879 return Some(false);
880 }
881 }
882
883 let sqrt = heron_sqrt_raw(&row);
886
887 #[cfg(test)]
888 {
889 if let Some(n) = try_into_num!(&sqrt, usize, &mut 0) {
890 tg.sqrt = n
891 }
892 }
893
894 let mut accel_cnt: [isize; 25] = [
896 1, -1, -3, -4, -6, -7, -9, -12, -13, -16, -18, -19, -21, -24, -27, -28, -31, -33, -34, -37, -39, -42, -46, -48, -49, ];
922
923 let then = Instant::now();
924 let (limited, limit) = if let Some(d) = lim {
925 (true, d)
926 } else {
927 (false, Duration::ZERO)
928 };
929
930 let increment = vec![2];
931 let mut probe = vec![5];
932 loop {
933 if limited && limit <= then.elapsed() {
934 return None;
935 }
936
937 addition_sum(&increment, &mut probe, 0);
938
939 if let Rel::Greater(_) = rel_raw(&probe, &sqrt) {
940 #[cfg(test)]
941 {
942 if !tg.check_starts {
943 tg.esc = PrimeCkEscCode::Pn;
944 }
945 }
946
947 return Some(true);
948 }
949
950 accel_cnt[0] += 1;
951 accel_cnt[1] += 1;
952 accel_cnt[2] += 1;
953 accel_cnt[3] += 1;
954 accel_cnt[4] += 1;
955
956 accel_cnt[5] += 1;
957 accel_cnt[6] += 1;
958 accel_cnt[7] += 1;
959 accel_cnt[8] += 1;
960 accel_cnt[9] += 1;
961
962 accel_cnt[10] += 1;
963 accel_cnt[11] += 1;
964 accel_cnt[12] += 1;
965 accel_cnt[13] += 1;
966 accel_cnt[14] += 1;
967
968 accel_cnt[15] += 1;
969 accel_cnt[16] += 1;
970 accel_cnt[17] += 1;
971 accel_cnt[18] += 1;
972 accel_cnt[19] += 1;
973
974 accel_cnt[20] += 1;
975 accel_cnt[21] += 1;
976 accel_cnt[22] += 1;
977 accel_cnt[23] += 1;
978 accel_cnt[24] += 1;
979
980 #[cfg(test)]
981 {
982 if tg.check_starts {
983 let probe_val = try_into_num!(probe, usize, &mut 0).unwrap();
984 if accel_cnt[0] == 3 {
985 tg.esc = PrimeCkEscCode::Hit_3_Start;
986 tg.peekhole = probe_val;
987 }
988
989 if probe[0] == 5 {
990 tg.esc = PrimeCkEscCode::Hit_5_Start;
991 tg.peekhole = probe_val;
992 }
993
994 if accel_cnt[1] == 0 {
995 tg.esc = PrimeCkEscCode::Hit_7_Start;
996 tg.peekhole = probe_val;
997 }
998
999 if accel_cnt[2] == 0 {
1000 tg.esc = PrimeCkEscCode::Hit_11_Start;
1001 tg.peekhole = probe_val;
1002 }
1003
1004 if accel_cnt[3] == 0 {
1005 tg.esc = PrimeCkEscCode::Hit_13_Start;
1006 tg.peekhole = probe_val;
1007 }
1008
1009 if accel_cnt[4] == 0 {
1010 tg.esc = PrimeCkEscCode::Hit_17_Start;
1011 tg.peekhole = probe_val;
1012 }
1013
1014 if accel_cnt[5] == 0 {
1015 tg.esc = PrimeCkEscCode::Hit_19_Start;
1016 tg.peekhole = probe_val;
1017 }
1018
1019 if accel_cnt[6] == 0 {
1020 tg.esc = PrimeCkEscCode::Hit_23_Start;
1021 tg.peekhole = probe_val;
1022 }
1023
1024 if accel_cnt[7] == 0 {
1025 tg.esc = PrimeCkEscCode::Hit_29_Start;
1026 tg.peekhole = probe_val;
1027 }
1028
1029 if accel_cnt[8] == 0 {
1030 tg.esc = PrimeCkEscCode::Hit_31_Start;
1031 tg.peekhole = probe_val;
1032 }
1033
1034 if accel_cnt[9] == 0 {
1035 tg.esc = PrimeCkEscCode::Hit_37_Start;
1036 tg.peekhole = probe_val;
1037 }
1038
1039 if accel_cnt[10] == 0 {
1040 tg.esc = PrimeCkEscCode::Hit_41_Start;
1041 tg.peekhole = probe_val;
1042 }
1043
1044 if accel_cnt[11] == 0 {
1045 tg.esc = PrimeCkEscCode::Hit_43_Start;
1046 tg.peekhole = probe_val;
1047 }
1048
1049 if accel_cnt[12] == 0 {
1050 tg.esc = PrimeCkEscCode::Hit_47_Start;
1051 tg.peekhole = probe_val;
1052 }
1053
1054 if accel_cnt[13] == 0 {
1055 tg.esc = PrimeCkEscCode::Hit_53_Start;
1056 tg.peekhole = probe_val;
1057 }
1058
1059 if accel_cnt[14] == 0 {
1060 tg.esc = PrimeCkEscCode::Hit_59_Start;
1061 tg.peekhole = probe_val;
1062 }
1063
1064 if accel_cnt[15] == 0 {
1065 tg.esc = PrimeCkEscCode::Hit_61_Start;
1066 tg.peekhole = probe_val;
1067 }
1068
1069 if accel_cnt[16] == 0 {
1070 tg.esc = PrimeCkEscCode::Hit_67_Start;
1071 tg.peekhole = probe_val;
1072 }
1073
1074 if accel_cnt[17] == 0 {
1075 tg.esc = PrimeCkEscCode::Hit_71_Start;
1076 tg.peekhole = probe_val;
1077 }
1078
1079 if accel_cnt[18] == 0 {
1080 tg.esc = PrimeCkEscCode::Hit_73_Start;
1081 tg.peekhole = probe_val;
1082 }
1083
1084 if accel_cnt[19] == 0 {
1085 tg.esc = PrimeCkEscCode::Hit_79_Start;
1086 tg.peekhole = probe_val;
1087 }
1088
1089 if accel_cnt[20] == 0 {
1090 tg.esc = PrimeCkEscCode::Hit_83_Start;
1091 tg.peekhole = probe_val;
1092 }
1093
1094 if accel_cnt[21] == 0 {
1095 tg.esc = PrimeCkEscCode::Hit_89_Start;
1096 tg.peekhole = probe_val;
1097 }
1098
1099 if accel_cnt[22] == 0 {
1100 tg.esc = PrimeCkEscCode::Hit_97_Start;
1101 tg.peekhole = probe_val;
1102 }
1103
1104 if accel_cnt[23] == 0 {
1105 tg.esc = PrimeCkEscCode::Hit_101_Start;
1106 tg.peekhole = probe_val;
1107 }
1108
1109 if accel_cnt[24] == 0 {
1110 tg.esc = PrimeCkEscCode::Hit_103_Start;
1111 tg.peekhole = probe_val;
1112 }
1113 }
1114 }
1115
1116 let mut probe_np = false;
1118 if accel_cnt[0] == 3 {
1119 accel_cnt[0] = 0;
1120 probe_np = true;
1121
1122 #[cfg(test)]
1123 {
1124 tg.cntrs[0] += 1;
1125 }
1126 }
1127
1128 if probe[0] == 5 {
1129 probe_np = true;
1130
1131 #[cfg(test)]
1132 {
1133 tg.cntrs[1] += 1;
1134 }
1135 }
1136
1137 if accel_cnt[1] == 7 {
1138 accel_cnt[1] = 0;
1139 probe_np = true;
1140
1141 #[cfg(test)]
1142 {
1143 tg.cntrs[2] += 1;
1144 }
1145 }
1146
1147 if accel_cnt[2] == 11 {
1148 accel_cnt[2] = 0;
1149 probe_np = true;
1150
1151 #[cfg(test)]
1152 {
1153 tg.cntrs[3] += 1;
1154 }
1155 }
1156
1157 if accel_cnt[3] == 13 {
1158 accel_cnt[3] = 0;
1159 probe_np = true;
1160
1161 #[cfg(test)]
1162 {
1163 tg.cntrs[4] += 1;
1164 }
1165 }
1166
1167 if accel_cnt[4] == 17 {
1168 accel_cnt[4] = 0;
1169 probe_np = true;
1170
1171 #[cfg(test)]
1172 {
1173 tg.cntrs[5] += 1;
1174 }
1175 }
1176
1177 if accel_cnt[5] == 19 {
1178 accel_cnt[5] = 0;
1179 probe_np = true;
1180
1181 #[cfg(test)]
1182 {
1183 tg.cntrs[6] += 1;
1184 }
1185 }
1186
1187 if accel_cnt[6] == 23 {
1188 accel_cnt[6] = 0;
1189 probe_np = true;
1190
1191 #[cfg(test)]
1192 {
1193 tg.cntrs[7] += 1;
1194 }
1195 }
1196
1197 if accel_cnt[7] == 29 {
1198 accel_cnt[7] = 0;
1199 probe_np = true;
1200
1201 #[cfg(test)]
1202 {
1203 tg.cntrs[8] += 1;
1204 }
1205 }
1206
1207 if accel_cnt[8] == 31 {
1208 accel_cnt[8] = 0;
1209 probe_np = true;
1210
1211 #[cfg(test)]
1212 {
1213 tg.cntrs[9] += 1;
1214 }
1215 }
1216
1217 if accel_cnt[9] == 37 {
1218 accel_cnt[9] = 0;
1219 probe_np = true;
1220
1221 #[cfg(test)]
1222 {
1223 tg.cntrs[10] += 1;
1224 }
1225 }
1226
1227 if accel_cnt[10] == 41 {
1228 accel_cnt[10] = 0;
1229 probe_np = true;
1230
1231 #[cfg(test)]
1232 {
1233 tg.cntrs[11] += 1;
1234 }
1235 }
1236
1237 if accel_cnt[11] == 43 {
1238 accel_cnt[11] = 0;
1239 probe_np = true;
1240
1241 #[cfg(test)]
1242 {
1243 tg.cntrs[12] += 1;
1244 }
1245 }
1246
1247 if accel_cnt[12] == 47 {
1248 accel_cnt[12] = 0;
1249 probe_np = true;
1250
1251 #[cfg(test)]
1252 {
1253 tg.cntrs[13] += 1;
1254 }
1255 }
1256
1257 if accel_cnt[13] == 53 {
1258 accel_cnt[13] = 0;
1259 probe_np = true;
1260
1261 #[cfg(test)]
1262 {
1263 tg.cntrs[14] += 1;
1264 }
1265 }
1266
1267 if accel_cnt[14] == 59 {
1268 accel_cnt[14] = 0;
1269 probe_np = true;
1270
1271 #[cfg(test)]
1272 {
1273 tg.cntrs[15] += 1;
1274 }
1275 }
1276
1277 if accel_cnt[15] == 61 {
1278 accel_cnt[15] = 0;
1279 probe_np = true;
1280
1281 #[cfg(test)]
1282 {
1283 tg.cntrs[16] += 1;
1284 }
1285 }
1286
1287 if accel_cnt[16] == 67 {
1288 accel_cnt[16] = 0;
1289 probe_np = true;
1290
1291 #[cfg(test)]
1292 {
1293 tg.cntrs[17] += 1;
1294 }
1295 }
1296
1297 if accel_cnt[17] == 71 {
1298 accel_cnt[17] = 0;
1299 probe_np = true;
1300
1301 #[cfg(test)]
1302 {
1303 tg.cntrs[18] += 1;
1304 }
1305 }
1306
1307 if accel_cnt[18] == 73 {
1308 accel_cnt[18] = 0;
1309 probe_np = true;
1310
1311 #[cfg(test)]
1312 {
1313 tg.cntrs[19] += 1;
1314 }
1315 }
1316 if accel_cnt[19] == 79 {
1317 accel_cnt[19] = 0;
1318 probe_np = true;
1319
1320 #[cfg(test)]
1321 {
1322 tg.cntrs[20] += 1;
1323 }
1324 }
1325 if accel_cnt[20] == 83 {
1326 accel_cnt[20] = 0;
1327 probe_np = true;
1328
1329 #[cfg(test)]
1330 {
1331 tg.cntrs[21] += 1;
1332 }
1333 }
1334 if accel_cnt[21] == 89 {
1335 accel_cnt[21] = 0;
1336 probe_np = true;
1337
1338 #[cfg(test)]
1339 {
1340 tg.cntrs[22] += 1;
1341 }
1342 }
1343 if accel_cnt[22] == 97 {
1344 accel_cnt[22] = 0;
1345 probe_np = true;
1346
1347 #[cfg(test)]
1348 {
1349 tg.cntrs[23] += 1;
1350 }
1351 }
1352 if accel_cnt[23] == 101 {
1353 accel_cnt[23] = 0;
1354 probe_np = true;
1355
1356 #[cfg(test)]
1357 {
1358 tg.cntrs[24] += 1;
1359 }
1360 }
1361 if accel_cnt[24] == 103 {
1362 accel_cnt[24] = 0;
1363 probe_np = true;
1364
1365 #[cfg(test)]
1366 {
1367 tg.cntrs[25] += 1;
1368 }
1369 }
1370
1371 if probe_np {
1372 continue;
1373 }
1374
1375 let rem = division(
1376 row,
1377 &probe,
1378 #[cfg(test)]
1379 &mut vec![],
1380 )
1381 .0;
1382
1383 if is_nought_raw(&rem) {
1384 #[cfg(test)]
1385 {
1386 if !tg.check_starts {
1387 tg.esc = PrimeCkEscCode::Np;
1388 }
1389 }
1390
1391 return Some(false);
1392 }
1393 }
1394}
1395#[derive(Clone, PartialEq, Debug)]
1397pub enum PrimeGenRes<T> {
1398 All(Vec<T>),
1400 Max(T),
1402}
1403
1404impl<T> PrimeGenRes<T> {
1405 pub fn uproot_all(self) -> Vec<T> {
1408 if let PrimeGenRes::All(all) = self {
1409 return all;
1410 }
1411
1412 panic!("Not `PrimeGenRes::All(_)` variant.");
1413 }
1414
1415 pub fn uproot_max(self) -> T {
1418 if let PrimeGenRes::Max(max) = self {
1419 return max;
1420 }
1421
1422 panic!("Not `PrimeGenRes::Max(_)` variant.");
1423 }
1424}
1425
1426pub trait PrimeGenResAide<T> {
1429 fn uproot_all(self) -> Vec<T>;
1431 fn uproot_max(self) -> T;
1433}
1434
1435impl<T> PrimeGenResAide<T> for Result<PrimeGenRes<T>, PrimeGenErr> {
1436 fn uproot_all(self) -> Vec<T> {
1440 if let Ok(r) = self {
1441 return r.uproot_all();
1442 }
1443
1444 panic!("Not `Ok(_)` variant.");
1445 }
1446
1447 fn uproot_max(self) -> T {
1451 if let Ok(r) = self {
1452 return r.uproot_max();
1453 }
1454
1455 panic!("Not `Ok(_)` variant.");
1456 }
1457}
1458
1459#[derive(Clone, PartialEq, Debug)]
1461pub enum PrimeGenErr {
1462 InputGreaterThanSizeMax(usize),
1464 ValueGreaterThanSizeMax(usize, usize),
1466 AimlessInput(usize),
1468 TimeframeExhaustion,
1470}
1471
1472#[derive(Clone, PartialEq, Debug)]
1474pub enum PrimeGenClass {
1475 Nth,
1477 Lim,
1479}
1480
1481#[macro_export]
1543macro_rules! pg {
1544 ($input: expr, $pgc: expr, $all: expr, $size:tt, $lim: expr) => {{
1545 if 0 == $input {
1546 return Err(PrimeGenErr::AimlessInput(0));
1547 }
1548
1549 #[allow(unused_comparisons)]
1550 if $input > $size::MAX as usize {
1551 return Err(PrimeGenErr::InputGreaterThanSizeMax($input));
1552 }
1553
1554 let nth = $pgc == PrimeGenClass::Nth;
1555
1556 let cap = if nth {
1557 $input
1558 } else {
1559 if $input == 1 {
1560 return Err(PrimeGenErr::AimlessInput(1));
1561 }
1562
1563 let ln = ($input as f64).log(std::f64::consts::E);
1564 let divisor = ln.max(1.0).floor();
1565 let ratio = $input as f64 / divisor;
1566
1567 (ratio * 1.15) as usize
1568 };
1569
1570 let mut aperture = Vec::<($size, $size)>::new();
1571 aperture.reserve_exact(cap);
1572
1573 aperture.push((2, 0));
1574
1575 let then = Instant::now();
1576 let (limited, limit) = if let Some(d) = $lim {
1577 (true, d)
1578 } else {
1579 (false, Duration::ZERO)
1580 };
1581
1582 let buff = aperture.as_mut_ptr();
1583
1584 let mut len = 1;
1585 let mut attempt = 1;
1586 loop {
1587 attempt += 2;
1588 if nth {
1589 if len == $input {
1590 break;
1591 }
1592 } else {
1593 if attempt > $input {
1594 break;
1595 }
1596 }
1597
1598 if limited && then.elapsed() >= limit {
1599 return Err(PrimeGenErr::TimeframeExhaustion);
1600 }
1601
1602 let mut prime = true;
1603
1604 let mut offset = 1;
1605 while offset < len {
1606 let scene = unsafe { buff.add(offset).as_mut().unwrap_unchecked() };
1607
1608 offset += 1;
1609
1610 let mut count = scene.1;
1611 count += 1;
1612
1613 scene.1 = if count == scene.0 {
1614 prime = false;
1615 0
1616 } else {
1617 count
1618 }
1619 }
1620
1621 if prime {
1622 #[allow(irrefutable_let_patterns)]
1623 if let Ok(prime) = TryInto::<$size>::try_into(attempt) {
1624 unsafe { buff.add(len).write((prime, 0)) };
1625 len += 1;
1626 } else {
1627 unsafe { aperture.set_len(len) }
1628 return Err(PrimeGenErr::ValueGreaterThanSizeMax($input, attempt));
1629 }
1630 }
1631 }
1632
1633 unsafe { aperture.set_len(len) }
1634
1635 if $all {
1636 let mut all = Vec::<$size>::new();
1637 all.reserve_exact(len);
1638
1639 let all_buff = all.as_mut_ptr();
1640 let mut ix = 0;
1641 while ix < len {
1642 unsafe {
1643 let scene = buff.add(ix).as_ref().unwrap_unchecked();
1644 all_buff.add(ix).write(scene.0)
1645 }
1646 ix += 1;
1647 }
1648
1649 unsafe { all.set_len(len) }
1650
1651 Ok(PrimeGenRes::All(all))
1652 } else {
1653 Ok(PrimeGenRes::Max(aperture[len - 1].0))
1654 }
1655 }};
1656}
1657
1658#[macro_export]
1669macro_rules! pg_sw {
1670 ($input: expr, $pgc: expr, $all: expr, $size:tt, $lim: expr) => {{
1671 if 0 == $input {
1672 return Err(PrimeGenErr::AimlessInput(0));
1673 }
1674
1675 #[allow(unused_comparisons)]
1676 if $input > ($size::MAX as usize) {
1677 return Err(PrimeGenErr::InputGreaterThanSizeMax($input));
1678 }
1679
1680 let nth = $pgc == PrimeGenClass::Nth;
1681
1682 let cap = if nth {
1683 $input
1684 } else {
1685 if $input == 1 {
1686 return Err(PrimeGenErr::AimlessInput(1));
1687 }
1688
1689 let ln = ($input as f64).log(std::f64::consts::E);
1690 let divisor = ln.max(1.0).floor();
1691 let ratio = $input as f64 / divisor;
1692
1693 (ratio * 1.15) as usize
1694 };
1695
1696 let mut aperture = Vec::<$size>::new();
1697 aperture.reserve_exact(cap);
1698
1699 aperture.push(2);
1700
1701 let then = Instant::now();
1702 let (limited, limit) = if let Some(d) = $lim {
1703 (true, d)
1704 } else {
1705 (false, Duration::ZERO)
1706 };
1707
1708 let buff = aperture.as_mut_ptr();
1709
1710 let mut len = 1;
1711 let mut attempt = 1;
1712 'gen: loop {
1713 attempt += 2;
1714 if nth {
1715 if len == $input {
1716 break;
1717 }
1718 } else {
1719 if attempt > $input {
1720 break;
1721 }
1722 }
1723
1724 if limited && then.elapsed() >= limit {
1725 return Err(PrimeGenErr::TimeframeExhaustion);
1726 }
1727
1728 let mut rix = 1;
1729 #[allow(unused_labels)]
1730 'ver: while rix < len {
1731 let scene = unsafe { buff.add(rix).read() };
1732 rix += 1;
1733
1734 if attempt % scene as usize == 0 {
1735 continue 'gen;
1736 }
1737 }
1738
1739 #[allow(irrefutable_let_patterns)]
1740 if let Ok(prime) = TryInto::<$size>::try_into(attempt) {
1741 unsafe { buff.add(len).write(prime) };
1742 len += 1;
1743 } else {
1744 unsafe { aperture.set_len(len) };
1745 return Err(PrimeGenErr::ValueGreaterThanSizeMax($input, attempt));
1746 }
1747 }
1748
1749 unsafe { aperture.set_len(len) }
1750
1751 if $all {
1752 Ok(PrimeGenRes::All(aperture))
1753 } else {
1754 Ok(PrimeGenRes::Max(aperture[len - 1]))
1755 }
1756 }};
1757}
1758
1759pub fn heron_sqrt(num: &PlacesRow) -> PlacesRow {
1765 let row = heron_sqrt_raw(&num.row);
1766 PlacesRow { row }
1767}
1768
1769fn heron_sqrt_raw(row: &[u8]) -> RawRow {
1770 if is_unity_raw(&row) || is_nought_raw(&row) {
1771 return row.to_vec();
1772 }
1773
1774 let two = &vec![2];
1775 let mut cur = division(
1776 row,
1777 two,
1778 #[cfg(test)]
1779 &mut vec![],
1780 )
1781 .1;
1782
1783 loop {
1784 let mut rat = division(
1785 &row,
1786 &cur,
1787 #[cfg(test)]
1788 &mut vec![],
1789 )
1790 .1;
1791
1792 addition_sum(&cur, &mut rat, 0);
1793 let nex = division_dynamo(
1794 rat,
1795 &two,
1796 #[cfg(test)]
1797 &mut vec![],
1798 )
1799 .1;
1800
1801 if let Rel::Lesser(_) = rel_raw(&nex, &cur) {
1802 cur = nex;
1803 } else {
1804 break;
1805 }
1806 }
1807
1808 cur
1809}
1810
1811#[cfg(test)]
1812use tests_of_units::division::DivRemGrade;
1813
1814fn division(
1815 dividend: &[u8],
1816 divisor: &[u8],
1817 #[cfg(test)] codes: &mut Vec<DivRemGrade>,
1818) -> (RawRow, RawRow) {
1819 let dividend = dividend.to_vec();
1820 division_dynamo(
1821 dividend,
1822 divisor,
1823 #[cfg(test)]
1824 codes,
1825 )
1826}
1827
1828fn division_dynamo(
1829 mut end: Vec<u8>,
1830 sor: &[u8],
1831 #[cfg(test)] codes: &mut Vec<DivRemGrade>,
1832) -> (RawRow, RawRow) {
1833 let mut end_len = end.len();
1834 let sor_len = sor.len();
1835
1836 #[cfg(test)]
1837 assert_eq!(false, is_nought_raw(sor));
1838
1839 if end_len < sor_len {
1840 #[cfg(test)]
1841 codes.push(DivRemGrade::DLBPI);
1842 return (end, nought_raw());
1843 }
1844
1845 let mut ratio = Vec::with_capacity(50);
1846 let mut start_ix = dividend_start(&end, sor);
1847
1848 'div: loop {
1849 let (rat, rem_len) = subtraction_divisional(&mut end[start_ix..end_len], sor);
1850
1851 #[cfg(test)]
1852 assert_eq!(true, rat.len() == 1);
1853
1854 ratio.insert(0, rat[0]);
1855
1856 end_len = start_ix + rem_len;
1857
1858 if rem_len == 0 && end_len > 0 {
1859 let mut pix = end_len;
1861
1862 while pix > 0 {
1863 pix -= 1;
1864 if end[pix] != 0 {
1865 pix += 1;
1866 break;
1867 }
1868 }
1869
1870 let places = end_len - pix;
1871 if places > 0 {
1872 add_places(&mut ratio, places);
1873 end_len -= places;
1874 }
1875
1876 #[cfg(test)]
1877 {
1878 let c = if end_len == 0 {
1879 DivRemGrade::DFVD
1880 } else if places > 0 {
1881 DivRemGrade::DPVD
1882 } else {
1883 DivRemGrade::NDVD
1884 };
1885
1886 codes.push(c);
1887 }
1888 }
1889
1890 if end_len == 0 {
1891 #[cfg(test)]
1892 codes.push(DivRemGrade::DEXH);
1893
1894 break 'div;
1895 }
1896
1897 let undivided_places = end_len - rem_len;
1898 if end_len < sor_len {
1899 if start_ix > 0 {
1900 #[cfg(test)]
1901 codes.push(DivRemGrade::RVD);
1902
1903 add_places(&mut ratio, undivided_places);
1904 }
1905
1906 #[cfg(test)]
1907 codes.push(DivRemGrade::DLBP);
1908 break 'div;
1909 }
1910
1911 if start_ix == 0 {
1912 #[cfg(test)]
1913 codes.push(DivRemGrade::DLBV);
1914
1915 break 'div;
1916 }
1917
1918 start_ix = dividend_start(&end[..end_len], sor);
1919 let places = undivided_places - start_ix - 1;
1920
1921 if places > 0 {
1922 #[cfg(test)]
1923 codes.push(DivRemGrade::DEVD);
1924
1925 add_places(&mut ratio, places);
1926 }
1927 }
1928
1929 #[cfg(test)]
1930 assert_eq!(true, (end_len == 0 && end[0] == 0) || end_len > 0);
1931
1932 end.truncate(max(end_len, 1));
1933
1934 return (end, ratio);
1935
1936 fn add_places(ratio: &mut RawRow, mut p: usize) {
1937 while p > 0 {
1938 p -= 1;
1939 ratio.insert(0, 0);
1940 }
1941 }
1942}
1943
1944fn dividend_start(end: &[u8], sor: &[u8]) -> usize {
1947 #[cfg(test)]
1948 assert_eq!(true, end.len() >= sor.len(), "Dividend has less places.");
1949
1950 let mut end_ix = end.len();
1951 let mut sor_ix = sor.len();
1952
1953 let mut start_ix = end_ix - sor_ix;
1954
1955 if start_ix > 0 {
1956 while sor_ix > 0 {
1957 end_ix -= 1;
1958 sor_ix -= 1;
1959
1960 let end_num = end[end_ix];
1961 let sor_num = sor[sor_ix];
1962
1963 if end_num > sor_num {
1964 break;
1965 }
1966
1967 if end_num < sor_num {
1968 start_ix -= 1;
1969 break;
1970 }
1971 }
1972 }
1973
1974 start_ix
1975}
1976
1977const MUL_DYNAMO_CAP: usize = 1000;
1978fn multiplication(mpler: &[u8], mcand: &[u8]) -> RawRow {
1979 let mpler_len = mpler.len();
1980
1981 let mut sum = Vec::with_capacity(MUL_DYNAMO_CAP);
1982
1983 let mut offset = 0;
1984 while offset < mpler_len {
1985 muladd(mpler[offset], &mcand, &mut sum, offset);
1986 offset += 1;
1987 }
1988
1989 sum
1990}
1991
1992fn power_steps(mut step: u16) -> Vec<u16> {
1993 #[cfg(test)]
1994 {
1995 if step < 2 {
1996 panic!("Pow steps for powers > 1 only.");
1997 }
1998 }
1999
2000 let mut steps = Vec::with_capacity(15);
2001 loop {
2002 steps.push(step);
2003
2004 step >>= 1;
2005 if step == 1 {
2006 break;
2007 }
2008 }
2009
2010 steps
2011}
2012
2013const POWER_CAP: usize = 2500;
2014fn power(base: &[u8], pow: u16) -> RawRow {
2015 let mut sum = Vec::with_capacity(POWER_CAP);
2016 let mut mcand = Vec::with_capacity(POWER_CAP);
2017
2018 mcand.extend_from_slice(base);
2019
2020 let steps = power_steps(pow);
2021 let mut s_iter = steps.iter();
2022 let mut curr_s = unsafe { s_iter.next_back().unwrap_unchecked() };
2023
2024 let base_len = base.len();
2025 let mut offset;
2026 loop {
2027 let mcand_len = mcand.len();
2028 offset = 0;
2029 while offset < mcand_len {
2030 muladd(mcand[offset], &mcand, &mut sum, offset);
2031 offset += 1;
2032 }
2033
2034 if curr_s & 1 == 1 {
2035 clear_swap(&mut mcand, &mut sum);
2036
2037 offset = 0;
2038 while offset < base_len {
2039 muladd(base[offset], &mcand, &mut sum, offset);
2040 offset += 1;
2041 }
2042 }
2043
2044 if let Some(s) = s_iter.next_back() {
2045 curr_s = s
2046 } else {
2047 break;
2048 }
2049
2050 clear_swap(&mut mcand, &mut sum);
2051 }
2052
2053 sum
2054}
2055
2056fn clear_swap<'a>(mcand: *mut RawRow, i_sum: *mut RawRow) {
2057 unsafe {
2058 let mut swap = mcand.read();
2059 swap.clear();
2060
2061 mcand.write(i_sum.read());
2062 i_sum.write(swap);
2063 }
2064}
2065
2066fn muladd(mpler: u8, mcand: &[u8], sum: &mut Vec<u8>, place_off: usize) {
2080 let mut ix = 0;
2081 let mcand_len = mcand.len();
2082
2083 loop {
2084 let prod = mpler * mcand[ix];
2085
2086 sumadd(prod, sum, place_off + ix);
2087
2088 ix += 1;
2089 if ix == mcand_len {
2090 break;
2091 }
2092 }
2093}
2094
2095fn sumadd(mut addend: u8, sum: &mut RawRow, mut off: usize) {
2096 let mut takeover = 0;
2097 let sum_len = sum.len();
2098
2099 loop {
2100 if off < sum_len {
2101 sum[off] = ones(sum[off] + addend, &mut takeover);
2102 off += 1;
2103 } else {
2104 let num = ones(addend, &mut takeover);
2105 sum.push(num);
2106 };
2107
2108 if takeover == 0 {
2109 break;
2110 } else {
2111 addend = 0;
2112 }
2113 }
2114}
2115
2116fn addition_sum(addend: &[u8], sum: &mut RawRow, offset: usize) {
2117 let a_len = addend.len();
2118 let s_len = sum.len();
2119
2120 let mut takeover = 0;
2121 let mut a_inx = 0;
2122 let mut s_inx = offset;
2123
2124 loop {
2125 let a_available = a_inx < a_len;
2126 if !a_available && takeover == 0 {
2127 break;
2128 }
2129
2130 let a_num = if a_available { addend[a_inx] } else { 0 };
2131
2132 let s_available = s_inx < s_len;
2133 let s_num = if s_available { sum[s_inx] } else { 0 };
2134
2135 let add = ones(s_num + a_num, &mut takeover);
2136
2137 if s_available {
2138 sum[s_inx] = add;
2139 } else {
2140 sum.push(add);
2141 }
2142
2143 a_inx += 1;
2144 s_inx += 1;
2145 }
2146}
2147
2148fn addition_two(lh_addend: &[u8], rh_addend: &[u8], sum: &mut RawRow) {
2149 let lha_len = lh_addend.len();
2150 let rha_len = rh_addend.len();
2151
2152 let mut takeover = 0;
2153 let mut a_inx = 0;
2154
2155 loop {
2156 let lha_available = a_inx < lha_len;
2157 let rha_available = a_inx < rha_len;
2158
2159 if !(lha_available || rha_available) && takeover == 0 {
2160 break;
2161 }
2162
2163 let lha_num = if lha_available { lh_addend[a_inx] } else { 0 };
2164 let rha_num = if rha_available { rh_addend[a_inx] } else { 0 };
2165
2166 let add = ones(lha_num + rha_num, &mut takeover);
2167 sum.push(add);
2168
2169 a_inx += 1;
2170 }
2171}
2172
2173fn subtraction_arithmetical(minuend: &mut RawRow, subtrahend: &[u8]) -> RawRow {
2174 let ratio = subtraction(
2175 minuend,
2176 subtrahend,
2177 false,
2178 #[cfg(test)]
2179 &mut 0,
2180 );
2181
2182 truncate_leading_raw(minuend, 0, 1);
2183 ratio
2184}
2185
2186fn subtraction_divisional(mut minuend: &mut [u8], subtrahend: &[u8]) -> (RawRow, usize) {
2187 let ratio = subtraction(
2188 minuend,
2189 subtrahend,
2190 true,
2191 #[cfg(test)]
2192 &mut 0,
2193 );
2194
2195 let mut len = len_without_leading_raw(minuend, 9, subtrahend.len());
2196 minuend = &mut minuend[..len];
2197
2198 len = len_without_leading_raw(minuend, 0, 0);
2199
2200 (ratio, len)
2201}
2202
2203fn subtraction(
2209 minuend: &mut [u8],
2210 subtrahend: &[u8],
2211 remainder: bool,
2212 #[cfg(test)] ctr: &mut usize,
2213) -> RawRow {
2214 let minuend_len = minuend.len();
2215 let subtrahend_len = subtrahend.len();
2216
2217 let mut ratio = nought_raw();
2218 let unity = unity_raw();
2219
2220 let mut takeover;
2221 let mut inx;
2222 loop {
2223 #[cfg(test)]
2224 {
2225 *ctr += 1;
2226 }
2227
2228 takeover = 0;
2229 inx = 0;
2230
2231 while inx < minuend_len {
2232 let s_num = if inx < subtrahend_len {
2233 subtrahend[inx]
2234 } else if takeover == 0 {
2235 break;
2236 } else {
2237 0
2238 };
2239
2240 let mut m_num = minuend[inx];
2241
2242 let total_s = s_num + takeover;
2243 takeover = if m_num < total_s {
2244 m_num += 10;
2245 1
2246 } else {
2247 0
2248 };
2249
2250 minuend[inx] = m_num - total_s;
2251 inx += 1;
2252 }
2253
2254 if takeover == 1 {
2257 inx = 0;
2258 takeover = 0;
2259
2260 while inx < subtrahend_len {
2261 let correction = minuend[inx] + subtrahend[inx];
2262 minuend[inx] = ones(correction, &mut takeover);
2263 inx += 1;
2264 }
2265
2266 break;
2267 }
2268
2269 addition_sum(&unity, &mut ratio, 0);
2270
2271 if remainder {
2272 continue;
2273 }
2274
2275 break;
2276 }
2277
2278 ratio
2279}
2280
2281const fn ones(num: u8, takeover_ref: &mut u8) -> u8 {
2287 let mut takeover_val = *takeover_ref;
2288 let total = num + takeover_val;
2289
2290 takeover_val = total / 10;
2291 *takeover_ref = takeover_val;
2292
2293 total - takeover_val * 10
2294}
2295
2296#[cfg(test)]
2297mod tests_of_units {
2298
2299 use crate::RawRow;
2300
2301 fn unity() -> RawRow {
2302 [1].to_vec()
2303 }
2304
2305 fn nought() -> RawRow {
2306 [0].to_vec()
2307 }
2308
2309 mod placesrow {
2310 use crate::Row;
2311
2312 mod new_from_vec {
2313 use crate::Row;
2314
2315 #[test]
2316 fn basic_test() {
2317 let row = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
2318 let proof = row.clone();
2319 let row = Row::new_from_vec(row);
2320
2321 assert!(row.is_ok());
2322 assert_eq!(proof, row.unwrap().row);
2323 }
2324
2325 #[test]
2326 fn zero_len_test() {
2327 let row = Row::new_from_vec(vec![0; 0]);
2328 assert!(row.is_err());
2329 assert_eq!(None, row.err().unwrap());
2330 }
2331
2332 #[test]
2333 fn unsupported_num_len_index_test() {
2334 let row = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
2335 let row = Row::new_from_vec(row);
2336
2337 assert!(row.is_err());
2338 assert_eq!(Some(10), row.err().unwrap());
2339 }
2340
2341 #[test]
2342 fn unsupported_num_0_index_test() {
2343 let row = vec![10, 0, 0, 0];
2344 let row = Row::new_from_vec(row);
2345
2346 assert!(row.is_err());
2347 assert_eq!(Some(0), row.err().unwrap());
2348 }
2349
2350 #[test]
2351 fn leading_zeros_trim_test() {
2352 let row = Row::new_from_vec(vec![1, 2, 0, 0]);
2353 assert_eq!(&[1, 2], &*row.unwrap().row);
2354 }
2355
2356 #[test]
2357 fn zero_reduction_test() {
2358 let row = Row::new_from_vec(vec![0, 0, 0, 0]);
2359 assert_eq!(&[0], &*row.unwrap().row);
2360 }
2361 }
2362
2363 mod new_from {
2364 use crate::Row;
2365
2366 #[test]
2367 fn zero_test() {
2368 let row = Row::new_from_usize(0);
2369 assert_eq!(&[0], &*row);
2370 }
2371
2372 #[test]
2373 fn new_from_u8_test() {
2374 let row = Row::new_from_u8(000_123u8);
2375 assert_eq!(&[3, 2, 1], &*row);
2376 }
2377
2378 #[test]
2379 fn new_from_u16_test() {
2380 let row = Row::new_from_u16(000_12345u16);
2381 assert_eq!(&[5, 4, 3, 2, 1], &*row);
2382 }
2383
2384 #[test]
2385 fn new_from_u32_test() {
2386 let row = Row::new_from_u32(000_1234567890u32);
2387 assert_eq!(&[0, 9, 8, 7, 6, 5, 4, 3, 2, 1], &*row);
2388 }
2389
2390 #[test]
2391 fn new_from_u64_test() {
2392 let row = Row::new_from_u64(000_1234567890u64);
2393 assert_eq!(&[0, 9, 8, 7, 6, 5, 4, 3, 2, 1], &*row);
2394 }
2395
2396 #[test]
2397 fn new_from_u128_test() {
2398 let row = Row::new_from_u128(000_12345678900u128);
2399 assert_eq!(&[0, 0, 9, 8, 7, 6, 5, 4, 3, 2, 1], &*row);
2400 }
2401
2402 #[test]
2403 fn new_from_usize_test() {
2404 let row = Row::new_from_usize(000_1234567890usize);
2405 assert_eq!(&[0, 9, 8, 7, 6, 5, 4, 3, 2, 1], &*row);
2406 }
2407 }
2408
2409 mod try_into {
2410 use crate::Row;
2411
2412 #[test]
2413 fn try_into_u8_test() {
2414 let num = u8::MAX;
2415 let row = new_from_num!(num);
2416 let test = row.try_into_u8();
2417 assert_eq!(Some(num), test);
2418 }
2419
2420 #[test]
2421 fn try_into_u16_test() {
2422 let num = u16::MAX;
2423 let row = new_from_num!(num);
2424
2425 let test = row.try_into_u16();
2426 assert_eq!(Some(num), test);
2427 }
2428
2429 #[test]
2430 fn try_into_u32_test() {
2431 let num = u32::MAX;
2432 let row = new_from_num!(num);
2433
2434 let test = row.try_into_u32();
2435 assert_eq!(Some(num), test);
2436 }
2437
2438 #[test]
2439 fn try_into_u64_test() {
2440 let num = u64::MAX;
2441 let row = new_from_num!(num);
2442
2443 let test = row.try_into_u64();
2444 assert_eq!(Some(num), test);
2445 }
2446
2447 #[test]
2448 fn try_into_u128_test() {
2449 let num = u128::MAX;
2450 let row = new_from_num!(num);
2451
2452 let test = row.try_into_u128();
2453 assert_eq!(Some(num), test);
2454 }
2455
2456 #[test]
2457 fn try_into_usize_test() {
2458 let num = usize::MAX;
2459 let row = new_from_num!(num);
2460
2461 let test = row.try_into_usize();
2462 assert_eq!(Some(num), test);
2463 }
2464
2465 #[test]
2466 fn try_into_i8_test() {
2467 let num = i8::MAX;
2468 let row = new_from_num!(num);
2469 let test = row.try_into_i8();
2470 assert_eq!(Some(num), test);
2471 }
2472
2473 #[test]
2474 fn try_into_i16_test() {
2475 let num = i16::MAX;
2476 let row = new_from_num!(num);
2477
2478 let test = row.try_into_i16();
2479 assert_eq!(Some(num), test);
2480 }
2481
2482 #[test]
2483 fn try_into_i32_test() {
2484 let num = i32::MAX;
2485 let row = new_from_num!(num);
2486
2487 let test = row.try_into_i32();
2488 assert_eq!(Some(num), test);
2489 }
2490
2491 #[test]
2492 fn try_into_i64_test() {
2493 let num = i64::MAX;
2494 let row = new_from_num!(num);
2495
2496 let test = row.try_into_i64();
2497 assert_eq!(Some(num), test);
2498 }
2499
2500 #[test]
2501 fn try_into_i128_test() {
2502 let num = i128::MAX;
2503 let row = new_from_num!(num);
2504
2505 let test = row.try_into_i128();
2506 assert_eq!(Some(num), test);
2507 }
2508
2509 #[test]
2510 fn try_into_isize_test() {
2511 let num = isize::MAX;
2512 let row = new_from_num!(num);
2513
2514 let test = row.try_into_isize();
2515 assert_eq!(Some(num), test);
2516 }
2517 }
2518
2519 mod new_from_str {
2520
2521 use crate::Row;
2522
2523 #[test]
2524 fn ok_test() {
2525 let row = Row::new_from_str("1234567890");
2526 assert_eq!(vec![0, 9, 8, 7, 6, 5, 4, 3, 2, 1], row.unwrap().row);
2527 }
2528
2529 #[test]
2530 fn err_test() {
2531 let row = Row::new_from_str("");
2532 assert_eq!(Err(None), row);
2533 }
2534 }
2535
2536 mod to_number {
2537 use crate::Row;
2538
2539 #[test]
2540 fn basic_test() {
2541 let row = Row::new_from_vec(vec![0, 9, 8, 7, 6, 5, 4, 3, 2, 1]).unwrap();
2542 assert_eq!("1234567890", row.to_number().as_str());
2543 }
2544 }
2545
2546 use super::{nought, unity};
2547 #[test]
2548 fn is_unity_test() {
2549 let test = Row { row: unity() };
2550 assert_eq!(true, test.is_unity());
2551 }
2552
2553 #[test]
2554 fn is_nought_test() {
2555 let test = Row { row: nought() };
2556 assert_eq!(true, test.is_nought());
2557 }
2558
2559 #[test]
2560 fn unity_test() {
2561 let proof = Row { row: unity() };
2562 assert_eq!(proof, Row::unity());
2563 }
2564
2565 #[test]
2566 fn nought_test() {
2567 let proof = Row { row: nought() };
2568 assert_eq!(proof, Row::nought());
2569 }
2570
2571 #[test]
2572 #[allow(deprecated)]
2573 fn zero_test() {
2574 assert_eq!(&[0], &*Row::zero());
2575 }
2576
2577 #[test]
2578 fn places_test() {
2579 let unity = Row::unity();
2580 assert_eq!(1, unity.places());
2581 }
2582
2583 #[test]
2584 fn to_string_test() {
2585 let row = Row::new_from_usize(1);
2586 assert_eq!("1", row.to_string());
2587 }
2588
2589 #[test]
2590 fn from_u8_test() {
2591 let row: Row = From::<u8>::from(123);
2592 assert_eq!(&[3, 2, 1], &*row);
2593 }
2594
2595 #[test]
2596 fn from_u16_test() {
2597 let row: Row = From::<u16>::from(123);
2598 assert_eq!(&[3, 2, 1], &*row);
2599 }
2600
2601 #[test]
2602 fn from_u32_test() {
2603 let row: Row = From::<u32>::from(123);
2604 assert_eq!(&[3, 2, 1], &*row);
2605 }
2606
2607 #[test]
2608 fn from_u64_test() {
2609 let row: Row = From::<u64>::from(123);
2610 assert_eq!(&[3, 2, 1], &*row);
2611 }
2612
2613 #[test]
2614 fn from_u128_test() {
2615 let row: Row = From::<u128>::from(123);
2616 assert_eq!(&[3, 2, 1], &*row);
2617 }
2618
2619 #[test]
2620 fn from_usize_test() {
2621 let row: Row = From::<usize>::from(123);
2622 assert_eq!(&[3, 2, 1], &*row);
2623 }
2624 }
2625
2626 mod new_from_str_raw {
2627 use crate::new_from_str_raw;
2628
2629 #[test]
2630 fn zero_len_test() {
2631 let row = new_from_str_raw("");
2632 assert!(row.is_err());
2633 assert_eq!(None, row.err().unwrap());
2634 }
2635
2636 #[test]
2637 fn leading_zeros_trim_test() {
2638 let row = new_from_str_raw("0021");
2639 assert!(row.is_ok());
2640 assert_eq!(&[1, 2], &*row.unwrap());
2641 }
2642
2643 #[test]
2644 fn zeros_reduction_test() {
2645 let row = new_from_str_raw("0000");
2646 assert!(row.is_ok());
2647 assert_eq!(&[0], &*row.unwrap());
2648 }
2649
2650 #[test]
2651 fn nondigit_str_test() {
2652 let row = new_from_str_raw("0012w123");
2653 assert!(row.is_err());
2654 let inx = row.err().unwrap();
2655 assert!(inx.is_some());
2656 assert_eq!(4, inx.unwrap());
2657 }
2658
2659 #[test]
2660 fn basic_test() {
2661 let row = new_from_str_raw("1234567890");
2662 assert!(row.is_ok());
2663 assert_eq!(&[0, 9, 8, 7, 6, 5, 4, 3, 2, 1], &*row.unwrap());
2664 }
2665 }
2666
2667 mod truncate_leading_raw {
2668 use crate::truncate_leading_raw;
2669
2670 #[test]
2671 fn basic_test() {
2672 let mut row = vec![7, 7, 7, 7, 7];
2673 truncate_leading_raw(&mut row, 7, 3);
2674 assert_eq!(vec![7, 7, 7,], row);
2675 }
2676 }
2677
2678 mod len_without_leading_raw {
2679 use crate::len_without_leading_raw;
2680
2681 #[test]
2682 fn counting_test() {
2683 let count = len_without_leading_raw(&vec![1, 2, 5, 5, 5], 5, 0);
2684 assert_eq!(2, count);
2685 }
2686
2687 #[test]
2688 fn preservation_test() {
2689 let count = len_without_leading_raw(&vec![5, 5, 5, 5], 5, 1);
2690 assert_eq!(1, count);
2691 }
2692
2693 #[test]
2694 fn no_leading_test() {
2695 let count = len_without_leading_raw(&vec![5, 5, 5, 0], 5, 0);
2696 assert_eq!(4, count);
2697 }
2698
2699 #[test]
2700 fn exto_equal_len_test() {
2701 let count = len_without_leading_raw(&vec![5, 5, 5], 5, 3);
2702 assert_eq!(3, count);
2703 }
2704 }
2705
2706 use crate::{is_nought_raw, is_unity_raw, nought_raw, unity_raw};
2707 #[test]
2708 fn unity_raw_test() {
2709 assert_eq!(unity(), unity_raw());
2710 }
2711
2712 #[test]
2713 fn nought_raw_test() {
2714 assert_eq!(nought(), nought_raw());
2715 }
2716
2717 #[test]
2718 fn is_unity_raw_test() {
2719 assert_eq!(true, is_unity_raw(&unity()));
2720 }
2721
2722 #[test]
2723 fn is_nought_raw_test() {
2724 assert_eq!(true, is_nought_raw(&nought()));
2725 }
2726
2727 mod is_one_raw {
2728 use crate::is_one_raw;
2729
2730 #[test]
2731 fn is_test() {
2732 let test = [3].to_vec();
2733 assert_eq!(true, is_one_raw(&test, 3));
2734 }
2735
2736 #[test]
2737 fn different_test() {
2738 let test = [3].to_vec();
2739 assert_eq!(false, is_one_raw(&test, 4));
2740 }
2741
2742 #[test]
2743 fn longer_test() {
2744 let test = [3, 3].to_vec();
2745 assert_eq!(false, is_one_raw(&test, 3));
2746 }
2747 }
2748
2749 mod from_digit {
2750
2751 use crate::from_digit;
2752 use std::panic::catch_unwind;
2753
2754 #[test]
2755 fn basic_test() {
2756 for proof in 0..=9 {
2757 let test = from_digit(proof.to_string().chars().next().unwrap());
2758 assert_eq!(proof, test);
2759 }
2760 }
2761
2762 #[test]
2763 fn unsupported_char_test() {
2764 let uc = ['0' as u8 - 1, '9' as u8 + 1];
2765
2766 for c in uc {
2767 let c = c as char;
2768
2769 let proof = format!("Unsupported char `{c}` conversion.");
2770 let catch = catch_unwind(|| from_digit(c));
2771
2772 assert!(catch.is_err());
2773 let err = catch.unwrap_err().downcast::<String>().unwrap();
2774 assert_eq!(proof, *err);
2775 }
2776 }
2777 }
2778
2779 mod to_digit {
2780 use crate::to_digit;
2781
2782 #[test]
2783 fn basic_test() {
2784 for n in 0..=9 {
2785 let test = to_digit(n);
2786 let proof = n.to_string().chars().next().unwrap();
2787 assert_eq!(proof, test);
2788 }
2789 }
2790
2791 #[test]
2792 #[should_panic(expected = "Only number < 10 supported.")]
2793 fn less_than_10_support_only_test() {
2794 to_digit(10);
2795 }
2796 }
2797
2798 mod ord_of_mag {
2799
2800 use crate::{ord_of_mag, Oom, OomClass, PlacesRow, Row};
2801
2802 const PROOF: &str = "3162277660168379331998893544432718533719555139325216826857504852792594438639238221344248108379300295187347284152840055148548856030453880014690519596700153903344921657179259940659150153474113339484124085316929577090471576461044369257879062037808609941828371711548406328552999118596824564203326961604691314336128949791890266529543612676178781350061388186278580463683134952478031143769334671973819513185678403231241795402218308045872844614600253577579702828644029024407977896034543989163349222652612067792651676031048436697793756926155720500369894909469421850007358348844643882731109289109042348054235653403907274019786543725939641726001306990000955784463109626790694418336130181302894541703315807731626386395193793704654765220632063686587197822049312426053454111609356979828132452297000798883523759585328579251362964686511497675217123459559238039375625125369855194955325099947038843990336466165470647234999796132343403021857052187836676345789510732982875157945215771652139626324438399018484560935762602";
2803
2804 #[test]
2805 fn consts_test() {
2806 use crate::SQUARE_ROOT_TEN_COMPARATOR;
2807
2808 assert_eq!(1000, SQUARE_ROOT_TEN_COMPARATOR.len());
2809 assert_eq!(PROOF, SQUARE_ROOT_TEN_COMPARATOR);
2810 }
2811
2812 #[test]
2813 fn nought_test() {
2814 let r = Row::nought();
2815 let oom = unsafe { core::mem::transmute::<u8, OomClass>(u8::MAX) };
2816
2817 assert_eq!(Oom::Undefined, ord_of_mag(&r, oom));
2818 }
2819
2820 #[test]
2821 fn readme_sample_test() {
2822 let number_1 = PlacesRow::new_from_u128(3162277660168379331998893544432);
2823 let number_2 = PlacesRow::new_from_u128(3162277660168379331998893544433);
2824
2825 assert_eq!(Oom::Precise(30), ord_of_mag(&number_1, OomClass::Strict));
2826 assert_eq!(Oom::Precise(31), ord_of_mag(&number_2, OomClass::Strict));
2827 assert_eq!(Oom::Precise(30), ord_of_mag(&number_2, OomClass::Loose));
2828 }
2829
2830 mod strict {
2831
2832 use super::PROOF;
2833 use crate::{ord_of_mag, Oom, OomClass::Strict, Row};
2834
2835 #[test]
2836 fn universal_test() {
2837 #[rustfmt::skip]
2838 let values = [
2840 (2,0), (3, 0), (4, 1),
2841 (30, 1), (31, 1), (32, 2),
2842 (315, 2), (316, 2), (317, 3),
2843 (3161, 3), (3162, 3), (3163, 4),
2844 (316_227_765, 8), (316_227_766, 8), (316_227_767, 9),
2845 ];
2846
2847 for v in values {
2848 let r = Row::new_from_usize(v.0);
2849 let o = ord_of_mag(&r, Strict);
2850
2851 assert_eq!(Oom::Precise(v.1), o, "{:?}", v);
2852 }
2853 }
2854
2855 #[test]
2856 fn full_precision_test() {
2857 let r = Row::new_from_str(PROOF).unwrap();
2858 let o = ord_of_mag(&r, Strict);
2859
2860 assert_eq!(Oom::Precise(PROOF.len()), o);
2861 }
2862
2863 #[test]
2864 fn behind_precision_test() {
2865 let mut proof = String::from(PROOF);
2866 proof.push('0');
2867
2868 let r = Row::new_from_str(proof.as_str()).unwrap();
2869 let o = ord_of_mag(&r, Strict);
2870
2871 let proof_len = proof.len();
2872 assert_eq!(1001, proof_len);
2873 assert_eq!(Oom::Approx(proof_len), o);
2874 }
2875 }
2876
2877 mod loose {
2878 use crate::{ord_of_mag, Oom, OomClass::Loose, Row};
2879
2880 #[test]
2881 fn universal_test() {
2882 #[rustfmt::skip]
2883 let values = [
2884 (4, 0) , (5, 1) , (6, 1),
2886 (40, 1) , (50, 2) , (60, 2),
2888 (4000, 3) , (5000, 4) , (6000, 4)
2889 ];
2890
2891 for v in values {
2892 let r = Row::new_from_usize(v.0);
2893 let o = ord_of_mag(&r, Loose);
2894
2895 assert_eq!(Oom::Precise(v.1), o, "{:?}", v);
2896 }
2897 }
2898 }
2899 }
2900
2901 mod rel {
2903 use crate::{rel, Rel, Row};
2904
2905 #[test]
2906 fn basic_test() {
2907 let num = Row::new_from_usize(155);
2908 assert_eq!(Rel::Equal, rel(&num, &num));
2909 }
2910 }
2911
2912 mod rel_raw {
2913
2914 use crate::{rel_raw, Rel};
2915
2916 #[test]
2917 fn longer_test() {
2918 let num = new_from_num_raw!(11);
2919 let comparand = new_from_num_raw!(9);
2920
2921 let proof = Rel::Greater(Some((2, 1, 1)));
2922 assert_eq!(proof, rel_raw(&num, &comparand));
2923 }
2924
2925 #[test]
2926 fn shorter_test() {
2927 let num = new_from_num_raw!(9);
2928 let comparand = new_from_num_raw!(10);
2929
2930 let proof = Rel::Lesser(Some((1, 2, 1)));
2931 assert_eq!(proof, rel_raw(&num, &comparand));
2932 }
2933
2934 #[test]
2935 fn greater_test() {
2936 let num_num = 1234567899;
2937 let cpd_num = 1234567890;
2938
2939 let num = new_from_num_raw!(num_num);
2940 let comparand = new_from_num_raw!(cpd_num);
2941
2942 assert_eq!(Rel::Greater(None), rel_raw(&num, &comparand));
2943 }
2944
2945 #[test]
2946 fn equal_test() {
2947 let num = new_from_num_raw!(1234567890);
2948 assert_eq!(Rel::Equal, rel_raw(&num, &num));
2949 }
2950
2951 #[test]
2952 fn lesser_test() {
2953 let num_num = 1234567890;
2954 let cpd_num = 1234567899;
2955
2956 let num = new_from_num_raw!(num_num);
2957 let comparand = new_from_num_raw!(cpd_num);
2958
2959 assert_eq!(Rel::Lesser(None), rel_raw(&num, &comparand));
2960 }
2961
2962 #[test]
2963 fn both_nought_test() {
2964 let num = new_from_num_raw!(0);
2965
2966 assert_eq!(Rel::Equal, rel_raw(&num, &num));
2967 }
2968 }
2969
2970 mod rel_dec {
2971 use crate::{rel_dec, RelDec, Row};
2972
2973 #[test]
2974 fn basic_test() {
2975 let num = Row::new_from_usize(9876543210);
2976
2977 assert_eq!(RelDec::Equal(10), rel_dec(&num, &num));
2978 }
2979
2980 #[test]
2981 #[rustfmt::skip]
2982 fn readme_sample_test() {
2983 let number = Row::new_from_str("1489754132134687989463132131").unwrap();
2984 let comparand = Row::new_from_str( "48645698946456531371").unwrap();
2985 let decrel = rel_dec(&number, &comparand);
2986
2987 assert_eq!(RelDec::Greater((28, 20, 8)), decrel);
2988 }
2989 }
2990
2991 mod rel_dec_raw {
2992 use crate::{rel_dec_raw, RelDec};
2993
2994 #[test]
2995 fn equal_test() {
2996 let num = new_from_num_raw!(9876543210u64);
2997
2998 assert_eq!(RelDec::Equal(10), rel_dec_raw(&num, &num));
2999 }
3000
3001 #[test]
3002 fn lesser_test() {
3003 let num = new_from_num_raw!(10);
3004 let comparand = new_from_num_raw!(9876543210u64);
3005
3006 let proof = RelDec::Lesser((2, 10, 8));
3007 assert_eq!(proof, rel_dec_raw(&num, &comparand));
3008 }
3009
3010 #[test]
3011 fn greater_test() {
3012 let num = new_from_num_raw!(9876543210u64);
3013 let comparand = new_from_num_raw!(10);
3014
3015 let proof = RelDec::Greater((10, 2, 8));
3016 assert_eq!(proof, rel_dec_raw(&num, &comparand));
3017 }
3018
3019 #[test]
3020 fn nought_test() {
3021 let num = new_from_num_raw!(0);
3022
3023 assert_eq!(RelDec::Equal(0), rel_dec_raw(&num, &num));
3024 }
3025 }
3026
3027 mod dec_pla_cnt_raw {
3028
3029 use crate::dec_pla_cnt_raw;
3030
3031 #[test]
3032 fn nought_test() {
3033 let nought = vec![0; 1];
3034 assert_eq!(0, dec_pla_cnt_raw(&nought));
3035 }
3036
3037 #[test]
3038 fn basic_test() {
3039 for test in [vec![1; 1], vec![1; 100]] {
3040 assert_eq!(test.len(), dec_pla_cnt_raw(&test));
3041 }
3042 }
3043
3044 #[test]
3045 fn zero_len_pseudo_test() {
3048 let zero_len = vec![9; 0];
3049 assert_eq!(0, dec_pla_cnt_raw(&zero_len));
3050 }
3051 }
3052
3053 mod add {
3055 use crate::{add, Row};
3056
3057 #[test]
3058 fn basic_test() {
3059 let row1 = Row::new_from_usize(4);
3060 let row2 = Row::new_from_usize(5);
3061
3062 let sum = add(&row1, &row2);
3063 assert_eq!(&[9], &*sum.row);
3064 }
3065
3066 #[test]
3067 fn left_num_longer_test() {
3068 let row1 = Row::new_from_usize(10_000);
3069 let row2 = Row::new_from_usize(5);
3070
3071 let sum = add(&row1, &row2);
3072 assert_eq!(Row::new_from_usize(10_005), sum);
3073 }
3074
3075 #[test]
3076 fn right_num_longer_test2() {
3077 let row1 = Row::new_from_usize(5);
3078 let row2 = Row::new_from_usize(10_000);
3079
3080 let sum = add(&row1, &row2);
3081 assert_eq!(Row::new_from_usize(10_005), sum);
3082 }
3083
3084 #[test]
3085 fn advanced_test() {
3086 let row = Row::new_from_str("680564733841876926926749214863536422910").unwrap();
3087
3088 let sum = add(&row, &row);
3089 assert_eq!("1361129467683753853853498429727072845820", sum.to_number());
3090 }
3091
3092 #[test]
3093 fn addend1_nought_test() {
3094 let addend1 = Row::nought();
3095 let addend2 = Row::new_from_usize(4321);
3096 let sum = add(&addend1, &addend2);
3097 assert_eq!(addend2, sum);
3098 }
3099
3100 #[test]
3101 fn addend2_nought_test() {
3102 let addend1 = Row::new_from_usize(4321);
3103 let addend2 = Row::nought();
3104 let sum = add(&addend1, &addend2);
3105 assert_eq!(addend1, sum);
3106 }
3107
3108 #[test]
3109 fn both_addends_nought_test() {
3110 let addend1 = Row::nought();
3111 let addend2 = Row::nought();
3112 let sum = add(&addend1, &addend2);
3113 assert_eq!(Row::nought(), sum);
3114 }
3115 }
3116
3117 mod sub {
3119 use crate::{sub, Row};
3120
3121 #[test]
3122 fn universal_test() {
3123 for triplet in [(99, 11, 88), (133, 133, 0), (90, 19, 71), (700, 699, 1)] {
3124 let minuend = new_from_num!(triplet.0);
3125 let subtrahend = new_from_num!(triplet.1);
3126
3127 let proof = new_from_num!(triplet.2);
3128 let diff = sub(&minuend, &subtrahend);
3129 assert!(diff.is_some());
3130
3131 assert_eq!(proof, diff.unwrap());
3132 }
3133 }
3134
3135 #[test]
3136 fn nought_subtrahend_test() {
3137 let minuend = new_from_num!(40);
3138 let subtrahend = Row::nought();
3139
3140 let proof = minuend.clone();
3141 let test = sub(&minuend, &subtrahend);
3142 assert_eq!(Some(proof), test);
3143 }
3144
3145 #[test]
3146 fn lesser_minuend_test() {
3147 let minuend = new_from_num!(4);
3148 let subtrahend = new_from_num!(5);
3149
3150 assert!(sub(&minuend, &subtrahend).is_none());
3151 }
3152
3153 #[test]
3154 fn equal_operands_test() {
3155 let minuend = new_from_num!(1364);
3156 let subtrahend = minuend.clone();
3157
3158 let proof = Row::nought();
3159 let test = sub(&minuend, &subtrahend);
3160 assert_eq!(Some(proof), test);
3161 }
3162
3163 #[test]
3164 fn greater_minuend_test() {
3165 let minuend = new_from_num!(2);
3166 let subtrahend = new_from_num!(1);
3167
3168 let res = sub(&minuend, &subtrahend);
3169 assert_eq!(Some(new_from_num!(1)), res);
3170 }
3171
3172 #[test]
3173 fn boht_nought_test() {
3174 let minuend = Row::nought();
3175 let subtrahend = Row::nought();
3176
3177 let proof = Row::nought();
3178 let test = sub(&minuend, &subtrahend);
3179 assert_eq!(Some(proof), test);
3180 }
3181
3182 #[test]
3183 fn shrinking_test() {
3184 let minuend = new_from_num!(1234567890_1234567890usize);
3185 let subtrahend = new_from_num!(1234567890_1234567889usize);
3186
3187 let proof = Row::unity();
3188 let test = sub(&minuend, &subtrahend);
3189 assert_eq!(Some(proof), test);
3190 assert_eq!(true, test.unwrap().row.capacity() < minuend.row.len());
3191 }
3192 }
3193
3194 mod mul {
3196 use crate::{mul, Row, MUL_DYNAMO_CAP};
3197
3198 #[test]
3199 fn basic_test() {
3200 let row1 = Row::new_from_usize(2);
3201 let row2 = Row::new_from_usize(3);
3202 let prod = mul(&row1, &row2);
3203
3204 assert_eq!(true, prod.row.capacity() < MUL_DYNAMO_CAP);
3205
3206 assert_eq!(&[6], &*prod);
3207 }
3208
3209 #[test]
3210 fn row1_nought_test() {
3211 let row1 = Row::nought();
3212 let row2 = Row::new_from_usize(123456789_10111213);
3213 let prod = mul(&row1, &row2);
3214 let row = &prod.row;
3215 assert_eq!(&[0], row.as_slice());
3216 assert!(row.capacity() < row2.len());
3217 }
3218
3219 #[test]
3220 fn row2_nought_test() {
3221 let row1 = Row::new_from_usize(123456789_10111213);
3222 let row2 = Row::nought();
3223 let prod = mul(&row1, &row2);
3224 let row = &prod.row;
3225 assert_eq!(&[0], row.as_slice());
3226 assert!(row.capacity() < row1.len());
3227 }
3228
3229 #[test]
3230 fn both_nought_test() {
3231 let row1 = Row::nought();
3232 let row2 = Row::nought();
3233 let prod = mul(&row1, &row2);
3234 assert_eq!(&[0], &*prod);
3235 }
3236
3237 #[test]
3238 fn advanced_test() {
3239 let row = Row::new_from_u128(u128::MAX);
3240 let prod = mul(&row, &row);
3241 let proof =
3242 "115792089237316195423570985008687907852589419931798687112530834793049593217025";
3243 assert_eq!(proof, prod.to_number());
3244 }
3245
3246 #[test]
3247 fn decadic_test() {
3248 let row1 = Row::new_from_u128(100);
3249 let row2 = Row::new_from_u128(10_000);
3250
3251 let proof = new_from_num!(1_000_000);
3252 let prod = mul(&row1, &row2);
3253
3254 assert_eq!(proof, prod);
3255 }
3256
3257 #[test]
3258 fn decadic_test2() {
3259 let row1 = Row::new_from_u128(100_000);
3260 let row2 = Row::new_from_u128(100_000);
3261
3262 let proof = new_from_num!(10_000_000_000usize);
3263 let prod = mul(&row1, &row2);
3264
3265 assert_eq!(proof, prod);
3266 }
3267 }
3268
3269 mod mul_raw {
3270
3271 use crate::{mul_raw, MUL_DYNAMO_CAP};
3272 #[test]
3273 fn shrinking_test() {
3274 let prod = mul_raw(&vec![2], &vec![3], false);
3275 assert_eq!(true, prod.capacity() == MUL_DYNAMO_CAP);
3276
3277 let prod = mul_raw(&vec![2], &vec![3], true);
3278 assert_eq!(true, prod.capacity() < MUL_DYNAMO_CAP);
3279 }
3280 }
3281
3282 mod mul_shortcut {
3283 use crate::{mul_shortcut, nought_raw, unity_raw};
3284
3285 #[test]
3286 fn factor1_nought_test() {
3287 let row1 = nought_raw();
3288 let row2 = new_from_num_raw!(333_990);
3289
3290 let res = mul_shortcut(&row1, &row2);
3291 assert_eq!(Some(row1), res);
3292 }
3293
3294 #[test]
3295 fn factor2_nought_test() {
3296 let row1 = new_from_num_raw!(333_990);
3297 let row2 = nought_raw();
3298
3299 let res = mul_shortcut(&row1, &row2);
3300 assert_eq!(Some(row2), res);
3301 }
3302
3303 #[test]
3304 fn factor1_unity_test() {
3305 let row1 = unity_raw();
3306 let row2 = new_from_num_raw!(333_990);
3307
3308 let res = mul_shortcut(&row1, &row2);
3309 assert_eq!(Some(row2), res);
3310 }
3311
3312 #[test]
3313 fn factor2_unity_test() {
3314 let row1 = new_from_num_raw!(333_990);
3315 let row2 = unity_raw();
3316
3317 let res = mul_shortcut(&row1, &row2);
3318 assert_eq!(Some(row1), res);
3319 }
3320
3321 #[test]
3322 fn neither_unity_nor_nought_test() {
3323 let row = new_from_num_raw!(2);
3324
3325 let res = mul_shortcut(&row, &row);
3326 assert_eq!(None, res);
3327 }
3328 }
3329
3330 mod pow {
3337 use crate::{pow, Row, POWER_CAP};
3338
3339 #[test]
3340 fn basic_test() {
3341 let row = Row::new_from_usize(2);
3342 assert_eq!(&[4], &*pow(&row, 2));
3343
3344 assert_eq!(true, row.row.capacity() < POWER_CAP);
3345 }
3346
3347 #[test]
3348 fn advanced_test2() {
3349 let proof = Row::new_from_str("88817841970012523233890533447265625").unwrap();
3350 let row = Row::new_from_usize(25);
3351 assert_eq!(proof, pow(&row, 25));
3352 }
3353
3354 #[test]
3355 fn advanced_test3() {
3356 let proof = Row::new_from_str(
3357 "949279437109690919948053832937215463733689853138782229364504479870922851876864",
3358 )
3359 .unwrap();
3360
3361 let row = Row::new_from_usize(998);
3362 assert_eq!(proof, pow(&row, 26));
3363 }
3364
3365 #[test]
3366 fn advanced_test4() {
3367 let proof = Row::new_from_str(
3368 "926336713898529563388567880069503262826159877325124512315660672063305037119488",
3369 )
3370 .unwrap();
3371
3372 let row = Row::new_from_usize(2);
3373 assert_eq!(proof, pow(&row, 259));
3374 }
3375
3376 #[test]
3377 fn advanced_test5() {
3379 let row = Row::new_from_u128(u128::MAX);
3380 let pow = pow(&row, 500);
3381 let number = pow.to_number();
3382
3383 assert!(number.starts_with("8312324609993336522"));
3384 assert_eq!(19266, number.len());
3385 }
3386
3387 #[test]
3388 fn decadic_test() {
3389 let row = Row::new_from_u128(100);
3390 let pow = pow(&row, 4);
3391 let proof = new_from_num!(1_00_00_00_00);
3392
3393 assert_eq!(proof, pow);
3394 }
3395
3396 #[test]
3397 fn decadic_test2() {
3398 let row = Row::new_from_u128(100);
3399 let pow = pow(&row, 10);
3400 let proof = "1_00_00_00_00_00_00_00_00_00_00";
3401 let proof = Row::new_from_str(proof.replace("_", "").as_str()).unwrap();
3402
3403 assert_eq!(proof, pow);
3404 }
3405
3406 #[test]
3407 fn zero_power_test() {
3408 let row = Row::new_from_usize(0);
3409 let pow = pow(&row, 0);
3410 assert_eq!(&[1], &*pow);
3411 }
3412
3413 #[test]
3414 fn one_power_test() {
3415 let row = Row::new_from_usize(3030);
3416 let pow = pow(&row, 1);
3417 assert_eq!(&[0, 3, 0, 3], &*pow);
3418 }
3419
3420 #[test]
3421 fn power_of_nought_test() {
3422 let row = Row::new_from_usize(0);
3423 let pow = pow(&row, 1000);
3424 assert_eq!(&[0], &*pow);
3425 }
3426
3427 #[test]
3428 fn power_of_one_test() {
3429 let row = Row::new_from_usize(1);
3430 let pow = pow(&row, u16::MAX);
3431 assert_eq!(&[1], &*pow);
3432 }
3433 }
3434
3435 mod pow_raw {
3436
3437 use crate::{pow_raw, POWER_CAP};
3438 #[test]
3439 fn shrinking_test() {
3440 let prod = pow_raw(&vec![2], 3, false);
3441 assert_eq!(true, prod.capacity() == POWER_CAP);
3442
3443 let prod = pow_raw(&vec![2], 3, true);
3444 assert_eq!(true, prod.capacity() < POWER_CAP);
3445 }
3446 }
3447
3448 mod pow_shortcut {
3449 use super::nought;
3450 use crate::{nought_raw, pow_shortcut, unity_raw};
3451
3452 #[test]
3453 fn zero_power_test() {
3454 let row = nought();
3455 let pow = pow_shortcut(&row, 0);
3456 assert_eq!(Some(unity_raw()), pow);
3457 }
3458
3459 #[test]
3460 fn power_of_nought_test() {
3461 let row = nought_raw();
3462 let pow = pow_shortcut(&row, 1000);
3463 assert_eq!(Some(row), pow);
3464 }
3465
3466 #[test]
3467 fn one_power_test() {
3468 let row = new_from_num_raw!(3030);
3469 let pow = pow_shortcut(&row, 1);
3470 assert_eq!(Some(row), pow);
3471 }
3472
3473 #[test]
3474 fn power_of_one_test() {
3475 let row = unity_raw();
3476 let pow = pow_shortcut(&row, u16::MAX);
3477 assert_eq!(Some(row), pow);
3478 }
3479 }
3480
3481 mod divrem {
3483 use crate::{divrem, Row};
3484
3485 #[test]
3486 fn nought_divisor_test() {
3487 let dividend = Row::new_from_usize(1);
3488 let divisor = Row::new_from_usize(0);
3489
3490 let ratrem = divrem(÷nd, &divisor);
3491 assert!(ratrem.is_none());
3492 }
3493
3494 #[test]
3495 fn shorter_dividend_test() {
3496 let dividend = Row::new_from_usize(99);
3497 let divisor = Row::new_from_usize(999);
3498
3499 let ratrem = divrem(÷nd, &divisor);
3500 assert!(ratrem.is_some());
3501
3502 let ratrem = ratrem.unwrap();
3503
3504 assert_eq!(Row::nought(), ratrem.0);
3505 assert_eq!(dividend, ratrem.1);
3506 }
3507
3508 #[test]
3509 fn universal_test() {
3510 for quadruplet in [
3511 (0, 100, 0, 0),
3512 (99, 11, 9, 0),
3513 (133, 133, 1, 0),
3514 (90, 19, 4, 14),
3515 (700, 699, 1, 1),
3516 (700, 70, 10, 0),
3517 ] {
3518 let dividend = Row::new_from_usize(quadruplet.0);
3519 let divisor = Row::new_from_usize(quadruplet.1);
3520
3521 let ratio = Row::new_from_usize(quadruplet.2);
3522 let remainder = Row::new_from_usize(quadruplet.3);
3523 let ratrem = divrem(÷nd, &divisor);
3524
3525 assert!(ratrem.is_some());
3526 let ratrem = ratrem.unwrap();
3527
3528 assert_eq!(ratio, ratrem.0);
3529 assert_eq!(remainder, ratrem.1);
3530 }
3531 }
3532
3533 #[test]
3535 fn load_test() {
3536 let dividend =
3537 Row::new_from_str("99999340282366920938463463374607431768211455").unwrap();
3538 let divisor = Row::new_from_usize(249);
3539
3540 let ratio = Row::new_from_str("401603776234405304973748848894005750073138").unwrap();
3541 let remainder = Row::new_from_usize(93);
3542
3543 let ratrem = divrem(÷nd, &divisor).unwrap();
3544 assert_eq!(ratio, ratrem.0);
3545 assert_eq!(remainder, ratrem.1);
3546 }
3547
3548 #[test]
3549 fn readme_sample_test() {
3550 let dividend =
3551 Row::new_from_str("3402823669209384634633746074317682114565556668744123").unwrap();
3552 let divisor =
3553 Row::new_from_str("14034568236692093846346337460345176821145655563453").unwrap();
3554 let ratio = "242";
3555 let remainder = "6458155929897923817932408914149323848308022388497";
3556
3557 let ratrem = divrem(÷nd, &divisor).unwrap();
3558
3559 assert_eq!(ratio, ratrem.0.to_number());
3560 assert_eq!(remainder, ratrem.1.to_number());
3561 }
3562
3563 #[test]
3564 fn shrinking_test() {
3565 let dividend =
3566 Row::new_from_str("1000000000000000000000000000000000000000000000").unwrap();
3567 let divisor = Row::unity();
3568
3569 let ratrem = divrem(÷nd, &divisor).unwrap();
3570
3571 assert_eq!(dividend, ratrem.0);
3572
3573 let rem = ratrem.1;
3574 assert_eq!(Row::nought(), rem);
3575
3576 assert_eq!(true, rem.row.capacity() < dividend.len());
3577 }
3578 }
3579
3580 mod divrem_shortcut {
3581 use crate::{divrem_shortcut, nought_raw, unity_raw, Row};
3582
3583 #[test]
3584 fn nought_divisor_test() {
3585 let dividend = nought_raw();
3586 let divisor = nought_raw();
3587
3588 let ratrem = divrem_shortcut(÷nd, &divisor);
3589 assert_eq!(Some(None), ratrem);
3590 }
3591
3592 #[test]
3593 fn nought_dividend_test() {
3594 let dividend = nought_raw();
3595 let divisor = new_from_num_raw!(4);
3596
3597 let proof = (Row::nought(), Row::nought());
3598 let ratrem = divrem_shortcut(÷nd, &divisor);
3599 assert_eq!(Some(Some(proof)), ratrem);
3600 }
3601
3602 #[test]
3603 fn unity_divisor_test() {
3604 let dividend = nought_raw();
3605 let divisor = unity_raw();
3606
3607 let proof = (Row::nought(), Row::nought());
3608 let ratrem = divrem_shortcut(÷nd, &divisor);
3609 assert_eq!(Some(Some(proof)), ratrem);
3610 }
3611
3612 #[test]
3613 fn unity_divisor_test2() {
3614 let dividend = new_from_num!(334_556);
3615 let divisor = unity_raw();
3616
3617 let proof = (dividend.clone(), Row::nought());
3618 let ratrem = divrem_shortcut(÷nd.row, &divisor);
3619 assert_eq!(Some(Some(proof)), ratrem);
3620 }
3621
3622 #[test]
3623 fn lesser_dividend_test() {
3624 let dividend = new_from_num!(0);
3625 let divisor = new_from_num_raw!(1);
3626
3627 let proof = (Row::nought(), dividend.clone());
3628 let ratrem = divrem_shortcut(÷nd.row, &divisor);
3629 assert_eq!(Some(Some(proof)), ratrem);
3630 }
3631 }
3632
3633 pub mod division {
3634 use crate::{division, new_from_str_raw, nought_raw, unity_raw};
3635 use DivRemGrade::*;
3636
3637 #[derive(Debug, PartialEq)]
3638 pub enum DivRemGrade {
3639 DLBPI,
3641 DLBP,
3643 DLBV,
3645 DFVD,
3647 DPVD,
3649 NDVD,
3651 DEXH,
3653 RVD,
3655 DEVD,
3657 }
3658
3659 #[test]
3660 fn basic_test() {
3661 let dividend = new_from_num_raw!(65006);
3662 let divisor = vec![5];
3663
3664 let proof_ra = new_from_num_raw!(13001);
3665 let (rem, ratio) = division(÷nd, &divisor, &mut vec![]);
3666
3667 assert_eq!(vec![1], rem);
3668 assert_eq!(proof_ra, ratio);
3669 }
3670
3671 #[test]
3672 fn zero_division_test_1() {
3673 let dividend = nought_raw();
3674 let divisor = unity_raw();
3675
3676 let mut codes = vec![];
3677 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
3678
3679 assert_eq!(vec![0], rem);
3680 assert_eq!(vec![0], ratio);
3681
3682 assert_eq!(vec![DEXH], codes);
3683 }
3684
3685 #[test]
3686 fn zero_division_test_2() {
3687 let dividend = nought_raw();
3688 let divisor = new_from_num_raw!(usize::MAX);
3689
3690 let mut codes = vec![];
3691 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
3692
3693 assert_eq!(vec![0], rem);
3694 assert_eq!(vec![0], ratio);
3695
3696 assert_eq!(vec![DLBPI], codes);
3697 }
3698
3699 #[test]
3700 fn one_division_test1() {
3701 let dividend = unity_raw();
3702 let divisor = unity_raw();
3703
3704 let mut codes = vec![];
3705 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
3706
3707 assert_eq!(vec![0], rem);
3708 assert_eq!(vec![1], ratio);
3709
3710 assert_eq!(vec![DEXH], codes);
3711 }
3712
3713 #[test]
3714 fn one_division_test2() {
3715 let dividend = unity_raw();
3716 let divisor = new_from_num_raw!(usize::MAX);
3717
3718 let mut codes = vec![];
3719 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
3720
3721 assert_eq!(vec![1], rem);
3722 assert_eq!(vec![0], ratio);
3723
3724 assert_eq!(vec![DLBPI], codes);
3725 }
3726
3727 #[test]
3728 fn dividend_lesser_by_place_test() {
3729 let dividend = new_from_num_raw!(100);
3730 let divisor = new_from_num_raw!(1000);
3731
3732 let mut codes = vec![];
3733 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
3734
3735 assert_eq!(dividend, rem);
3736 assert_eq!(vec![0], ratio);
3737
3738 assert_eq!(vec![DLBPI], codes);
3739 }
3740
3741 #[test]
3742 fn dividend_lesser_by_value_test_1() {
3743 let dividend = new_from_num_raw!(1);
3744 let divisor = new_from_num_raw!(2);
3745
3746 let mut codes = vec![];
3747 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
3748
3749 assert_eq!(vec![1], rem);
3750 assert_eq!(vec![0], ratio);
3751 assert_eq!(vec![DLBV], codes);
3752 }
3753
3754 #[test]
3755 fn dividend_lesser_by_value_test_2() {
3756 let dividend = new_from_num_raw!(0);
3757 let divisor = new_from_num_raw!(1);
3758
3759 let mut codes = vec![];
3760 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
3761
3762 assert_eq!(vec![0], rem);
3763 assert_eq!(vec![0], ratio);
3764 assert_eq!(vec![DEXH], codes);
3765 }
3766
3767 #[test]
3768 fn dividend_lesser_by_value_test_3() {
3769 let dividend = new_from_num_raw!(6_010_990);
3770 let divisor = new_from_num_raw!(600);
3771
3772 let mut codes = vec![];
3773 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
3774
3775 assert_eq!(vec![0, 9, 1], rem);
3776 assert_eq!(vec![8, 1, 0, 0, 1], ratio);
3777
3778 assert_eq!(vec![DEVD, DLBV], codes);
3779 }
3780
3781 #[test]
3782 fn dividend_full_virtual_division_test_1() {
3783 let dividend = new_from_num_raw!(65000);
3784 let divisor = new_from_num_raw!(65);
3785
3786 let mut codes = vec![];
3787 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
3788
3789 assert_eq!(vec![0], rem);
3790 assert_eq!(vec![0, 0, 0, 1], ratio);
3791
3792 assert_eq!(vec![DFVD, DEXH], codes);
3793 }
3794
3795 #[test]
3796 fn dividend_full_virtual_division_test_2() {
3797 let dividend = new_from_num_raw!(65_650);
3798 let divisor = new_from_num_raw!(65);
3799
3800 let mut codes = vec![];
3801 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
3802
3803 assert_eq!(vec![0], rem);
3804 assert_eq!(vec![0, 1, 0, 1], ratio);
3805
3806 assert_eq!(vec![NDVD, DEVD, DFVD, DEXH], codes);
3807 }
3808
3809 #[test]
3810 fn dividend_full_virtual_division_test_3() {
3811 let dividend = new_from_num_raw!(6_500_650);
3812 let divisor = new_from_num_raw!(65);
3813
3814 let mut codes = vec![];
3815 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
3816
3817 assert_eq!(vec![0], rem);
3818 assert_eq!(vec![0, 1, 0, 0, 0, 1], ratio);
3819
3820 assert_eq!(vec![DPVD, DEVD, DFVD, DEXH], codes);
3821 }
3822
3823 #[test]
3824 fn dividend_full_virtual_division_test_4() {
3825 let dividend = new_from_num_raw!(600_000_000);
3826 let divisor = new_from_num_raw!(600);
3827
3828 let mut codes = vec![];
3829 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
3830
3831 assert_eq!(vec![0], rem);
3832 assert_eq!(vec![0, 0, 0, 0, 0, 0, 1], ratio);
3833
3834 assert_eq!(vec![DFVD, DEXH], codes);
3835 }
3836
3837 #[test]
3838 fn dividend_partial_virtual_division_test_1() {
3839 let dividend = new_from_num_raw!(65066);
3840 let divisor = new_from_num_raw!(65);
3841
3842 let mut codes = vec![];
3843 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
3844
3845 assert_eq!(vec![1], rem);
3846 assert_eq!(vec![1, 0, 0, 1], ratio);
3847
3848 assert_eq!(vec![DPVD, DEVD, DLBP], codes);
3849 }
3850
3851 #[test]
3852 fn dividend_partial_virtual_division_test_2() {
3853 let dividend = new_from_num_raw!(65_650_075);
3854 let divisor = new_from_num_raw!(65);
3855
3856 let mut codes = vec![];
3857 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
3858
3859 assert_eq!(vec![0, 1], rem);
3860 assert_eq!(vec![1, 0, 0, 0, 1, 0, 1], ratio);
3861
3862 assert_eq!(vec![NDVD, DEVD, DPVD, DEVD, DLBV], codes);
3863 }
3864
3865 #[test]
3866 fn dividend_exhaustion_test_1() {
3867 let dividend = new_from_num_raw!(65065);
3868 let divisor = dividend.clone();
3869
3870 let mut codes = vec![];
3871 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
3872
3873 assert_eq!(vec![0], rem);
3874 assert_eq!(vec![1], ratio);
3875
3876 assert_eq!(vec![DEXH], codes);
3877 }
3878
3879 #[test]
3880 fn dividend_exhaustion_test_2() {
3881 let dividend = new_from_num_raw!(65065);
3882 let divisor = new_from_num_raw!(65);
3883
3884 let mut codes = vec![];
3885 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
3886
3887 assert_eq!(vec![0], rem);
3888 assert_eq!(vec![1, 0, 0, 1], ratio);
3889
3890 assert_eq!(vec![DPVD, DEVD, DEXH], codes);
3891 }
3892
3893 #[test]
3894 fn non_zero_remainder_test_a_1() {
3895 let dividend = new_from_num_raw!(60_055);
3896 let divisor = new_from_num_raw!(600);
3897
3898 let mut codes = vec![];
3899 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
3900
3901 assert_eq!(vec![5, 5], rem);
3902 assert_eq!(vec![0, 0, 1], ratio);
3903 assert_eq!(vec![NDVD, RVD, DLBP], codes);
3904 }
3905
3906 #[test]
3907 fn non_zero_remainder_test_a_2() {
3908 let dividend = new_from_num_raw!(600_600_055);
3909 let divisor = new_from_num_raw!(600);
3910
3911 let mut codes = vec![];
3912 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
3913
3914 assert_eq!(vec![5, 5], rem);
3915 assert_eq!(vec![0, 0, 0, 1, 0, 0, 1], ratio);
3916 assert_eq!(vec![NDVD, DEVD, DPVD, RVD, DLBP], codes);
3917 }
3918
3919 #[test]
3920 fn non_zero_remainder_test_b_1() {
3921 let dividend = new_from_num_raw!(655);
3922 let divisor = new_from_num_raw!(600);
3923
3924 let mut codes = vec![];
3925 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
3926
3927 assert_eq!(vec![5, 5], rem);
3928 assert_eq!(vec![1], ratio);
3929 assert_eq!(vec![DLBP], codes);
3930 }
3931
3932 #[test]
3933 fn non_zero_remainder_test_b_2() {
3934 let dividend = new_from_num_raw!(600_655);
3935 let divisor = new_from_num_raw!(600);
3936
3937 let mut codes = vec![];
3938 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
3939
3940 assert_eq!(vec![5, 5], rem);
3941 assert_eq!(vec![1, 0, 0, 1], ratio);
3942 assert_eq!(vec![NDVD, DEVD, DLBP], codes);
3943 }
3944
3945 #[test]
3946 fn non_zero_remainder_test_c_1() {
3947 let dividend = new_from_num_raw!(599);
3948 let divisor = new_from_num_raw!(300);
3949
3950 let mut codes = vec![];
3951 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
3952
3953 assert_eq!(vec![9, 9, 2], rem);
3954 assert_eq!(vec![1], ratio);
3955
3956 assert_eq!(vec![DLBV], codes);
3957 }
3958
3959 #[test]
3960 fn non_zero_remainder_test_c_2() {
3961 let dividend = new_from_num_raw!(600_599);
3962 let divisor = new_from_num_raw!(300);
3963
3964 let mut codes = vec![];
3965 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
3966
3967 assert_eq!(vec![9, 9, 2], rem);
3968 assert_eq!(vec![1, 0, 0, 2], ratio);
3969
3970 assert_eq!(vec![NDVD, DEVD, DLBV], codes);
3971 }
3972
3973 #[test]
3974 fn zero_remainder_test_1() {
3975 let dividend = new_from_num_raw!(usize::MAX);
3976 let divisor = new_from_num_raw!(usize::MAX);
3977
3978 let mut codes = vec![];
3979 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
3980
3981 assert_eq!(vec![0], rem);
3982 assert_eq!(vec![1], ratio);
3983
3984 assert_eq!(vec![DEXH], codes);
3985 }
3986
3987 #[test]
3988 fn zero_remainder_test_2() {
3989 let dividend = new_from_num_raw!(2);
3990 let divisor = new_from_num_raw!(2);
3991
3992 let mut codes = vec![];
3993 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
3994
3995 assert_eq!(vec![0], rem);
3996 assert_eq!(vec![1], ratio);
3997
3998 assert_eq!(vec![DEXH], codes);
3999 }
4000
4001 #[test]
4002 fn dividend_portion_computation_a_1() {
4003 let dividend = new_from_num_raw!(600);
4004 let divisor = new_from_num_raw!(600);
4005
4006 let mut codes = vec![];
4007 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
4008
4009 assert_eq!(vec![0], rem);
4010 assert_eq!(vec![1], ratio);
4011
4012 assert_eq!(vec![DEXH], codes);
4013 }
4014
4015 #[test]
4016 fn dividend_portion_computation_a_2() {
4017 let dividend = new_from_num_raw!(600);
4018 let divisor = new_from_num_raw!(599);
4019
4020 let mut codes = vec![];
4021 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
4022
4023 assert_eq!(vec![1], rem);
4024 assert_eq!(vec![1], ratio);
4025
4026 assert_eq!(vec![DLBP], codes);
4027 }
4028
4029 #[test]
4030 fn dividend_portion_computation_a_3() {
4031 let dividend = new_from_num_raw!(5990);
4032 let divisor = new_from_num_raw!(600);
4033
4034 let mut codes = vec![];
4035 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
4036
4037 assert_eq!(vec![0, 9, 5], rem);
4038 assert_eq!(vec![9], ratio);
4039
4040 assert_eq!(vec![DLBV], codes);
4041 }
4042
4043 #[test]
4044 fn dividend_portion_computation_b_1() {
4045 let dividend = new_from_num_raw!(600_600);
4046 let divisor = new_from_num_raw!(600);
4047
4048 let mut codes = vec![];
4049 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
4050
4051 assert_eq!(vec![0], rem);
4052 assert_eq!(vec![1, 0, 0, 1], ratio);
4053
4054 assert_eq!(vec![NDVD, DEVD, DEXH], codes);
4055 }
4056
4057 #[test]
4058 fn dividend_portion_computation_b_2() {
4059 let dividend = new_from_num_raw!(600_599);
4060 let divisor = new_from_num_raw!(600);
4061
4062 let mut codes = vec![];
4063 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
4064
4065 assert_eq!(vec![9, 9, 5], rem);
4066 assert_eq!(vec![0, 0, 0, 1], ratio);
4067
4068 assert_eq!(vec![NDVD, DEVD, DLBV], codes);
4069 }
4070
4071 #[test]
4072 fn dividend_portion_computation_b_3() {
4073 let dividend = new_from_num_raw!(6_005_990);
4074 let divisor = new_from_num_raw!(600);
4075
4076 let mut codes = vec![];
4077 let (rem, ratio) = division(÷nd, &divisor, &mut codes);
4078
4079 assert_eq!(vec![0, 9, 5], rem);
4080 assert_eq!(vec![9, 0, 0, 0, 1], ratio);
4081
4082 assert_eq!(vec![NDVD, DEVD, DLBV], codes);
4083 }
4084
4085 #[test]
4086 fn load_test_1() {
4087 let dividend = new_from_num_raw!(u128::MAX);
4088 let divisor = new_from_num_raw!(249);
4089
4090 let proof_ra = new_from_num_raw!(1366595851088106278969375933460916511u128);
4091 let (rem, ratio) = division(÷nd, &divisor, &mut vec![]);
4092
4093 assert_eq!(vec![6, 1, 2], rem);
4094 assert_eq!(proof_ra, ratio);
4095 }
4096
4097 #[test]
4098 fn load_test_2() {
4099 let dividend = new_from_num_raw!(u128::MAX);
4100 let divisor = new_from_num_raw!(2);
4101
4102 let proof_ra = new_from_num_raw!(170141183460469231731687303715884105727u128);
4103 let (rem, ratio) = division(÷nd, &divisor, &mut vec![]);
4104
4105 assert_eq!(vec![1], rem);
4106 assert_eq!(proof_ra, ratio);
4107 }
4108
4109 #[test]
4110 fn load_test_3() {
4111 let dividend = new_from_num_raw!(u128::MAX);
4112 let divisor = new_from_num_raw!(u128::MAX / 2);
4113
4114 let proof_ra = new_from_num_raw!(2);
4115 let (rem, ratio) = division(÷nd, &divisor, &mut vec![]);
4116
4117 assert_eq!(vec![1], rem);
4118 assert_eq!(proof_ra, ratio);
4119 }
4120
4121 #[test]
4122 fn load_test_4() {
4123 let dividend = new_from_str_raw(
4124 "340282366920938463463374607431768211455340282366920938463463374607431768211455",
4125 )
4126 .unwrap();
4127 let divisor = new_from_num_raw!(13);
4128
4129 let proof_ra = new_from_str_raw(
4130 "26175566686226035651028815956289862419641560182070841420266413431340905247035",
4131 )
4132 .unwrap();
4133 let (rem, ratio) = division(÷nd, &divisor, &mut vec![]);
4134
4135 assert_eq!(vec![0], rem);
4136 assert_eq!(proof_ra, ratio);
4137 }
4138
4139 #[test]
4140 fn load_test_5() {
4141 let dividend = new_from_str_raw(
4142 "340282366920938463463374607431768211455340282366920938463463374607431768211455",
4143 )
4144 .unwrap();
4145 let divisor = new_from_num_raw!(14);
4146
4147 let proof_ra = new_from_str_raw(
4148 "24305883351495604533098186245126300818238591597637209890247383900530840586532",
4149 )
4150 .unwrap();
4151 let (rem, ratio) = division(÷nd, &divisor, &mut vec![]);
4152
4153 assert_eq!(vec![7], rem);
4154 assert_eq!(proof_ra, ratio);
4155 }
4156 }
4157
4158 pub mod dividend_start {
4159 use crate::dividend_start;
4160
4161 #[test]
4162 fn basic_test() {
4163 let dividend = new_from_num_raw!(333_333_333);
4164 let divisor = new_from_num_raw!(333);
4165
4166 let portion = dividend_start(÷nd, &divisor);
4167 assert_eq!(6, portion);
4168 }
4169
4170 #[test]
4171 fn place_satisfaction_test_1() {
4172 let dividend = new_from_num_raw!(911_111);
4173
4174 for duo in [(19, 4), (899, 3), (911_10, 1)] {
4175 let divisor = new_from_num_raw!(duo.0);
4176 let portion = dividend_start(÷nd, &divisor);
4177 assert_eq!(duo.1, portion);
4178 }
4179 }
4180
4181 #[test]
4182 fn place_satisfaction_test_2() {
4183 let dividend = new_from_num_raw!(911_111);
4184
4185 for duo in [(9, 5), (911, 3), (911_11, 1), (911_111, 0)] {
4186 let divisor = new_from_num_raw!(duo.0);
4187 let portion = dividend_start(÷nd, &divisor);
4188 assert_eq!(duo.1, portion);
4189 }
4190 }
4191
4192 #[test]
4193 fn place_unsatisfaction_test() {
4194 let dividend = new_from_num_raw!(809_000);
4195
4196 for duo in [(90, 3), (81, 3), (9, 4), (80_901, 0), (809_001, 0)] {
4197 let divisor = new_from_num_raw!(duo.0);
4198 let portion = dividend_start(÷nd, &divisor);
4199 assert_eq!(duo.1, portion, "{:?}", duo);
4200 }
4201 }
4202
4203 #[test]
4204 fn equal_places_indifference_test() {
4205 let dividend = new_from_num_raw!(809_000);
4206
4207 for duo in [(100_000, 0), (809_000, 0), (999_999, 0)] {
4208 let divisor = new_from_num_raw!(duo.0);
4209 let portion = dividend_start(÷nd, &divisor);
4210 assert_eq!(duo.1, portion, "{:?}", duo);
4211 }
4212 }
4213
4214 #[test]
4215 #[should_panic(expected = "Dividend has less places.")]
4216 fn length_precondition_test() {
4217 let dividend = new_from_num_raw!(1);
4218 let divisor = new_from_num_raw!(11);
4219
4220 _ = dividend_start(÷nd, &divisor);
4221 }
4222 }
4223
4224 pub mod prime_ck {
4225 use std::time::Duration;
4226
4227 use crate::{prime_ck, Row};
4228
4229 #[derive(PartialEq, Debug)]
4230 #[allow(non_camel_case_types)]
4231 pub enum PrimeCkEscCode {
4232 Unset,
4233 Pn,
4235 Ar,
4237 Ob,
4239 Dt,
4241 Np,
4243 Hit_3_Start,
4244 Hit_5_Start,
4245 Hit_7_Start,
4246 Hit_11_Start,
4247 Hit_13_Start,
4248 Hit_17_Start,
4249 Hit_19_Start,
4250 Hit_23_Start,
4251 Hit_29_Start,
4252 Hit_31_Start,
4253 Hit_37_Start,
4254 Hit_41_Start,
4255 Hit_43_Start,
4256 Hit_47_Start,
4257 Hit_53_Start,
4258 Hit_59_Start,
4259 Hit_61_Start,
4260 Hit_67_Start,
4261 Hit_71_Start,
4262 Hit_73_Start,
4263 Hit_79_Start,
4264 Hit_83_Start,
4265 Hit_89_Start,
4266 Hit_97_Start,
4267 Hit_101_Start,
4268 Hit_103_Start,
4269 }
4270
4271 pub struct PrimeCkTestGauges {
4272 pub esc: PrimeCkEscCode,
4273 pub check_starts: bool,
4274 pub cntrs: [usize; 26],
4275 pub peekhole: usize,
4276 pub sqrt: usize,
4277 }
4278
4279 impl PrimeCkTestGauges {
4280 fn blank() -> Self {
4281 Self {
4282 esc: PrimeCkEscCode::Unset,
4283 check_starts: false,
4284 cntrs: [0; 26],
4285 peekhole: 0,
4286 sqrt: 0,
4287 }
4288 }
4289 }
4290
4291 #[test]
4292 fn basic_test() {
4293 let row = new_from_num!(4643);
4294 assert_eq!(
4295 Some(true),
4296 prime_ck(&row, None, &mut PrimeCkTestGauges::blank())
4297 );
4298 }
4299
4300 #[test]
4301 fn basic_values_test() {
4302 let vals = [
4303 (0, PrimeCkEscCode::Ob),
4304 (1, PrimeCkEscCode::Ob),
4305 (2, PrimeCkEscCode::Ar),
4306 (3, PrimeCkEscCode::Ar),
4307 (4, PrimeCkEscCode::Ob),
4308 (5, PrimeCkEscCode::Ar),
4309 (6, PrimeCkEscCode::Ob),
4310 (7, PrimeCkEscCode::Ar),
4311 (8, PrimeCkEscCode::Ob),
4312 (9, PrimeCkEscCode::Dt),
4313 (10, PrimeCkEscCode::Ob),
4314 ];
4315
4316 for v in vals {
4317 let mut tg = PrimeCkTestGauges::blank();
4318 let row = new_from_num!(v.0);
4319
4320 let pn = v.1 == PrimeCkEscCode::Ar;
4321 assert_eq!(Some(pn), prime_ck(&row, None, &mut tg), "{}", v.0);
4322 assert_eq!(v.1, tg.esc, "{}", v.0);
4323 }
4324 }
4325
4326 #[test]
4327 fn advaced_values_test() {
4328 let vals = [
4329 (11, PrimeCkEscCode::Pn),
4330 (13, PrimeCkEscCode::Pn),
4331 (15, PrimeCkEscCode::Ob),
4332 (17, PrimeCkEscCode::Pn),
4333 (19, PrimeCkEscCode::Pn),
4334 (21, PrimeCkEscCode::Dt),
4335 (23, PrimeCkEscCode::Pn),
4336 (25, PrimeCkEscCode::Ob),
4337 (27, PrimeCkEscCode::Dt),
4338 (29, PrimeCkEscCode::Pn),
4339 (31, PrimeCkEscCode::Pn),
4340 (33, PrimeCkEscCode::Dt),
4341 (35, PrimeCkEscCode::Ob),
4342 (37, PrimeCkEscCode::Pn),
4343 ];
4344
4345 for v in vals {
4346 let mut tg = PrimeCkTestGauges::blank();
4347 let row = new_from_num!(v.0);
4348
4349 let pn = v.1 == PrimeCkEscCode::Pn;
4350 assert_eq!(Some(pn), prime_ck(&row, None, &mut tg), "{}", v.0);
4351 assert_eq!(v.1, tg.esc, "{}", v.0);
4352 }
4353 }
4354
4355 #[test]
4356 fn division_cache_test() {
4357 let vals = [
4359 (83, PrimeCkEscCode::Hit_3_Start, 9),
4363 (227, PrimeCkEscCode::Hit_5_Start, 15),
4367 (49, PrimeCkEscCode::Hit_7_Start, 7),
4368 (121, PrimeCkEscCode::Hit_11_Start, 11),
4369 (169, PrimeCkEscCode::Hit_13_Start, 13),
4370 (289, PrimeCkEscCode::Hit_17_Start, 17),
4371 (361, PrimeCkEscCode::Hit_19_Start, 19),
4372 (529, PrimeCkEscCode::Hit_23_Start, 23),
4373 (841, PrimeCkEscCode::Hit_29_Start, 29),
4374 (961, PrimeCkEscCode::Hit_31_Start, 31),
4375 (1369, PrimeCkEscCode::Hit_37_Start, 37),
4376 (1681, PrimeCkEscCode::Hit_41_Start, 41),
4377 (1849, PrimeCkEscCode::Hit_43_Start, 43),
4378 (2209, PrimeCkEscCode::Hit_47_Start, 47),
4379 (2809, PrimeCkEscCode::Hit_53_Start, 53),
4380 (3481, PrimeCkEscCode::Hit_59_Start, 59),
4381 (3721, PrimeCkEscCode::Hit_61_Start, 61),
4382 (4489, PrimeCkEscCode::Hit_67_Start, 67),
4383 (5041, PrimeCkEscCode::Hit_71_Start, 71),
4384 (5329, PrimeCkEscCode::Hit_73_Start, 73),
4385 (6241, PrimeCkEscCode::Hit_79_Start, 79),
4386 (6889, PrimeCkEscCode::Hit_83_Start, 83),
4387 (7921, PrimeCkEscCode::Hit_89_Start, 89),
4388 (9409, PrimeCkEscCode::Hit_97_Start, 97),
4389 (10201, PrimeCkEscCode::Hit_101_Start, 101),
4390 (10609, PrimeCkEscCode::Hit_103_Start, 103),
4391 ];
4392
4393 for v in vals {
4394 let mut tg = PrimeCkTestGauges::blank();
4395 tg.check_starts = true;
4396 let row = new_from_num!(v.0);
4397
4398 _ = prime_ck(&row, None, &mut tg);
4399 assert_eq!(v.1, tg.esc, "{}", v.0);
4400 assert_eq!(v.2, tg.sqrt, "{}", v.0);
4401 assert_eq!(v.2, tg.peekhole, "{}", v.0);
4402 }
4403 }
4404
4405 #[test]
4406 fn division_cache_test2() {
4407 let mut tg = PrimeCkTestGauges::blank();
4408
4409 let row = new_from_num!(96_721);
4411
4412 assert_eq!(Some(false), prime_ck(&row, None, &mut tg));
4413
4414 assert_eq!(311, tg.sqrt);
4431
4432 let proof = [
4434 51, 30, 21, 13, 11, 8, 7, 6, 4, 4, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, ];
4461
4462 for (ix, c) in tg.cntrs.iter().enumerate() {
4463 assert_eq!(proof[ix], *c, "ix {ix}");
4464 }
4465 }
4466
4467 #[test]
4468 fn easy_discard_test() {
4469 let vals = [0, 1, 1000, 2222, 3008, 5005, 5025, 7275];
4470
4471 for v in vals {
4472 let row = new_from_num!(v);
4473 let mut tg = PrimeCkTestGauges::blank();
4474 assert_eq!(Some(false), prime_ck(&row, None, &mut tg), "{}", v);
4475 assert_eq!(PrimeCkEscCode::Ob, tg.esc, "{}", v);
4476 }
4477 }
4478
4479 #[test]
4480 fn timeframe_exhaustion_test() {
4481 let prime = Row::new_from_str(
4482 "5210644015679228794060694325390955853335898483908056458352183851018372555735221",
4483 )
4484 .unwrap();
4485 let duration = Duration::from_secs(2);
4486
4487 assert_eq!(
4488 None,
4489 prime_ck(&prime, Some(duration), &mut PrimeCkTestGauges::blank())
4490 );
4491 }
4492
4493 #[test]
4494 fn primes_test() {
4495 let primes = [
4496 "4003",
4497 "7919",
4498 "19373",
4499 "100005583",
4500 "100010717",
4501 "1000037299",
4502 "1000062023",
4503 "100000012561",
4504 "100000002199",
4505 "100000015333",
4506 "2932031007403",
4507 ];
4508
4509 for p in primes {
4510 let mut tg = PrimeCkTestGauges::blank();
4511 let row = Row::new_from_str(p).unwrap();
4512 assert_eq!(
4513 Some(true),
4514 prime_ck(&row, None, &mut tg),
4515 "{}",
4516 row.to_number()
4517 );
4518 assert_eq!(PrimeCkEscCode::Pn, tg.esc, "{}", row.to_number());
4519 }
4520 }
4521
4522 #[test]
4523 #[cfg(feature = "ext-tests2")]
4524 fn primes_ext_test() {
4525 let primes = [
4526 "9999999900000001",
4527 "909090909090909091",
4528 "768614336404564651",
4529 ];
4530
4531 for p in primes {
4532 let mut tg = PrimeCkTestGauges::blank();
4533 let row = Row::new_from_str(p).unwrap();
4534 assert_eq!(
4535 Some(true),
4536 prime_ck(&row, None, &mut tg),
4537 "{}",
4538 row.to_number()
4539 );
4540 assert_eq!(PrimeCkEscCode::Pn, tg.esc, "{}", row.to_number());
4541 }
4542 }
4543
4544 #[test]
4546 #[cfg(feature = "ext-tests3")]
4547 fn primes_ext2_test() {
4548 let primes = [
4549 "5210644015679228794060694325390955853335898483908056458352183851018372555735221",
4550 "6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151",
4551 "531137992816767098689588206552468627329593117727031923199444138200403559860852242739162502265229285668889329486246501015346579337652707239409519978766587351943831270835393219031728127"
4552 ];
4553
4554 for p in primes {
4555 let mut tg = PrimeCkTestGauges::blank();
4556 let row = Row::new_from_str(p).unwrap();
4557 assert_eq!(
4558 Some(true),
4559 prime_ck(&row, None, &mut tg),
4560 "{}",
4561 row.to_number()
4562 );
4563 assert_eq!(PrimeCkEscCode::Pn, tg.esc, "{}", row.to_number());
4564 }
4565 }
4566
4567 #[test]
4568 fn not_primes_test() {
4569 let not_primes = [
4570 ("6", PrimeCkEscCode::Ob),
4571 ("4009", PrimeCkEscCode::Np),
4572 ("7917", PrimeCkEscCode::Dt),
4573 ("19371", PrimeCkEscCode::Dt),
4574 ("100005587", PrimeCkEscCode::Np),
4575 ("100010713", PrimeCkEscCode::Np),
4576 ("1000037291", PrimeCkEscCode::Np),
4577 ("1000062029", PrimeCkEscCode::Np),
4578 ("5210644015679228794060694325390955853335898483908056458352183851018372555735223", PrimeCkEscCode::Dt),
4579 ("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057153", PrimeCkEscCode::Dt),
4580 ("531137992816767098689588206552468627329593117727031923199444138200403559860852242739162502265229285668889329486246501015346579337652707239409519978766587351943831270835393219031728121", PrimeCkEscCode::Np)
4581 ];
4582
4583 for np in not_primes {
4584 let mut tg = PrimeCkTestGauges::blank();
4585 let row = Row::new_from_str(np.0).unwrap();
4586 assert_eq!(
4587 Some(false),
4588 prime_ck(&row, None, &mut tg),
4589 "{}",
4590 row.to_number()
4591 );
4592 assert_eq!(np.1, tg.esc, "{}", row.to_number());
4593 }
4594 }
4595
4596 #[test]
4597 fn readme_sample_test() {
4598 let num = Row::new_from_str("340282366920938463463374607431768211479").unwrap();
4599 let limit = Duration::from_secs(3);
4600 assert_eq!(
4601 Some(false),
4602 prime_ck(&num, Some(limit), &mut PrimeCkTestGauges::blank())
4603 );
4604 }
4605 }
4606
4607 mod prime_gen_res {
4608 use crate::PrimeGenRes;
4609
4610 #[test]
4611 fn uproot_all_test() {
4612 let test = PrimeGenRes::All(vec![1, 2, 3, 4]);
4613 assert_eq!(vec![1, 2, 3, 4], test.uproot_all());
4614 }
4615
4616 #[test]
4617 #[should_panic(expected = "Not `PrimeGenRes::All(_)` variant.")]
4618 fn uproot_all_not_all_test() {
4619 _ = PrimeGenRes::Max(0).uproot_all();
4620 }
4621
4622 #[test]
4623 fn max_all_test() {
4624 let test = PrimeGenRes::Max(99);
4625 assert_eq!(99, test.uproot_max());
4626 }
4627
4628 #[test]
4629 #[should_panic(expected = "Not `PrimeGenRes::Max(_)` variant.")]
4630 fn uproot_max_not_max_test() {
4631 _ = PrimeGenRes::All(vec![0; 0]).uproot_max();
4632 }
4633 }
4634
4635 mod prime_gen_res_aide {
4636 use crate::{PrimeGenErr, PrimeGenRes, PrimeGenResAide};
4637
4638 #[test]
4639 fn uproot_all_ok() {
4640 let proof = vec![3, 2, 1];
4641 let res: Result<PrimeGenRes<usize>, PrimeGenErr> = Ok(PrimeGenRes::All(proof.clone()));
4642 let test = res.uproot_all();
4643
4644 assert_eq!(proof, test);
4645 }
4646
4647 #[test]
4648 #[should_panic(expected = "Not `Ok(_)` variant.")]
4649 fn uproot_all_err() {
4650 let err = PrimeGenErr::TimeframeExhaustion;
4651 let res: Result<PrimeGenRes<usize>, PrimeGenErr> = Err(err);
4652 _ = res.uproot_all();
4653 }
4654
4655 #[test]
4656 #[should_panic(expected = "Not `PrimeGenRes::All(_)` variant.")]
4657 fn uproot_all_ok_max() {
4658 let max = 17;
4659 let res: Result<PrimeGenRes<usize>, PrimeGenErr> = Ok(PrimeGenRes::Max(max));
4660 _ = res.uproot_all();
4661 }
4662
4663 #[test]
4664 fn uproot_max_ok() {
4665 let proof = 17;
4666 let res: Result<PrimeGenRes<usize>, PrimeGenErr> = Ok(PrimeGenRes::Max(proof));
4667 let test = res.uproot_max();
4668
4669 assert_eq!(proof, test);
4670 }
4671
4672 #[test]
4673 #[should_panic(expected = "Not `Ok(_)` variant.")]
4674 fn uproot_max_err() {
4675 let err = PrimeGenErr::TimeframeExhaustion;
4676 let res: Result<PrimeGenRes<usize>, PrimeGenErr> = Err(err);
4677 _ = res.uproot_max();
4678 }
4679
4680 #[test]
4681 #[should_panic(expected = "Not `PrimeGenRes::Max(_)` variant.")]
4682 fn uproot_max_ok_all() {
4683 let all = vec![3, 2, 1];
4684 let res: Result<PrimeGenRes<usize>, PrimeGenErr> = Ok(PrimeGenRes::All(all));
4685 _ = res.uproot_max();
4686 }
4687 }
4688
4689 mod pg {
4690 use crate::{PrimeGenClass, PrimeGenErr, PrimeGenRes, PrimeGenResAide};
4691 use std::time::{Duration, Instant};
4692
4693 #[test]
4694 fn basic_primes_test() {
4695 let vals: [u8; 15] = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47];
4696
4697 for rix in 0..15 {
4698 let p = || pg!(rix + 1, PrimeGenClass::Nth, false, u8, None);
4699 assert_eq!(vals[rix], p().uproot_max());
4700 }
4701 }
4702
4703 #[test]
4704 fn basic_primes_test2() {
4705 let vals: [u8; 13] = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41];
4706
4707 for v in vals {
4708 let p = || pg!(v as usize, PrimeGenClass::Lim, false, u8, None);
4709 assert_eq!(v, p().uproot_max());
4710 }
4711 }
4712
4713 #[test]
4714 fn advanced_primes_test() {
4715 #[rustfmt::skip]
4716 let vals: [u16; 20] = [
4717 6143, 6151, 6163, 6173, 6197,
4718 6199, 6203, 6211, 6217, 6221,
4719 6229, 6247, 6257, 6263, 6269,
4720 6271, 6277, 6287, 6299, 6301,
4721 ];
4722
4723 for rix in 0..20 {
4724 let p = || pg!(rix + 801, PrimeGenClass::Nth, false, u16, None);
4725 assert_eq!(vals[rix], p().uproot_max());
4726 }
4727 }
4728
4729 #[test]
4730 fn advanced_primes_test2() {
4731 #[rustfmt::skip]
4732 let vals: [u16; 20] = [
4733 6143, 6151, 6163, 6173, 6197,
4734 6199, 6203, 6211, 6217, 6221,
4735 6229, 6247, 6257, 6263, 6269,
4736 6271, 6277, 6287, 6299, 6301,
4737 ];
4738
4739 for v in vals {
4740 let p = || pg!(v as usize, PrimeGenClass::Lim, false, u16, None);
4741 assert_eq!(v, p().uproot_max());
4742 }
4743 }
4744
4745 #[test]
4746 fn lim_test() {
4747 let vals: [u16; 2] = [65413, 65418];
4748
4749 for v in vals {
4750 let p = || pg!(v as usize, PrimeGenClass::Lim, false, u16, None);
4751 assert_eq!(65413, p().uproot_max());
4752 }
4753 }
4754
4755 #[test]
4756 #[cfg(feature = "ext-tests")]
4757 fn large_nth_test() {
4759 let limit = Duration::from_secs(60);
4760 let p = || pg!(200_000, PrimeGenClass::Nth, false, u32, Some(limit));
4761 assert_eq!(Ok(PrimeGenRes::Max(2_750_159)), p());
4762 }
4763
4764 mod timeframe_exhaustion {
4765 use crate::{PrimeGenClass, PrimeGenErr, PrimeGenRes};
4766 use std::time::{Duration, Instant};
4767 #[test]
4768 fn basic_test() {
4769 let lim = Duration::from_secs(1);
4770 let res = || pg!(10_000_000, PrimeGenClass::Nth, false, u128, Some(lim));
4771 assert_eq!(Err(PrimeGenErr::TimeframeExhaustion), res());
4772 }
4773
4774 #[test]
4775 fn two_always_test() {
4776 let lim = Duration::ZERO;
4777 let res = || pg!(1, PrimeGenClass::Nth, false, u8, Some(lim));
4778 assert_eq!(Ok(PrimeGenRes::Max(2)), res());
4779
4780 let lim = Duration::ZERO;
4781 let res = || pg!(2, PrimeGenClass::Lim, false, u8, Some(lim));
4782 assert_eq!(Ok(PrimeGenRes::Max(2)), res());
4783 }
4784 }
4785
4786 mod invalid_input {
4787 use crate::{PrimeGenClass, PrimeGenErr, PrimeGenRes};
4788 use std::time::{Duration, Instant};
4789
4790 #[test]
4791 fn invalid_nth_test() {
4792 let test = || pg!(0, PrimeGenClass::Nth, false, u8, None);
4793 assert_eq!(Err(PrimeGenErr::AimlessInput(0)), test());
4794 }
4795
4796 #[test]
4797 fn invalid_limit_test() {
4798 for lim in [0, 1] {
4799 let test = || pg!(lim, PrimeGenClass::Lim, false, usize, None);
4800 assert_eq!(Err(PrimeGenErr::AimlessInput(lim)), test());
4801 }
4802 }
4803
4804 #[test]
4805 fn limit_outside_type_size_test() {
4806 let test = || pg!(255, PrimeGenClass::Lim, false, u8, None);
4807 assert_eq!(Ok(PrimeGenRes::Max(251)), test());
4808
4809 let test = || pg!(256, PrimeGenClass::Lim, false, u8, None);
4810 assert_eq!(Err(PrimeGenErr::InputGreaterThanSizeMax(256)), test());
4811 }
4812
4813 #[test]
4814 fn nth_outside_type_size_test() {
4815 let test = || pg!(54, PrimeGenClass::Nth, false, u8, None);
4816 assert_eq!(Ok(PrimeGenRes::Max(251)), test());
4817
4818 let test = || pg!(55, PrimeGenClass::Nth, false, u8, None);
4819 assert_eq!(Err(PrimeGenErr::ValueGreaterThanSizeMax(55, 257)), test());
4820 }
4821
4822 #[test]
4823 #[should_panic(expected = "capacity overflow")]
4824 fn impossible_to_unfit_type_size_test() {
4825 let test = || pg!(usize::MAX, PrimeGenClass::Lim, false, u128, None);
4826 _ = test();
4827 }
4828 }
4829
4830 mod cap {
4831 use crate::{PrimeGenClass, PrimeGenErr, PrimeGenRes, PrimeGenResAide};
4832 use std::time::{Duration, Instant};
4833
4834 #[test]
4835 fn lim_test() {
4836 let test = || pg!(7919, PrimeGenClass::Lim, true, usize, None);
4839 let test = test().uproot_all();
4840 assert_eq!(true, test.capacity() < 1138);
4841 }
4842
4843 #[test]
4844 fn nth_test() {
4845 let test = || pg!(1000, PrimeGenClass::Nth, true, usize, None);
4846 let test = test().uproot_all();
4847 assert_eq!(1000, test.capacity());
4848 }
4849 }
4850
4851 mod all {
4852 use crate::{PrimeGenClass, PrimeGenErr, PrimeGenRes, PrimeGenResAide};
4853 use std::time::{Duration, Instant};
4854
4855 #[test]
4856 fn basic_test() {
4857 let test1 = || pg!(11, PrimeGenClass::Nth, true, u8, None);
4858 let test2 = || pg!(31, PrimeGenClass::Lim, true, u8, None);
4859
4860 let proof: [u8; 11] = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31];
4861
4862 let test1 = test1().uproot_all();
4863 let test2 = test2().uproot_all();
4864
4865 assert_eq!(test1, test2);
4866 assert_eq!(proof, test1.as_slice());
4867 }
4868
4869 #[test]
4870 fn advanced_test() {
4871 let test1 = || pg!(1000, PrimeGenClass::Nth, true, u16, None);
4872 let test2 = || pg!(7919, PrimeGenClass::Lim, true, u16, None);
4873
4874 let test1 = test1().uproot_all();
4875 let test2 = test2().uproot_all();
4876
4877 assert_eq!(1000, test1.len());
4878 assert_eq!(1000, test2.len());
4879 assert_eq!(test1, test2);
4880
4881 assert_eq!(7919, test1[999]);
4882 assert_eq!(6997, test1[899]);
4883 assert_eq!(6133, test1[799]);
4884 assert_eq!(5279, test1[699]);
4885 assert_eq!(4409, test1[599]);
4886 assert_eq!(3571, test1[499]);
4887 assert_eq!(2741, test1[399]);
4888 assert_eq!(1987, test1[299]);
4889 assert_eq!(1223, test1[199]);
4890 assert_eq!(541, test1[99]);
4891 assert_eq!(2, test1[0]);
4892 }
4893 }
4894
4895 mod examples {
4896
4897 #[test]
4898 fn example_1() {
4899 use crate::{pg, PrimeGenClass, PrimeGenErr, PrimeGenRes, PrimeGenResAide};
4900 use std::time::{Duration, Instant};
4901
4902 let all1 = || pg!(11, PrimeGenClass::Nth, true, usize, None);
4903 let all2 = || pg!(31, PrimeGenClass::Lim, true, usize, None);
4904
4905 let proof: [usize; 11] = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31];
4906
4907 let all1 = all1().uproot_all();
4908 let all2 = all2().uproot_all();
4909
4910 assert_eq!(all1, all2);
4911 assert_eq!(proof, all1.as_slice());
4912 }
4913
4914 #[test]
4915 fn example_2() {
4916 use crate::{pg, PrimeGenClass, PrimeGenErr, PrimeGenRes, PrimeGenResAide};
4917 use std::time::{Duration, Instant};
4918
4919 let limit = Duration::from_secs(1);
4920 let result = (|| pg!(5_000, PrimeGenClass::Nth, false, u128, Some(limit)))();
4921
4922 assert_eq!(48_611, result.uproot_max());
4923 }
4924
4925 #[test]
4926 fn example_3() {
4927 use crate::{pg, PrimeGenClass, PrimeGenErr, PrimeGenRes, PrimeGenResAide};
4928 use std::time::{Duration, Instant};
4929
4930 let num = || pg!(20_000, PrimeGenClass::Nth, false, u64, None);
4931 assert_eq!(224_737, num().uproot_max());
4932
4933 let num = || pg!(20_000, PrimeGenClass::Nth, false, u32, None);
4934 assert_eq!(224_737, num().uproot_max());
4935 }
4936 }
4937 }
4938
4939 mod pg_sw {
4940 use crate::{PrimeGenClass, PrimeGenErr, PrimeGenRes, PrimeGenResAide};
4941 use std::time::{Duration, Instant};
4942
4943 #[test]
4944 fn basic_primes_test() {
4945 let vals: [u8; 15] = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47];
4946
4947 for rix in 0..15 {
4948 let p = || pg_sw!(rix + 1, PrimeGenClass::Nth, false, u8, None);
4949 assert_eq!(vals[rix], p().uproot_max());
4950 }
4951 }
4952
4953 #[test]
4954 fn basic_primes_test2() {
4955 let vals: [u8; 13] = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41];
4956
4957 for v in vals {
4958 let p = || pg_sw!(v as usize, PrimeGenClass::Lim, false, u8, None);
4959 assert_eq!(v, p().uproot_max());
4960 }
4961 }
4962
4963 #[test]
4964 fn advanced_primes_test() {
4965 #[rustfmt::skip]
4966 let vals: [u16; 20] = [
4967 6143, 6151, 6163, 6173, 6197,
4968 6199, 6203, 6211, 6217, 6221,
4969 6229, 6247, 6257, 6263, 6269,
4970 6271, 6277, 6287, 6299, 6301,
4971 ];
4972
4973 for rix in 0..20 {
4974 let p = || pg_sw!(rix + 801, PrimeGenClass::Nth, false, u16, None);
4975 assert_eq!(vals[rix], p().uproot_max());
4976 }
4977 }
4978
4979 #[test]
4980 fn advanced_primes_test2() {
4981 #[rustfmt::skip]
4982 let vals: [u16; 20] = [
4983 6143, 6151, 6163, 6173, 6197,
4984 6199, 6203, 6211, 6217, 6221,
4985 6229, 6247, 6257, 6263, 6269,
4986 6271, 6277, 6287, 6299, 6301,
4987 ];
4988
4989 for v in vals {
4990 let p = || pg_sw!(v as usize, PrimeGenClass::Lim, false, u16, None);
4991 assert_eq!(v, p().uproot_max());
4992 }
4993 }
4994
4995 #[test]
4996 fn lim_test() {
4997 let vals: [u16; 2] = [65413, 65418];
4998
4999 for v in vals {
5000 let p = || pg_sw!(v as usize, PrimeGenClass::Lim, false, u16, None);
5001 assert_eq!(65413, p().uproot_max());
5002 }
5003 }
5004
5005 #[test]
5006 #[cfg(feature = "ext-tests")]
5007 fn large_nth_test() {
5008 let limit = Duration::from_secs(80);
5009 let p = || pg_sw!(200_000, PrimeGenClass::Nth, false, u32, Some(limit));
5010 assert_eq!(Ok(PrimeGenRes::Max(2_750_159)), p());
5011 }
5012
5013 mod timeframe_exhaustion {
5014 use crate::{PrimeGenClass, PrimeGenErr, PrimeGenRes};
5015 use std::time::{Duration, Instant};
5016 #[test]
5017 fn basic_test() {
5018 let lim = Duration::from_secs(1);
5019 let res = || pg_sw!(10_000_000, PrimeGenClass::Nth, false, u128, Some(lim));
5020 assert_eq!(Err(PrimeGenErr::TimeframeExhaustion), res());
5021 }
5022
5023 #[test]
5024 fn two_always_test() {
5025 let lim = Duration::ZERO;
5026 let res = || pg_sw!(1, PrimeGenClass::Nth, false, u8, Some(lim));
5027 assert_eq!(Ok(PrimeGenRes::Max(2)), res());
5028
5029 let lim = Duration::ZERO;
5030 let res = || pg_sw!(2, PrimeGenClass::Lim, false, u8, Some(lim));
5031 assert_eq!(Ok(PrimeGenRes::Max(2)), res());
5032 }
5033 }
5034
5035 mod invalid_input {
5036 use crate::{PrimeGenClass, PrimeGenErr, PrimeGenRes};
5037 use std::time::{Duration, Instant};
5038
5039 #[test]
5040 fn invalid_nth_test() {
5041 let test = || pg_sw!(0, PrimeGenClass::Nth, false, u8, None);
5042 assert_eq!(Err(PrimeGenErr::AimlessInput(0)), test());
5043 }
5044
5045 #[test]
5046 fn invalid_limit_test() {
5047 for lim in [0, 1] {
5048 let test = || pg_sw!(lim, PrimeGenClass::Lim, false, usize, None);
5049 assert_eq!(Err(PrimeGenErr::AimlessInput(lim)), test());
5050 }
5051 }
5052
5053 #[test]
5054 fn limit_outside_type_size_test() {
5055 let test = || pg_sw!(255, PrimeGenClass::Lim, false, u8, None);
5056 assert_eq!(Ok(PrimeGenRes::Max(251)), test());
5057
5058 let test = || pg_sw!(256, PrimeGenClass::Lim, false, u8, None);
5059 assert_eq!(Err(PrimeGenErr::InputGreaterThanSizeMax(256)), test());
5060 }
5061
5062 #[test]
5063 fn nth_outside_type_size_test() {
5064 let test = || pg_sw!(54, PrimeGenClass::Nth, false, u8, None);
5065 assert_eq!(Ok(PrimeGenRes::Max(251)), test());
5066
5067 let test = || pg_sw!(55, PrimeGenClass::Nth, false, u8, None);
5068 assert_eq!(Err(PrimeGenErr::ValueGreaterThanSizeMax(55, 257)), test());
5069 }
5070
5071 #[test]
5072 fn impossible_to_unfit_type_size_test() {
5073 let test = || pg_sw!(u8::MAX as usize, PrimeGenClass::Lim, false, u16, None);
5074 assert_eq!(Ok(PrimeGenRes::Max(251)), test());
5075 }
5076 }
5077
5078 mod cap {
5079 use crate::{PrimeGenClass, PrimeGenErr, PrimeGenRes, PrimeGenResAide};
5080 use std::time::{Duration, Instant};
5081
5082 #[test]
5083 fn lim_test() {
5084 let test = || pg_sw!(7919, PrimeGenClass::Lim, true, usize, None);
5087 let test = test().uproot_all();
5088 assert_eq!(1138, test.capacity());
5089 }
5090
5091 #[test]
5092 fn nth_test() {
5093 let test = || pg_sw!(1000, PrimeGenClass::Nth, true, usize, None);
5094 let test = test().uproot_all();
5095 assert_eq!(1000, test.capacity());
5096 }
5097 }
5098
5099 mod all {
5100 use crate::{PrimeGenClass, PrimeGenErr, PrimeGenRes, PrimeGenResAide};
5101 use std::time::{Duration, Instant};
5102
5103 #[test]
5104 fn basic_test() {
5105 let test1 = || pg_sw!(11, PrimeGenClass::Nth, true, u8, None);
5106 let test2 = || pg_sw!(31, PrimeGenClass::Lim, true, u8, None);
5107
5108 let proof: [u8; 11] = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31];
5109
5110 let test1 = test1().uproot_all();
5111 let test2 = test2().uproot_all();
5112
5113 assert_eq!(test1, test2);
5114 assert_eq!(proof, test1.as_slice());
5115 }
5116
5117 #[test]
5118 fn advanced_test() {
5119 let test1 = || pg_sw!(1000, PrimeGenClass::Nth, true, u16, None);
5120 let test2 = || pg_sw!(7919, PrimeGenClass::Lim, true, u16, None);
5121
5122 let test1 = test1().uproot_all();
5123 let test2 = test2().uproot_all();
5124
5125 assert_eq!(1000, test1.len());
5126 assert_eq!(1000, test2.len());
5127 assert_eq!(test1, test2);
5128
5129 assert_eq!(7919, test1[999]);
5130 assert_eq!(6997, test1[899]);
5131 assert_eq!(6133, test1[799]);
5132 assert_eq!(5279, test1[699]);
5133 assert_eq!(4409, test1[599]);
5134 assert_eq!(3571, test1[499]);
5135 assert_eq!(2741, test1[399]);
5136 assert_eq!(1987, test1[299]);
5137 assert_eq!(1223, test1[199]);
5138 assert_eq!(541, test1[99]);
5139 assert_eq!(2, test1[0]);
5140 }
5141 }
5142
5143 #[test]
5144 fn faster_test() {
5145 let test = || pg_sw!(20_000 as usize, PrimeGenClass::Nth, false, u32, None);
5146 let test = test().uproot_max();
5147 assert_eq!(224_737, test);
5148 }
5149
5150 #[test]
5151 fn slower_test() {
5152 let test = || pg_sw!(20_000, PrimeGenClass::Nth, false, u64, None);
5153 let test = test().uproot_max();
5154 assert_eq!(224_737, test);
5155 }
5156 }
5157
5158 mod heron_sqrt {
5159 use crate::{heron_sqrt, Row};
5160 #[test]
5161 fn basic_test() {
5162 let row = Row::new_from_u8(16);
5163 assert_eq!([4], &*heron_sqrt(&row));
5164 }
5165
5166 #[test]
5167 #[rustfmt::skip]
5168 fn readme_sample_test() {
5169 let radicand = Row::new_from_str("9754610577924096936222542295378750190521").unwrap();
5170 let test = Row::new_from_u128(98_765_432_100_123_456_789);
5171 assert_eq!(test, heron_sqrt(&radicand));
5172 }
5173 }
5174
5175 mod heron_sqrt_raw {
5176 use crate::{heron_sqrt_raw, new_from_str_raw, nought_raw, unity_raw};
5177
5178 #[test]
5179 fn test_2() {
5180 assert_eq!(vec![1], heron_sqrt_raw(&vec![2]));
5181 }
5182
5183 #[test]
5184 fn test_3() {
5185 assert_eq!(vec![1], heron_sqrt_raw(&vec![3]));
5186 }
5187
5188 #[test]
5189 fn test_4() {
5190 assert_eq!(vec![2], heron_sqrt_raw(&vec![4]));
5191 }
5192
5193 #[test]
5194 fn test_7() {
5195 assert_eq!(vec![2], heron_sqrt_raw(&vec![8]));
5196 }
5197
5198 #[test]
5199 fn test_8() {
5200 assert_eq!(vec![3], heron_sqrt_raw(&vec![9]));
5201 }
5202
5203 #[test]
5204 fn test_17() {
5205 let test = new_from_num_raw!(17);
5206 assert_eq!(vec![4], heron_sqrt_raw(&test));
5207 }
5208
5209 #[test]
5210 fn test_24() {
5211 let test = new_from_num_raw!(24);
5212 assert_eq!(vec![4], heron_sqrt_raw(&test));
5213 }
5214
5215 #[test]
5216 fn test_25() {
5217 let test = new_from_num_raw!(25);
5218 assert_eq!(vec![5], heron_sqrt_raw(&test));
5219 }
5220
5221 #[test]
5222 fn load_test() {
5223 let test = new_from_str_raw(
5224 "999999999999999999999999999999999999998000000000000000000000000000000000000001",
5225 )
5226 .unwrap();
5227 let proof = new_from_str_raw("999999999999999999999999999999999999999").unwrap();
5228 assert_eq!(proof, heron_sqrt_raw(&test));
5229 }
5230
5231 #[test]
5232 fn unity_test() {
5233 assert_eq!(unity_raw(), heron_sqrt_raw(&unity_raw()));
5234 }
5235
5236 #[test]
5237 fn nought_test() {
5238 assert_eq!(nought_raw(), heron_sqrt_raw(&nought_raw()));
5239 }
5240 }
5241
5242 mod multiplication {
5243 use crate::multiplication;
5244
5245 #[test]
5246 fn basic_test() {
5247 let mpler = vec![2];
5248 let mcand = vec![3, 2];
5249
5250 let prod = multiplication(&mpler, &mcand);
5251 assert_eq!(vec![6, 4], prod);
5252 }
5253
5254 #[test]
5255 fn zero_multiplier_test() {
5257 let mpler = vec![0];
5258 let mcand = vec![3, 2, 1];
5259
5260 let prod = multiplication(&mpler, &mcand);
5261 assert_eq!(vec![0, 0, 0], prod);
5262 }
5263
5264 #[test]
5265 fn one_multiplier_test() {
5266 let mpler = vec![1];
5267 let mcand = vec![3, 2, 1];
5268
5269 let prod = multiplication(&mpler, &mcand);
5270 assert_eq!(mcand, prod);
5271 }
5272
5273 #[test]
5274 fn load_test() {
5275 let mpler = vec![1, 2, 3, 4, 5];
5276 let mcand = vec![5, 4, 3, 2, 1];
5277 let proof = new_from_num_raw!(670_592_745);
5278
5279 let prod = multiplication(&mpler, &mcand);
5280 assert_eq!(proof, prod);
5281 }
5282 }
5283
5284 mod power_steps {
5285 use crate::power_steps;
5286
5287 #[test]
5288 fn basic_test() {
5289 let steps = power_steps(4);
5290 let proof = vec![4, 2];
5291
5292 assert_eq!(proof, steps);
5293 assert_eq!(15, steps.capacity());
5294 }
5295
5296 #[test]
5297 fn max_test() {
5298 let mut step = u16::MAX;
5299 let steps = power_steps(step);
5300 assert_eq!(15, steps.len());
5301
5302 for s in steps {
5303 assert_eq!(step, s);
5304 step /= 2;
5305 }
5306 }
5307
5308 #[test]
5309 fn odd_end_test() {
5310 let steps = power_steps(12);
5311 let proof = vec![12, 6, 3];
5312
5313 assert_eq!(proof, steps);
5314 }
5315
5316 #[test]
5317 fn even_end_test() {
5318 let steps = power_steps(16);
5319 let proof = vec![16, 8, 4, 2];
5320
5321 assert_eq!(proof, steps);
5322 }
5323 }
5324
5325 mod power {
5326 use crate::{new_from_str_raw, nought_raw, power, unity_raw};
5327
5328 #[test]
5329 fn basic_test() {
5330 let pow = power(&[2], 16);
5331 assert_eq!(vec![6, 3, 5, 5, 6], pow);
5332 }
5333
5334 #[test]
5335 #[should_panic(expected = "Pow steps for powers > 1 only.")]
5336 fn pow_zero_test() {
5337 _ = power(&[2], 0);
5338 }
5339
5340 #[test]
5341 #[should_panic(expected = "Pow steps for powers > 1 only.")]
5342 fn pow_one_test() {
5343 _ = power(&[2], 1);
5344 }
5345
5346 #[test]
5347 fn pow_of_zero_test() {
5348 let pows = [2, 3, 5, 11, 20];
5349 let zero = nought_raw();
5350
5351 for p in pows {
5352 let pow = power(&zero, p);
5353 assert_eq!(zero, pow);
5354 }
5355 }
5356
5357 #[test]
5358 fn pow_of_one_test() {
5359 let pows = [2, 3, 5, 11, 20];
5360 let one = unity_raw();
5361
5362 for p in pows {
5363 let pow = power(&one, p);
5364 assert_eq!(one, pow);
5365 }
5366 }
5367
5368 #[test]
5369 fn pow_two_test() {
5370 let pow = power(&[5, 5, 2], 2);
5371 assert_eq!(vec![5, 2, 0, 5, 6], pow);
5372 }
5373
5374 #[test]
5375 fn odd_test() {
5376 let pow = power(&[5, 5, 2], 11);
5377 let proof = new_from_str_raw("296443535898840969287109375").unwrap();
5378
5379 assert_eq!(proof, pow);
5380 }
5381
5382 #[test]
5383 fn even_test() {
5384 let pow = power(&[5, 5, 2], 10);
5385 let proof = new_from_str_raw("1162523670191533212890625").unwrap();
5386
5387 assert_eq!(proof, pow);
5388 }
5389 }
5390
5391 use crate::clear_swap;
5392 #[test]
5393 fn clear_swap_test() {
5394 let mut mcand = vec![3, 2, 1];
5395 let mut i_sum = vec![6, 5, 4];
5396
5397 let mcand_ptr = mcand.as_ptr() as usize;
5398 let i_sum_ptr = i_sum.as_ptr() as usize;
5399
5400 clear_swap(&mut mcand, &mut i_sum);
5401
5402 assert_eq!(mcand.as_ptr() as usize, i_sum_ptr);
5403 assert_eq!(i_sum.as_ptr() as usize, mcand_ptr);
5404 assert_eq!(vec![6, 5, 4], mcand);
5405 assert_eq!(0, i_sum.len());
5406 }
5407
5408 mod muladd {
5409 use crate::muladd;
5410
5411 #[test]
5412 fn basic_test() {
5413 let mpler = 2;
5414 let mcand = [2, 3, 4];
5415 let mut sum = Vec::new();
5416
5417 muladd(mpler, &mcand, &mut sum, 0);
5418 assert_eq!(vec![4, 6, 8], sum);
5419 }
5420
5421 #[test]
5422 fn multiplication_test() {
5423 let mpler = 9;
5424 let mcand = [9, 8, 7, 6];
5425 let mut sum = Vec::new();
5426
5427 muladd(mpler, &mcand, &mut sum, 0);
5428 assert_eq!(vec![1, 0, 1, 1, 6], sum);
5429 }
5430
5431 #[test]
5432 fn offset_test() {
5433 let mpler = 9;
5434 let mcand = [1, 0, 0, 9];
5435 let mut sum = Vec::new();
5436
5437 muladd(mpler, &mcand, &mut sum, 1);
5438 assert_eq!(vec![9, 0, 0, 1, 8], sum);
5439 }
5440
5441 #[test]
5442 fn sum_test() {
5443 let mpler = 9;
5444 let mcand = [9, 9, 9, 9];
5445 let mut sum = vec![9, 9, 9, 9, 9];
5446
5447 muladd(mpler, &mcand, &mut sum, 0);
5448 assert_eq!(vec![0, 9, 9, 9, 8, 1], sum);
5449 }
5450 }
5451
5452 mod sumadd {
5453 use crate::sumadd;
5454
5455 #[test]
5456 fn basic_test() {
5457 let mut sum = vec![1];
5458
5459 sumadd(1, &mut sum, 0);
5460 assert_eq!(vec![2], sum);
5461 }
5462
5463 #[test]
5464 fn empty_sum_test() {
5465 let mut sum = vec![];
5466
5467 sumadd(9, &mut sum, 0);
5468 assert_eq!(vec![9], sum);
5469 }
5470
5471 #[test]
5472 fn offset_test() {
5473 let mut sum = vec![0, 1];
5474
5475 sumadd(1, &mut sum, 1);
5476 assert_eq!(vec![0, 2], sum);
5477 }
5478
5479 #[test]
5480 fn takeover_test() {
5481 let mut sum = vec![1];
5482
5483 sumadd(9, &mut sum, 0);
5484 assert_eq!(vec![0, 1], sum);
5485 }
5486
5487 #[test]
5488 fn extension_test() {
5489 let mut sum = vec![1];
5490
5491 sumadd(9, &mut sum, 0);
5492 assert_eq!(vec![0, 1], sum);
5493 }
5494
5495 #[test]
5496 fn max_product_test() {
5497 let mut sum = vec![9, 9, 9, 9, 9, 9];
5498
5499 sumadd(81, &mut sum, 1);
5500 assert_eq!(vec![9, 0, 8, 0, 0, 0, 1], sum);
5501 }
5502
5503 #[test]
5504 fn extreme_test() {
5505 let mut sum = vec![0];
5506
5507 sumadd(255, &mut sum, 0);
5508 assert_eq!(vec![5, 5, 2], sum);
5509 }
5510
5511 #[test]
5512 fn extreme_test2() {
5513 let mut sum = vec![9, 9, 9];
5514
5515 sumadd(246, &mut sum, 0);
5516 assert_eq!(vec![5, 4, 2, 1], sum);
5517 }
5518 }
5519
5520 mod addition {
5525
5526 mod addition_sum {
5527 use crate::addition_sum;
5528
5529 #[test]
5530 fn basic_test() {
5531 let ad = vec![1, 2, 3];
5532 let mut sum = vec![4, 3, 2, 5, 5];
5533
5534 addition_sum(&ad, &mut sum, 0);
5535
5536 assert_eq!(vec![5, 5, 5, 5, 5], sum);
5537 }
5538
5539 #[test]
5540 fn takover_test() {
5541 let ad = vec![9];
5542 let mut sum = vec![9, 9, 9, 9, 9];
5543
5544 addition_sum(&ad, &mut sum, 0);
5545
5546 assert_eq!(vec![8, 0, 0, 0, 0, 1], sum);
5547 }
5548
5549 #[test]
5550 fn longer_addition_test() {
5551 let ad = vec![8, 8, 9, 9, 9];
5552 let mut sum = vec![1, 1];
5553
5554 addition_sum(&ad, &mut sum, 0);
5555
5556 assert_eq!(vec![9, 9, 9, 9, 9], sum);
5557 }
5558
5559 #[test]
5560 fn offset_test() {
5561 let ad = vec![9, 9, 9, 9];
5562 let mut sum = vec![1, 1, 7, 8];
5563
5564 addition_sum(&ad, &mut sum, 2);
5565
5566 assert_eq!(vec![1, 1, 6, 8, 0, 0, 1], sum);
5567 }
5568 }
5569
5570 mod addition_two {
5571 use crate::addition_two;
5572
5573 #[test]
5574 fn basic_test() {
5575 let ad1 = vec![8, 8, 7, 5];
5576 let ad2 = vec![1, 1, 2, 4, 9, 9];
5577 let mut sum = Vec::new();
5578
5579 addition_two(&ad1, &ad2, &mut sum);
5580
5581 assert_eq!(vec![9, 9, 9, 9, 9, 9], sum);
5582 }
5583
5584 #[test]
5585 fn takover_test1() {
5586 let ad1 = vec![99];
5587 let ad2 = vec![9];
5588 let mut sum = Vec::new();
5589
5590 addition_two(&ad1, &ad2, &mut sum);
5591
5592 assert_eq!(vec![8, 0, 1], sum);
5593 }
5594
5595 #[test]
5596 fn takover_test2() {
5597 let ad1 = vec![9];
5598 let ad2 = vec![99];
5599 let mut sum = Vec::new();
5600
5601 addition_two(&ad1, &ad2, &mut sum);
5602
5603 assert_eq!(vec![8, 0, 1], sum);
5604 }
5605
5606 #[test]
5607 fn longer_addition_test1() {
5608 let ad1 = vec![8, 8, 9, 9, 9];
5609 let ad2 = vec![1, 1];
5610 let mut sum = Vec::new();
5611
5612 addition_two(&ad1, &ad2, &mut sum);
5613
5614 assert_eq!(vec![9, 9, 9, 9, 9], sum);
5615 }
5616
5617 #[test]
5618 fn longer_addition_test2() {
5619 let ad1 = vec![1, 1];
5620 let ad2 = vec![8, 8, 9, 9, 9];
5621 let mut sum = Vec::new();
5622
5623 addition_two(&ad1, &ad2, &mut sum);
5624
5625 assert_eq!(vec![9, 9, 9, 9, 9], sum);
5626 }
5627 }
5628 }
5629
5630 mod subtraction {
5635
5636 mod subtraction_arithmetical {
5637 use crate::{new_from_str_raw, subtraction_arithmetical};
5638
5639 #[test]
5640 fn basic_test() {
5641 let mut mindiff = vec![9, 9];
5642 let ratio = subtraction_arithmetical(&mut mindiff, &vec![0, 1]);
5643 assert_eq!(&[9, 8], &*mindiff);
5644 assert_eq!(&[1], &*ratio);
5645 }
5646
5647 #[test]
5648 fn advanced_test() {
5649 let mut mindiff =
5650 new_from_str_raw("6577102745386680762814942322444851025767571854389858533375")
5651 .unwrap();
5652 let subtrahend =
5653 new_from_str_raw("6296101835386680762814942322444851025767571854389858533376")
5654 .unwrap();
5655 let proof =
5656 new_from_str_raw("281000909999999999999999999999999999999999999999999999999")
5657 .unwrap();
5658
5659 let ratio = subtraction_arithmetical(&mut mindiff, &subtrahend);
5660 assert_eq!(proof, mindiff);
5661 assert_eq!(&[1], &*ratio);
5662 }
5663
5664 #[test]
5665 fn takeover_test() {
5667 let mut mindiff = vec![8, 2, 2, 0, 1];
5668 let ratio = subtraction_arithmetical(&mut mindiff, &vec![9, 2, 1, 1]);
5669 assert_eq!(&[9, 9, 0, 9], &*mindiff);
5670 assert_eq!(&[1], &*ratio);
5671 }
5672
5673 #[test]
5674 fn overrun_clearing_test() {
5681 let mut mindiff = vec![2, 0, 0, 0, 0];
5682 let ratio = subtraction_arithmetical(&mut mindiff, &vec![7, 7, 3]);
5683
5684 assert_eq!(&[2, 0, 0, 9, 9], &*mindiff);
5685 assert_eq!(&[0], &*ratio);
5686 }
5687
5688 #[test]
5689 fn zero_truncation_test() {
5690 let mut mindiff = vec![9, 9, 9];
5691 let ratio = subtraction_arithmetical(&mut mindiff, &vec![8, 9, 9]);
5692 assert_eq!(&[1], &*mindiff);
5693 assert_eq!(&[1], &*ratio);
5694 }
5695
5696 #[test]
5701 fn top_place_9_preservation_test() {
5702 let mindiff = vec![1, 0, 9];
5703 let mut proof = mindiff.clone();
5704
5705 let ratio = subtraction_arithmetical(&mut proof, &vec![2, 0, 9]);
5706 assert_eq!(mindiff, proof);
5707 assert_eq!(&[0], &*ratio);
5708 }
5709
5710 #[test]
5714 fn lesser_minuend_test() {
5715 let mindiff = vec![1, 1, 1];
5716 let mut proof = mindiff.clone();
5717 let ratio = subtraction_arithmetical(&mut proof, &vec![3, 4, 7]);
5718 assert_eq!(mindiff, proof);
5719 assert_eq!(&[0], &*ratio);
5720 }
5721
5722 #[test]
5723 fn equal_operands_test() {
5724 let mut mindiff = vec![1, 1, 1];
5725 let subtrahend = mindiff.clone();
5726
5727 let ratio = subtraction_arithmetical(&mut mindiff, &subtrahend);
5728 assert_eq!(&[0], &*mindiff);
5729 assert_eq!(&[1], &*ratio);
5730 }
5731 }
5732
5733 mod subtraction_divisional {
5734 use crate::subtraction_divisional;
5735
5736 #[test]
5737 fn basic_test() {
5738 let mut minrem = vec![3, 3];
5739 let (ratio, rem_len) = subtraction_divisional(&mut minrem, &vec![1, 1]);
5740 assert_eq!(&[0, 0], &*minrem);
5741 assert_eq!(&[3], &*ratio);
5742 assert_eq!(0, rem_len);
5743 }
5744
5745 #[test]
5746 fn remainder_test() {
5747 let mut minrem = vec![9];
5748 let (ratio, rem_len) = subtraction_divisional(&mut minrem, &vec![7]);
5749 assert_eq!(&[2], &*minrem);
5750 assert_eq!(&[1], &*ratio);
5751 assert_eq!(1, rem_len);
5752 }
5753
5754 #[test]
5755 fn takeover_test() {
5756 let mut minrem = vec![9, 0, 9];
5757 let (ratio, rem_len) = subtraction_divisional(&mut minrem, &vec![9]);
5758 assert_eq!(&[0, 9, 9], &*minrem);
5759 assert_eq!(&[1, 0, 1], &*ratio);
5760 assert_eq!(0, rem_len);
5761 }
5762
5763 #[test]
5764 fn overrun_clearing_test() {
5771 let mut minrem = vec![2, 0, 0, 7, 7];
5772 let (ratio, rem_len) = subtraction_divisional(&mut minrem, &vec![7, 7]);
5773
5774 assert_eq!(&[2, 0, 9, 9, 9], &*minrem);
5775 assert_eq!(&[0, 0, 0, 1], &*ratio);
5776 assert_eq!(1, rem_len);
5777 }
5778
5779 #[test]
5780 fn advanced_test() {
5781 let mut minrem = new_from_num_raw!(627710173);
5782 let remainder = new_from_num_raw!(999999_130);
5783 let ratio = new_from_num_raw!(1955483);
5784
5785 let (rat, rem_len) = subtraction_divisional(&mut minrem, &vec![1, 2, 3]);
5786 assert_eq!(remainder, minrem);
5787 assert_eq!(ratio, rat);
5788 assert_eq!(3, rem_len);
5789 }
5790
5791 #[test]
5792 fn advanced_test2() {
5793 let mut minrem = new_from_num_raw!(627710173);
5794 let subtrahend = new_from_num_raw!(3552741);
5795 let remainder = new_from_num_raw!(99__2_427_757);
5796 let ratio = new_from_num_raw!(176);
5797
5798 let (rat, rem_len) = subtraction_divisional(&mut minrem, &subtrahend);
5799 assert_eq!(remainder, minrem);
5800 assert_eq!(ratio, rat);
5801 assert_eq!(7, rem_len);
5802 }
5803
5804 #[test]
5805 fn advanced_test3() {
5806 let mut minrem = new_from_num_raw!(242775712);
5807 let subtrahend = new_from_num_raw!(33333);
5808 let remainder = new_from_num_raw!(9999__11_473);
5809 let ratio = new_from_num_raw!(7283);
5810
5811 let (rat, rem_len) = subtraction_divisional(&mut minrem, &subtrahend);
5812 assert_eq!(remainder, minrem);
5813 assert_eq!(ratio, rat);
5814 assert_eq!(5, rem_len);
5815 }
5816
5817 #[test]
5823 fn top_place_9_preservation_test() {
5824 let mut minrem = vec![1, 1, 4, 5];
5825 let subtrahend = vec![2, 0, 9];
5826 let (ratio, rem_len) = subtraction_divisional(&mut minrem, &subtrahend);
5827 assert_eq!(&[1, 0, 9, 9], &*minrem);
5828 assert_eq!(&[5], &*ratio);
5829 assert_eq!(3, rem_len);
5830 }
5831
5832 #[test]
5836 fn lesser_dividend_test() {
5837 let mut minrem = vec![1, 1, 1];
5838 let proof = minrem.clone();
5839 let (ratio, rem_len) = subtraction_divisional(&mut minrem, &vec![3, 4, 7]);
5840 assert_eq!(proof, minrem);
5841 assert_eq!(&[0], &*ratio);
5842 assert_eq!(3, rem_len);
5843 }
5844
5845 #[test]
5847 fn equal_operands_test() {
5848 let mut minrem = vec![1, 1, 1];
5849 let subtrahend = vec![1, 1, 1];
5850
5851 let (ratio, rem_len) = subtraction_divisional(&mut minrem, &subtrahend);
5852 assert_eq!(&[0, 0, 0], &*minrem);
5853 assert_eq!(&[1], &*ratio);
5854 assert_eq!(0, rem_len);
5855 }
5856
5857 #[test]
5858 #[cfg(feature = "shorter-dividend-support")]
5859 fn shorter_dividend_test() {
5860 let mut minrem = vec![1, 1, 1];
5861 let subtrahend = vec![0, 4, 6, 8, 9, 3, 4, 7];
5862 let proof = minrem.clone();
5863
5864 let (ratio, rem_len) = subtraction_divisional(&mut minrem, &subtrahend);
5865 assert_eq!(proof, minrem);
5866 assert_eq!(&[0], &*ratio);
5867 assert_eq!(3, rem_len);
5868 }
5869 }
5870
5871 mod subtraction {
5872
5873 use crate::subtraction;
5874
5875 #[test]
5876 fn overrun_test_1() {
5883 let mut ctr = 0;
5884 let mut minrem = vec![2, 0, 0, 7, 7];
5885 let ratio = subtraction(&mut minrem, &vec![7, 7], true, &mut ctr);
5886
5887 assert_eq!(&[2, 0, 9, 9, 9], &*minrem);
5888 assert_eq!(&[0, 0, 0, 1], &*ratio);
5889 assert_eq!(1001, ctr);
5890 }
5891
5892 #[test]
5893 fn overrun_test_2() {
5900 let mut ctr = 0;
5901 let mut minrem = vec![2, 0, 0, 0, 0];
5902 let ratio = subtraction(&mut minrem, &vec![7, 7, 3], false, &mut ctr);
5903
5904 assert_eq!(&[2, 0, 0, 9, 9], &*minrem);
5905 assert_eq!(&[0], &*ratio);
5906 assert_eq!(1, ctr);
5907 }
5908 }
5909 }
5910
5911 mod ones {
5913 use crate::ones;
5914
5915 #[test]
5916 fn basic_test() {
5917 let num = 9;
5918 let mut takeover = 0;
5919
5920 assert_eq!(9, ones(num, &mut takeover));
5921 assert_eq!(0, takeover);
5922 }
5923
5924 #[test]
5925 fn split_test() {
5926 let num = 9;
5927 let mut takeover = 3;
5928
5929 assert_eq!(2, ones(num, &mut takeover));
5930 assert_eq!(1, takeover);
5931 }
5932
5933 #[test]
5934 fn maximum_test() {
5935 let num = 246;
5936 let mut takeover = 9;
5937
5938 assert_eq!(5, ones(num, &mut takeover));
5939 assert_eq!(25, takeover);
5940 }
5941 }
5942}
5943
5944