1use error::DivisionError;
9use generic::GenericInteger;
10
11use std::cmp::{Eq, Ordering, PartialEq};
12use std::fmt::Write;
13
14#[derive(Clone, Debug)]
16pub struct DivisionState<I> {
17 pub remainder: I,
18 pub divisor: I,
19}
20
21impl<I> DivisionState<I> {
22 pub fn new(remainder: I, divisor: I) -> Self {
23 DivisionState { remainder, divisor }
24 }
25}
26
27impl<I> PartialEq for DivisionState<I>
28where
29 I: PartialEq,
30{
31 fn eq(&self, other: &Self) -> bool {
32 self.remainder.eq(&other.remainder) && self.divisor.eq(&other.divisor)
33 }
34}
35
36impl<I> Eq for DivisionState<I> where I: Eq {}
37
38pub fn divide_integral<I, Consumer>(
81 mut dividend: I,
82 divisor: I,
83 mut consumer: Consumer,
84) -> Result<DivisionState<I>, DivisionError>
85where
86 Consumer: FnMut(u8) -> Result<bool, DivisionError>,
87 I: Clone + GenericInteger,
88{
89 if divisor.is_zero() {
90 return Err(DivisionError::DivisionByZero);
91 }
92
93 let mut ptr: I = match dividend.cmp(&divisor) {
95 Ordering::Equal => {
96 consumer(1u8)?;
97 return Ok(DivisionState::new(I::zero(), divisor));
98 }
99 Ordering::Less => {
100 consumer(0u8)?;
101 return Ok(DivisionState::new(dividend, divisor));
102 }
103 Ordering::Greater => {
104 let mut ptr: I = I::_1();
105
106 loop {
107 if ptr > dividend {
108 if I::_1r().map_or_else(|| ptr > I::_1(), |_1| ptr > *_1) {
109 I::_10r().map(|_10| ptr /= _10).or_else(|| {
110 ptr /= I::_10();
111 None
112 });
113 }
114 break;
115 }
116
117 ptr = match I::_10r()
118 .map_or_else(|| ptr.checked_mul(&I::_10()), |_10| ptr.checked_mul(_10))
119 {
120 Some(n) => n,
121 None => break,
122 };
123 }
124
125 ptr
126 }
127 };
128
129 let mut passed_leading_zeroes: bool = false;
130 loop {
131 let digit = dividend.div_floor(&ptr).div_floor(&divisor);
132
133 if I::_0r().map_or_else(|| digit > I::_0(), |_0| digit > *_0) {
134 passed_leading_zeroes = true;
135 dividend -= digit.clone() * &divisor * &ptr;
136 }
137
138 if passed_leading_zeroes {
139 let d: Option<u8> = digit.to_u8();
140 match d {
141 Some(n) => {
142 if !consumer(n)? {
143 return Ok(DivisionState::new(dividend, divisor));
144 }
145 }
146 None => unreachable!(),
147 };
148 }
149
150 if I::_1r().map_or_else(|| ptr == I::_1(), |_1| ptr == *_1) {
151 break;
152 }
153
154 I::_10r().map(|_10| ptr /= _10).or_else(|| {
155 ptr /= I::_10();
156 None
157 });
158 }
159
160 Ok(DivisionState::new(dividend, divisor))
161}
162
163#[inline]
191pub fn divide_rem<I, Consumer>(
192 dividend: I,
193 divisor: I,
194 consumer: Consumer,
195) -> Result<DivisionState<I>, DivisionError>
196where
197 Consumer: FnMut(
198 DivisionState<I>,
199 u8,
200 ) -> Result<Result<DivisionState<I>, DivisionState<I>>, DivisionError>,
201 I: Clone + GenericInteger,
202{
203 divide_rem_resume(DivisionState::new(dividend, divisor), consumer)
204}
205
206pub fn divide_rem_resume<I, Consumer>(
237 mut state: DivisionState<I>,
238 mut consumer: Consumer,
239) -> Result<DivisionState<I>, DivisionError>
240where
241 Consumer: FnMut(
242 DivisionState<I>,
243 u8,
244 ) -> Result<Result<DivisionState<I>, DivisionState<I>>, DivisionError>,
245 I: Clone + GenericInteger,
246{
247 loop {
248 if state.remainder.is_zero() {
249 break;
250 }
251
252 let digit = I::_10r()
253 .map(|_10| {
254 let (rem, digit) = state.remainder.checked_mul(_10).map_or_else(
255 || {
256 let (reduced_divisor, reduced_divisor_rem) = state.divisor.div_rem(_10);
257
258 let mut digit = state.remainder.div_floor(&reduced_divisor);
259 let mut remainder = state.remainder.clone();
260
261 remainder -= digit.clone() * &reduced_divisor;
262
263 let mut red_div_rem_diff =
264 (reduced_divisor_rem.clone() * &digit).div_rem(_10);
265
266 loop {
267 if red_div_rem_diff.0 > remainder {
268 digit -= I::one();
269 remainder += &reduced_divisor;
270 red_div_rem_diff =
271 (reduced_divisor_rem.clone() * &digit).div_rem(_10);
272 } else {
273 break;
274 }
275 }
276
277 remainder -= red_div_rem_diff.0;
278 remainder *= _10;
279
280 if red_div_rem_diff.1 > remainder {
281 digit -= I::one();
282 remainder += &state.divisor;
283 }
284
285 remainder -= red_div_rem_diff.1;
286
287 (remainder, digit.to_u8())
288 },
289 |mut remainder| {
290 let digit = remainder.div_floor(&state.divisor);
291 remainder -= digit.clone() * &state.divisor;
292
293 (remainder, digit.to_u8())
294 },
295 );
296
297 state.remainder = rem;
298 digit
299 })
300 .or_else(|| {
301 let ten = I::_10();
302
303 let (rem, digit) = state.remainder.checked_mul(&ten).map_or_else(
304 || {
305 let (reduced_divisor, reduced_divisor_rem) = state.divisor.div_rem(&ten);
306
307 let mut digit = state.remainder.div_floor(&reduced_divisor);
308 let mut remainder = state.remainder.clone();
309
310 remainder -= digit.clone() * &reduced_divisor;
311
312 let mut red_div_rem_diff =
313 (reduced_divisor_rem.clone() * &digit).div_rem(&ten);
314
315 loop {
316 if red_div_rem_diff.0 > remainder {
317 digit -= I::one();
318 remainder += &reduced_divisor;
319 red_div_rem_diff =
320 (reduced_divisor_rem.clone() * &digit).div_rem(&ten);
321 } else {
322 break;
323 }
324 }
325
326 remainder -= red_div_rem_diff.0;
327 remainder *= &ten;
328
329 if red_div_rem_diff.1 > remainder {
330 digit -= I::one();
331 remainder += &state.divisor;
332 }
333
334 remainder -= red_div_rem_diff.1;
335
336 (remainder, digit.to_u8())
337 },
338 |mut remainder: I| {
339 let digit = remainder.div_floor(&state.divisor);
340 remainder -= digit.clone() * &state.divisor;
341
342 (remainder, digit.to_u8())
343 },
344 );
345
346 state.remainder = rem;
347 Some(digit)
348 })
349 .unwrap();
350
351 match digit {
352 Some(n) => {
353 state = match consumer(state, n)? {
354 Ok(state) => state,
355 Err(s) => return Ok(s),
356 };
357 }
358 None => unreachable!(),
359 };
360 }
361
362 Ok(state)
363}
364
365pub fn division_result_max_char_length<I>(dividend: &I, precision: usize) -> usize
381where
382 I: Clone + GenericInteger,
383{
384 let mut ptr: I = I::_1();
385 let mut len: usize = 0;
386
387 loop {
388 len += 1;
389
390 ptr = match I::_10r().map_or_else(|| ptr.checked_mul(&I::_10()), |_10| ptr.checked_mul(_10))
391 {
392 Some(n) => n,
393 None => break,
394 };
395
396 if ptr > *dividend {
397 break;
398 }
399 }
400
401 len + precision + usize::from(precision > 0)
402}
403
404#[inline]
431pub fn divide_to_string<I>(
432 dividend: I,
433 divisor: I,
434 precision: usize,
435 trail_zeroes: bool,
436) -> Result<String, DivisionError>
437where
438 I: Clone + GenericInteger,
439{
440 let mut result = String::with_capacity(division_result_max_char_length(÷nd, precision));
441
442 divide_to_writeable(&mut result, dividend, divisor, precision, trail_zeroes)?;
443
444 Ok(result)
445}
446
447#[inline]
474pub fn divide_to_ascii_vec<I>(
475 dividend: I,
476 divisor: I,
477 precision: usize,
478 trail_zeroes: bool,
479) -> Result<Vec<u8>, DivisionError>
480where
481 I: Clone + GenericInteger,
482{
483 const ZERO: u8 = 48u8;
484 const DOT: u8 = 46u8;
485
486 let mut result = Vec::with_capacity(division_result_max_char_length(÷nd, precision));
487
488 divide_to_callback(dividend, divisor, precision, trail_zeroes, |digit| {
489 if digit == 10u8 {
490 result.push(DOT);
491 } else {
492 result.push(ZERO + digit);
493 }
494 Ok(true)
495 })?;
496
497 Ok(result)
498}
499
500#[inline]
552pub fn divide_to_writeable<I>(
553 writeable: &mut dyn Write,
554 dividend: I,
555 divisor: I,
556 precision: usize,
557 trail_zeroes: bool,
558) -> Result<I, DivisionError>
559where
560 I: Clone + GenericInteger,
561{
562 divide_to_callback(dividend, divisor, precision, trail_zeroes, |digit| {
563 write_digit(writeable, digit)
564 })
565}
566
567pub fn divide_to_callback<I, C>(
597 dividend: I,
598 divisor: I,
599 mut precision: usize,
600 trail_zeroes: bool,
601 mut callback: C,
602) -> Result<I, DivisionError>
603where
604 C: FnMut(u8) -> Result<bool, DivisionError>,
605 I: Clone + GenericInteger,
606{
607 let mut keep_going = true;
608
609 let mut div_state = divide_integral(dividend, divisor, |digit: u8| match callback(digit) {
610 result @ Ok(false) => {
611 keep_going = false;
612 result
613 }
614 result => result,
615 })?;
616
617 if !keep_going {
618 return Ok(div_state.remainder);
619 }
620
621 if precision > 0 {
622 let mut dot = false;
623 let mut trailing_zeroes = 0;
624
625 if !div_state.remainder.is_zero() {
626 div_state = divide_rem(
627 div_state.remainder,
628 div_state.divisor,
629 |state, digit: u8| {
630 precision -= 1;
631
632 if digit == 0 {
633 trailing_zeroes += 1;
634 } else {
635 if !dot {
636 dot = true;
637
638 match callback(10u8) {
639 result @ Ok(false) => {
640 keep_going = false;
641 result
642 }
643 result => result,
644 }?;
645
646 if !keep_going {
647 return Ok(Err(state));
648 }
649 }
650
651 while trailing_zeroes > 0 {
652 trailing_zeroes -= 1;
653
654 match callback(0u8) {
655 result @ Ok(false) => {
656 keep_going = false;
657 result
658 }
659 result => result,
660 }?;
661
662 if !keep_going {
663 return Ok(Err(state));
664 }
665 }
666
667 match callback(digit) {
668 result @ Ok(false) => {
669 keep_going = false;
670 result
671 }
672 result => result,
673 }?;
674
675 if !keep_going {
676 return Ok(Err(state));
677 }
678 }
679
680 if precision > 0 {
681 Ok(Ok(state))
682 } else {
683 Ok(Err(state))
684 }
685 },
686 )?;
687 }
688
689 if keep_going && trail_zeroes {
690 if !dot {
691 match callback(10u8) {
692 result @ Ok(false) => {
693 keep_going = false;
694 result
695 }
696 result => result,
697 }?;
698
699 if !keep_going {
700 return Ok(div_state.remainder);
701 }
702 }
703
704 while trailing_zeroes > 0 {
705 trailing_zeroes -= 1;
706
707 match callback(0u8) {
708 result @ Ok(false) => {
709 keep_going = false;
710 result
711 }
712 result => result,
713 }?;
714
715 if !keep_going {
716 return Ok(div_state.remainder);
717 }
718 }
719
720 while precision > 0 {
721 precision -= 1;
722
723 match callback(0u8) {
724 result @ Ok(false) => {
725 keep_going = false;
726 result
727 }
728 result => result,
729 }?;
730
731 if !keep_going {
732 return Ok(div_state.remainder);
733 }
734 }
735 }
736 }
737
738 Ok(div_state.remainder)
739}
740
741pub fn write_digit(writeable: &mut dyn Write, digit: u8) -> Result<bool, DivisionError> {
762 if digit == 10u8 {
763 match writeable.write_char('.') {
764 Ok(_) => Ok(true),
765 Err(e) => Err(DivisionError::from(e)),
766 }
767 } else {
768 match writeable.write_fmt(format_args!("{}", digit)) {
769 Ok(_) => Ok(true),
770 Err(e) => Err(DivisionError::from(e)),
771 }
772 }
773}
774
775#[cfg(test)]
776mod tests {
777 use super::*;
778 use error::DivisionError;
779 use num::Zero;
780
781 #[cfg(feature = "with-bigint")]
784 use num::{bigint::BigUint, Num};
785
786 #[test]
787 fn test_division() {
788 const PRECISION: usize = 64;
789 let data: Vec<(u8, u8, &'static str, bool)> = vec![
790 (
791 1u8,
792 255u8,
793 "0.0039215686274509803921568627450980392156862745098039215686274509",
794 false,
795 ),
796 (
797 1u8,
798 254u8,
799 "0.0039370078740157480314960629921259842519685039370078740157480314",
800 false,
801 ),
802 (
803 1u8,
804 253u8,
805 "0.003952569169960474308300395256916996047430830039525691699604743",
806 false,
807 ),
808 (
809 1u8,
810 252u8,
811 "0.0039682539682539682539682539682539682539682539682539682539682539",
812 false,
813 ),
814 (
815 1u8,
816 251u8,
817 "0.0039840637450199203187250996015936254980079681274900398406374501",
818 false,
819 ),
820 (1u8, 250u8, "0.004", true),
821 (
822 1u8,
823 112u8,
824 "0.0089285714285714285714285714285714285714285714285714285714285714",
825 false,
826 ),
827 (
828 1u8,
829 111u8,
830 "0.009009009009009009009009009009009009009009009009009009009009009",
831 false,
832 ),
833 (
834 1u8,
835 96u8,
836 "0.0104166666666666666666666666666666666666666666666666666666666666",
837 false,
838 ),
839 (
840 1u8,
841 92u8,
842 "0.0108695652173913043478260869565217391304347826086956521739130434",
843 false,
844 ),
845 (
846 1u8,
847 91u8,
848 "0.0109890109890109890109890109890109890109890109890109890109890109",
849 false,
850 ),
851 (
852 1u8,
853 90u8,
854 "0.0111111111111111111111111111111111111111111111111111111111111111",
855 false,
856 ),
857 (
858 1u8,
859 9u8,
860 "0.1111111111111111111111111111111111111111111111111111111111111111",
861 false,
862 ),
863 (1u8, 8u8, "0.125", true),
864 (
865 1u8,
866 7u8,
867 "0.1428571428571428571428571428571428571428571428571428571428571428",
868 false,
869 ),
870 (
871 1u8,
872 6u8,
873 "0.1666666666666666666666666666666666666666666666666666666666666666",
874 false,
875 ),
876 (1u8, 5u8, "0.2", true),
877 (1u8, 4u8, "0.25", true),
878 (
879 1u8,
880 3u8,
881 "0.3333333333333333333333333333333333333333333333333333333333333333",
882 false,
883 ),
884 (1u8, 2u8, "0.5", true),
885 (1u8, 1u8, "1", true),
886 (
887 49u8,
888 255u8,
889 "0.192156862745098039215686274509803921568627450980392156862745098",
890 false,
891 ),
892 (
893 49u8,
894 254u8,
895 "0.1929133858267716535433070866141732283464566929133858267716535433",
896 false,
897 ),
898 (
899 49u8,
900 253u8,
901 "0.193675889328063241106719367588932806324110671936758893280632411",
902 false,
903 ),
904 (
905 49u8,
906 252u8,
907 "0.1944444444444444444444444444444444444444444444444444444444444444",
908 false,
909 ),
910 (
911 49u8,
912 251u8,
913 "0.1952191235059760956175298804780876494023904382470119521912350597",
914 false,
915 ),
916 (49u8, 250u8, "0.196", true),
917 (
918 49u8,
919 249u8,
920 "0.1967871485943775100401606425702811244979919678714859437751004016",
921 false,
922 ),
923 (
924 49u8,
925 248u8,
926 "0.1975806451612903225806451612903225806451612903225806451612903225",
927 false,
928 ),
929 (
930 49u8,
931 247u8,
932 "0.1983805668016194331983805668016194331983805668016194331983805668",
933 false,
934 ),
935 (
936 49u8,
937 246u8,
938 "0.1991869918699186991869918699186991869918699186991869918699186991",
939 false,
940 ),
941 (49u8, 245u8, "0.2", true),
942 (
943 49u8,
944 69u8,
945 "0.7101449275362318840579710144927536231884057971014492753623188405",
946 false,
947 ),
948 (
949 49u8,
950 68u8,
951 "0.7205882352941176470588235294117647058823529411764705882352941176",
952 false,
953 ),
954 (
955 49u8,
956 67u8,
957 "0.7313432835820895522388059701492537313432835820895522388059701492",
958 false,
959 ),
960 (
961 49u8,
962 66u8,
963 "0.7424242424242424242424242424242424242424242424242424242424242424",
964 false,
965 ),
966 (
967 49u8,
968 65u8,
969 "0.7538461538461538461538461538461538461538461538461538461538461538",
970 false,
971 ),
972 (49u8, 64u8, "0.765625", true),
973 (
974 49u8,
975 63u8,
976 "0.7777777777777777777777777777777777777777777777777777777777777777",
977 false,
978 ),
979 (
980 77u8,
981 255u8,
982 "0.3019607843137254901960784313725490196078431372549019607843137254",
983 false,
984 ),
985 (
986 77u8,
987 254u8,
988 "0.3031496062992125984251968503937007874015748031496062992125984251",
989 false,
990 ),
991 (
992 77u8,
993 253u8,
994 "0.3043478260869565217391304347826086956521739130434782608695652173",
995 false,
996 ),
997 (
998 77u8,
999 252u8,
1000 "0.3055555555555555555555555555555555555555555555555555555555555555",
1001 false,
1002 ),
1003 (
1004 77u8,
1005 251u8,
1006 "0.3067729083665338645418326693227091633466135458167330677290836653",
1007 false,
1008 ),
1009 (77u8, 250u8, "0.308", true),
1010 (
1011 77u8,
1012 249u8,
1013 "0.3092369477911646586345381526104417670682730923694779116465863453",
1014 false,
1015 ),
1016 (
1017 77u8,
1018 248u8,
1019 "0.3104838709677419354838709677419354838709677419354838709677419354",
1020 false,
1021 ),
1022 (
1023 77u8,
1024 231u8,
1025 "0.3333333333333333333333333333333333333333333333333333333333333333",
1026 false,
1027 ),
1028 (
1029 77u8,
1030 230u8,
1031 "0.3347826086956521739130434782608695652173913043478260869565217391",
1032 false,
1033 ),
1034 (
1035 77u8,
1036 229u8,
1037 "0.3362445414847161572052401746724890829694323144104803493449781659",
1038 false,
1039 ),
1040 (
1041 77u8,
1042 228u8,
1043 "0.3377192982456140350877192982456140350877192982456140350877192982",
1044 false,
1045 ),
1046 (
1047 77u8,
1048 227u8,
1049 "0.3392070484581497797356828193832599118942731277533039647577092511",
1050 false,
1051 ),
1052 (
1053 77u8,
1054 226u8,
1055 "0.3407079646017699115044247787610619469026548672566371681415929203",
1056 false,
1057 ),
1058 (
1059 77u8,
1060 225u8,
1061 "0.3422222222222222222222222222222222222222222222222222222222222222",
1062 false,
1063 ),
1064 (77u8, 224u8, "0.34375", true),
1065 (
1066 77u8,
1067 223u8,
1068 "0.3452914798206278026905829596412556053811659192825112107623318385",
1069 false,
1070 ),
1071 (
1072 77u8,
1073 222u8,
1074 "0.3468468468468468468468468468468468468468468468468468468468468468",
1075 false,
1076 ),
1077 (
1078 77u8,
1079 221u8,
1080 "0.3484162895927601809954751131221719457013574660633484162895927601",
1081 false,
1082 ),
1083 (77u8, 220u8, "0.35", true),
1084 ];
1085
1086 for i in data.iter() {
1087 assert_eq!(divide_to_string(i.0, i.1, PRECISION, false).unwrap(), i.2);
1088
1089 {
1090 let mut string: String = String::new();
1091 let remainder =
1092 divide_to_writeable(&mut string, i.0, i.1, PRECISION, false).unwrap();
1093
1094 assert_eq!(string, i.2);
1095 assert_eq!(remainder.is_zero(), i.3);
1096 }
1097 }
1098
1099 #[cfg(feature = "with-bigint")]
1100 {
1101 for i in data {
1102 assert_eq!(
1103 divide_to_string(BigUint::from(i.0), BigUint::from(i.1), PRECISION, false)
1104 .unwrap(),
1105 i.2
1106 );
1107 }
1108 }
1109 }
1110
1111 #[test]
1112 fn test_divide_to_string() {
1113 assert_eq!(divide_to_string(0, 5, 5, false).unwrap(), "0");
1114 assert_eq!(divide_to_string(0, 5, 5, true).unwrap(), "0.00000");
1115 assert_eq!(divide_to_string(30, 2, 5, false).unwrap(), "15");
1116 assert_eq!(divide_to_string(30, 2, 5, true).unwrap(), "15.00000");
1117 assert_eq!(divide_to_string(2, 4, 2, false).unwrap(), "0.5");
1118 assert_eq!(divide_to_string(2, 4, 2, true).unwrap(), "0.50");
1119 assert_eq!(divide_to_string(255u8, 3u8, 5, false).unwrap(), "85");
1120 assert_eq!(divide_to_string(255u8, 3u8, 5, true).unwrap(), "85.00000");
1121
1122 assert_eq!(divide_to_string(155u8, 253u8, 5, false).unwrap(), "0.61264");
1123 assert_eq!(divide_to_string(1u8, 2u8, 1, false).unwrap(), "0.5");
1124 assert_eq!(divide_to_string(1u8, 2u8, 1, true).unwrap(), "0.5");
1125
1126 assert_eq!(
1127 divide_to_string(1, 3, 28, false).unwrap(),
1128 "0.3333333333333333333333333333"
1129 );
1130 assert_eq!(
1131 divide_to_string(1, 3, 28, true).unwrap(),
1132 "0.3333333333333333333333333333"
1133 );
1134 assert_eq!(divide_to_string(806, 31, 0, false).unwrap(), "26");
1135 assert_eq!(divide_to_string(806, 31, 0, true).unwrap(), "26");
1136 assert_eq!(divide_to_string(807, 31, 4, false).unwrap(), "26.0322");
1137 assert_eq!(divide_to_string(807, 31, 4, true).unwrap(), "26.0322");
1138
1139 if let Err(DivisionError::DivisionByZero) = divide_to_string(1, 0, 1, false) {
1140 } else {
1141 assert!(false);
1142 };
1143
1144 if let Err(DivisionError::DivisionByZero) = divide_to_string(1, 0, 1, true) {
1145 } else {
1146 assert!(false);
1147 };
1148
1149 assert_eq!(divide_to_string(1, 10000, 2, false).unwrap(), "0");
1150 assert_eq!(divide_to_string(1, 10000, 2, true).unwrap(), "0.00");
1151
1152 #[cfg(feature = "with-bigint")]
1153 {
1154 let num = "820123456789012345678901234567890123456789";
1155 let den = "420420420420240240420240420240420420420";
1156 let result = "1950.7222222204153880534352079149419688493160244330759069204925259490806291881834407646199555744655166719234903156227406500953778757619920899563294795746797267246703798051247915744867884912121330007705286911209791422213223230426822190127666529437572025264829201539629594175021000386486667365851813562015885600393107707737453721144405603009059457352854387023006301508907770762997683254372534811586343569328131455924964081595076622200116354403760742833073621862325616259444084808295834752749082040590201012701034118255745516514972270054835928011374231619434684843847682844123336846713100440285930668493675706096464476187809105398269815519780303174023949885603320678109566772031394249633001137109155600514761384776616827086908396960584246277151426685095767130738996420461009015758184659365258827537226581854494195009714400547427050697946126012192691851549545189173091941689299722345297086508711845865506663262915436874050594522308464492248968916100678819937355384703664061966410613989688966690413319849627099468906113991173042101218";
1157
1158 let asrt1 = divide_to_string(
1159 BigUint::from_str_radix(num, 10).ok().unwrap(),
1160 BigUint::from_str_radix(den, 10).ok().unwrap(),
1161 1024,
1162 false,
1163 );
1164
1165 assert_eq!(&asrt1.ok().unwrap(), result);
1166
1167 let asrt1 = divide_to_string(
1168 BigUint::from_str_radix(num, 10).ok().unwrap(),
1169 BigUint::from_str_radix(den, 10).ok().unwrap(),
1170 1024,
1171 true,
1172 );
1173
1174 assert_eq!(&asrt1.ok().unwrap(), result);
1175 }
1176 }
1177
1178 #[test]
1179 fn test_divide_to_ascii_vec() {
1180 assert_eq!(divide_to_ascii_vec(0, 5, 5, false).unwrap(), vec![48]);
1181 assert_eq!(
1182 divide_to_ascii_vec(0, 5, 5, true).unwrap(),
1183 vec![48, 46, 48, 48, 48, 48, 48]
1184 );
1185 assert_eq!(divide_to_ascii_vec(30, 2, 5, false).unwrap(), vec![49, 53]);
1186 assert_eq!(
1187 divide_to_ascii_vec(2, 4, 2, false).unwrap(),
1188 vec![48, 46, 53]
1189 );
1190 assert_eq!(
1191 divide_to_ascii_vec(2, 4, 2, true).unwrap(),
1192 vec![48, 46, 53, 48]
1193 );
1194 assert_eq!(
1195 divide_to_ascii_vec(255u8, 3u8, 5, false).unwrap(),
1196 vec![56, 53]
1197 );
1198 assert_eq!(
1199 divide_to_ascii_vec(1000001u64, 10000u64, 3, false).unwrap(),
1200 vec![49, 48, 48]
1201 );
1202 assert_eq!(
1203 divide_to_ascii_vec(1000001u64, 10000u64, 3, true).unwrap(),
1204 vec![49, 48, 48, 46, 48, 48, 48]
1205 );
1206 }
1207
1208 #[test]
1209 fn test_divide_integral() {
1210 {
1211 let mut r1: [u8; 1] = [0; 1];
1212 let mut p1: usize = 0;
1213
1214 let mut r2: [u8; 2] = [0; 2];
1215 let mut p2: usize = 0;
1216
1217 let mut r3: [u8; 3] = [0; 3];
1218 let mut p3: usize = 0;
1219
1220 let rest1 = divide_integral(2, 4, |d| {
1221 r1[p1] = d;
1222 p1 += 1;
1223 Ok(true)
1224 });
1225
1226 assert_eq!(r1, [0]);
1227 assert_eq!(p1, 1);
1228 assert_eq!(rest1.unwrap(), DivisionState::new(2, 4));
1229
1230 let rest2 = divide_integral(82, 3, |d| {
1231 r2[p2] = d;
1232 p2 += 1;
1233 Ok(true)
1234 });
1235
1236 assert_eq!(r2, [2, 7]);
1237 assert_eq!(p2, 2);
1238 assert_eq!(rest2.unwrap(), DivisionState::new(1, 3));
1239
1240 let rest3 = divide_integral(2020, 4, |d| {
1241 r3[p3] = d;
1242 p3 += 1;
1243 Ok(true)
1244 });
1245
1246 assert_eq!(r3, [5, 0, 5]);
1247 assert_eq!(p3, 3);
1248 assert_eq!(rest3.unwrap(), DivisionState::new(0, 4));
1249 }
1250
1251 {
1252 let mut result = Vec::new();
1253 let rem = divide_integral(255u8, 3u8, |d| {
1254 result.push(d);
1255 Ok(true)
1256 });
1257
1258 assert_eq!(rem.ok(), Some(DivisionState::new(0, 3)));
1259 assert_eq!(result, vec![8, 5]);
1260 }
1261
1262 {
1263 let mut result = Vec::new();
1264 let rem = divide_integral(255u8, 3u8, |d| {
1265 result.push(d);
1266 Ok(false)
1267 });
1268
1269 assert_eq!(rem.ok(), Some(DivisionState::new(15, 3)));
1270 assert_eq!(result, vec![8]);
1271 }
1272 }
1273
1274 #[test]
1275 fn test_divide_rem() {
1276 let mut r1: [u8; 1] = [0; 1];
1277 let mut p1: usize = 0;
1278
1279 let mut r2: [u8; 2] = [0; 2];
1280 let mut p2: usize = 0;
1281
1282 let mut r3: [u8; 3] = [0; 3];
1283 let mut p3: usize = 0;
1284
1285 let mut rest1 = None;
1286 divide_rem(1, 3, |s, d| {
1287 r1[p1] = d;
1288 p1 += 1;
1289 rest1 = Some(s.remainder);
1290 Ok(Err(s))
1291 })
1292 .ok();
1293
1294 assert_eq!(r1, [3]);
1295 assert_eq!(p1, 1);
1296 assert_eq!(rest1, Some(1));
1297
1298 p1 = 0;
1299 let rest1 = divide_rem(1, 2, |s, d| {
1300 r1[p1] = d;
1301 p1 += 1;
1302 Ok(Ok(s))
1303 });
1304
1305 assert_eq!(r1, [5]);
1306 assert_eq!(p1, 1);
1307 assert_eq!(rest1.unwrap(), DivisionState::new(0, 2));
1308
1309 let rest2 = divide_rem(500, 2000, |s, d| {
1310 r2[p2] = d;
1311 p2 += 1;
1312 Ok(Ok(s))
1313 });
1314
1315 assert_eq!(r2, [2, 5]);
1316 assert_eq!(p2, 2);
1317 assert_eq!(rest2.unwrap(), DivisionState::new(0, 2000));
1318
1319 let rest3 = divide_rem(2, 1000, |s, d| {
1320 r3[p3] = d;
1321 p3 += 1;
1322 Ok(Ok(s))
1323 });
1324
1325 assert_eq!(r3, [0, 0, 2]);
1326 assert_eq!(p3, 3);
1327 assert_eq!(rest3.unwrap(), DivisionState::new(0, 1000));
1328
1329 p3 = 0;
1330 let rest3 = divide_rem(502, 1000, |s, d| {
1331 r3[p3] = d;
1332 p3 += 1;
1333 Ok(Ok(s))
1334 });
1335
1336 assert_eq!(r3, [5, 0, 2]);
1337 assert_eq!(p3, 3);
1338 assert_eq!(rest3.unwrap(), DivisionState::new(0, 1000));
1339 }
1340}