bignumbe_rs/
macros.rs

1pub mod test_macros {
2    #![cfg(test)]
3
4    macro_rules! assert_close_bignum {
5        ($lhs:expr, $rhs:expr) => {{
6            let (max, min) = if $rhs > $lhs {($rhs, $lhs)} else {($lhs, $rhs)};
7
8            if !max.fuzzy_eq(min, max.base.as_number() as u64) {
9                panic!("assertion failed: 
10    sig:
11    0x{:x} 
12    vs
13    0x{:x}
14
15    exp:
16    {}
17    vs
18    {}
19
20    base:
21    {}
22
23    min_sig:
24    0x{:x}
25    max_sig:
26    0x{:x}
27    min_exp:
28    {}
29    max_exp:
30    {}
31    "
32            , $lhs.sig,
33            $rhs.sig, $lhs.exp, $rhs.exp, $lhs.base.as_number(), $lhs.base.sig_range().min(), $lhs.base.sig_range().max(), $lhs.base.exp_range().min(), $lhs.base.exp_range().max());
34            }
35        }};
36    }
37
38    // For better error messages
39    macro_rules! assert_eq_bignum {
40        ($lhs:expr, $rhs:expr) => {{
41            let (lhs, rhs) = ($lhs, $rhs);
42
43            if lhs != rhs {
44                panic!("assertion failed: 
45    sig:
46    0x{:x} 
47    vs
48    0x{:x}
49
50    exp:
51    {}
52    vs
53    {}
54
55    base:
56    {}
57
58    min_sig:
59    0x{:x}
60    max_sig:
61    0x{:x}
62    min_exp:
63    {}
64    max_exp:
65    {}
66    "
67            , lhs.sig,
68            rhs.sig, lhs.exp, rhs.exp, lhs.base.as_number(), lhs.base.sig_range().min(), lhs.base.sig_range().max(), lhs.base.exp_range().min(), lhs.base.exp_range().max());
69            }
70        }};
71    }
72
73    macro_rules! test_add {
74        ($base:ident) => {{
75            type BigNum = BigNumBase<$base>;
76            let SigRange(min_sig, max_sig) = $base::calculate_ranges().1;
77
78            $crate::macros::test_macros::assert_eq_bignum!(
79                BigNum::new(min_sig, 1) + $base::NUMBER as u64,
80                BigNum::new_raw(min_sig + 1, 1)
81            );
82            $crate::macros::test_macros::assert_eq_bignum!(
83                BigNum::new(max_sig, 1) + $base::NUMBER as u64,
84                BigNum::new_raw(min_sig, 2)
85            );
86            $crate::macros::test_macros::assert_eq_bignum!(
87                BigNum::from(min_sig) + BigNum::from(min_sig),
88                BigNum::from(min_sig * 2)
89            );
90            $crate::macros::test_macros::assert_eq_bignum!(
91                BigNum::new(max_sig, 142) + BigNum::new(min_sig, 140),
92                BigNum::new(min_sig + $base::rshift(max_sig, 4), 143)
93            );
94            // If the math is confusing look at the example for Decimal:
95            // `9_999_999_999_999_999_999 + 9_999_999_999_999_999_999` is
96            // `19_999_999_999_999_999_998`, which normalizes to
97            // `BigNum{sig: 1_999_999_999_999_999_999, exp: 1}`
98            $crate::macros::test_macros::assert_eq_bignum!(
99                BigNum::new(max_sig, 0) + BigNum::new(max_sig, 0),
100                BigNum::new(2 * min_sig - 1, 1)
101            );
102        }};
103    }
104
105    macro_rules! test_sub {
106        ($base:ident) => {{
107            type BigNum = BigNumBase<$base>;
108            let SigRange(min_sig, max_sig) = $base::calculate_ranges().1;
109
110            $crate::macros::test_macros::assert_eq_bignum!(
111                BigNum::new(min_sig, 1) - $base::NUMBER as u64,
112                BigNum::new_raw(max_sig - ($base::NUMBER as u64 - 1), 0)
113            );
114            $crate::macros::test_macros::assert_eq_bignum!(
115                BigNum::new(max_sig, 1) - max_sig,
116                BigNum::new_raw(max_sig - max_sig / $base::NUMBER as u64, 1)
117            );
118            $crate::macros::test_macros::assert_eq_bignum!(
119                BigNum::new(12341098709128730491, 11234) - BigNum::new(12341098709128730491, 11234),
120                BigNum::from(0)
121            );
122            $crate::macros::test_macros::assert_eq_bignum!(
123                BigNum::from(max_sig) - BigNum::from(max_sig),
124                BigNum::from(0)
125            );
126        }};
127    }
128
129    macro_rules! test_mul {
130        ($base:ident) => {{
131            type BigNum = BigNumBase<$base>;
132            let SigRange(min_sig, max_sig) = $base::calculate_ranges().1;
133            let ExpRange(min_exp, max_exp) = $base::calculate_ranges().0;
134
135            $crate::macros::test_macros::assert_eq_bignum!(
136                BigNum::new(min_sig, 1) * $base::NUMBER as u64,
137                BigNum::new(min_sig, 2)
138            );
139            $crate::macros::test_macros::assert_eq_bignum!(
140                BigNum::new(max_sig, 1) * max_sig,
141                BigNum::new_raw(max_sig - 1, max_exp as u64 + 1 + 0)
142            );
143            $crate::macros::test_macros::assert_eq_bignum!(
144                BigNum::new(max_sig, 112341234) * BigNum::new(max_sig, 12341),
145                BigNum::new_raw(max_sig - 1, max_exp as u64 + 112341234 + 12341)
146            );
147            $crate::macros::test_macros::assert_eq_bignum!(
148                BigNum::new(min_sig, 1) * BigNum::new(min_sig + 1, 1241234),
149                BigNum::new(min_sig + 1, min_exp as u64 + 1 + 1241234)
150            );
151            $crate::macros::test_macros::assert_eq_bignum!(
152                BigNum::new(min_sig, 1) * BigNum::new(max_sig, 1241234),
153                BigNum::new(max_sig, min_exp as u64 + 1 + 1241234)
154            );
155        }};
156    }
157
158    macro_rules! test_div {
159        ($base:ident) => {{
160            type BigNum = BigNumBase<$base>;
161            let SigRange(min_sig, max_sig) = $base::calculate_ranges().1;
162            let ExpRange(min_exp, _) = $base::calculate_ranges().0;
163
164            $crate::macros::test_macros::assert_eq_bignum!(
165                BigNum::new(min_sig, 2) / BigNum::new(min_sig, 1),
166                BigNum::new($base::NUMBER as u64, 0)
167            );
168            $crate::macros::test_macros::assert_eq_bignum!(
169                BigNum::new_raw(max_sig, 1) / BigNum::new(max_sig, 1),
170                BigNum::from(1)
171            );
172            $crate::macros::test_macros::assert_eq_bignum!(
173                BigNum::new_raw(max_sig, 1) / BigNum::new(max_sig, 2),
174                BigNum::from(0)
175            );
176            $crate::macros::test_macros::assert_eq_bignum!(
177                BigNum::new_raw(min_sig, 1) / BigNum::new(min_sig + 1, 1),
178                BigNum::from(0)
179            );
180            $crate::macros::test_macros::assert_eq_bignum!(
181                BigNum::new_raw(max_sig, 5) / BigNum::new(max_sig, 1),
182                BigNum::new($base::pow(4), 0)
183            );
184            // The total magnitude for the lhs is (min_exp + min_exp + 112341234 + 12341), and
185            // the total magnitude for the rhs is (min_exp + 112341234), so we expect that the
186            // resulting magnitude will be mag(lhs) - mag(rhs) = min_exp + 12341, as shown
187            $crate::macros::test_macros::assert_eq_bignum!(
188                BigNum::new_raw(max_sig, min_exp as u64 + 112341234 + 12341)
189                    / BigNum::new(min_sig, 112341234),
190                BigNum::new(max_sig, 12341)
191            );
192            $crate::macros::test_macros::assert_eq_bignum!(
193                BigNum::new(min_sig, 12341234) / BigNum::new(min_sig, 1241234),
194                BigNum::new(min_sig, 12341234 - 1241234 - min_exp as u64)
195            );
196            $crate::macros::test_macros::assert_eq_bignum!(
197                BigNum::new(min_sig, 1) * BigNum::new(max_sig, 1241234),
198                BigNum::new(max_sig, min_exp as u64 + 1 + 1241234)
199            );
200        }};
201    }
202
203    macro_rules! test_succ {
204        ($base:ident) => {{
205            use $crate::traits::Succ;
206            type BigNum = BigNumBase<$base>;
207            let SigRange(min_sig, max_sig) = $base::calculate_ranges().1;
208
209            $crate::macros::test_macros::assert_eq_bignum!(
210                BigNum::new(0, 0).succ(),
211                BigNum::new(1, 0)
212            );
213            $crate::macros::test_macros::assert_eq_bignum!(
214                BigNum::new(max_sig, 0).succ(),
215                BigNum::new(min_sig, 1)
216            );
217            $crate::macros::test_macros::assert_eq_bignum!(
218                BigNum::new(max_sig, 1).succ(),
219                BigNum::new(min_sig, 2)
220            );
221            $crate::macros::test_macros::assert_eq_bignum!(
222                BigNum::new(max_sig, 2143124).succ(),
223                BigNum::new(min_sig, 2143125)
224            );
225        }};
226    }
227
228    macro_rules! test_pred {
229        ($base:ident) => {{
230            use $crate::traits::Pred;
231            type BigNum = BigNumBase<$base>;
232            let SigRange(min_sig, max_sig) = $base::calculate_ranges().1;
233
234            $crate::macros::test_macros::assert_eq_bignum!(
235                BigNum::new(1, 0).pred(),
236                BigNum::new(0, 0)
237            );
238            $crate::macros::test_macros::assert_eq_bignum!(
239                BigNum::new(min_sig, 1).pred(),
240                BigNum::new(max_sig, 0)
241            );
242            $crate::macros::test_macros::assert_eq_bignum!(
243                BigNum::new(min_sig, 2).pred(),
244                BigNum::new(max_sig, 1)
245            );
246        }};
247    }
248
249    macro_rules! test_shl {
250        ($base:ident) => {{
251            type BigNum = BigNumBase<$base>;
252            let SigRange(min_sig, max_sig) = $base::calculate_ranges().1;
253
254            $crate::macros::test_macros::assert_eq_bignum!(
255                BigNum::new(124, 0) << 1,
256                BigNum::new(124 * $base::NUMBER as u64, 0)
257            );
258            $crate::macros::test_macros::assert_eq_bignum!(
259                BigNum::new(124, 0) << 2,
260                BigNum::new(124 * ($base::NUMBER as u64).pow(2), 0)
261            );
262            $crate::macros::test_macros::assert_eq_bignum!(
263                BigNum::new(min_sig, 1) << 1,
264                BigNum::new(min_sig, 2)
265            );
266            $crate::macros::test_macros::assert_eq_bignum!(
267                BigNum::new(min_sig, 2) << 1,
268                BigNum::new(min_sig, 3)
269            );
270            $crate::macros::test_macros::assert_eq_bignum!(
271                BigNum::new(min_sig, 100) << 100,
272                BigNum::new(min_sig, 200)
273            );
274            $crate::macros::test_macros::assert_eq_bignum!(
275                BigNum::new(max_sig, 3) << 4,
276                BigNum::new(max_sig, 7)
277            );
278            $crate::macros::test_macros::assert_eq_bignum!(
279                BigNum::new(max_sig, 23) << 1243,
280                BigNum::new(max_sig, 1266)
281            );
282        }};
283    }
284
285    macro_rules! test_shr {
286        ($base:ident) => {{
287            type BigNum = BigNumBase<$base>;
288            let SigRange(min_sig, max_sig) = $base::calculate_ranges().1;
289
290            $crate::macros::test_macros::assert_eq_bignum!(
291                BigNum::new(12412341324, 0) >> 1,
292                BigNum::new(12412341324 / $base::NUMBER as u64, 0)
293            );
294            $crate::macros::test_macros::assert_eq_bignum!(
295                BigNum::new(12412341324, 0) >> 2,
296                BigNum::new(12412341324 / ($base::NUMBER as u64).pow(2), 0)
297            );
298            $crate::macros::test_macros::assert_eq_bignum!(
299                BigNum::new(min_sig, 1) >> 1,
300                BigNum::new(min_sig, 0)
301            );
302            $crate::macros::test_macros::assert_eq_bignum!(
303                BigNum::new(min_sig, 2) >> 1,
304                BigNum::new(min_sig, 1)
305            );
306            $crate::macros::test_macros::assert_eq_bignum!(
307                BigNum::new(min_sig, 100) >> 102,
308                BigNum::new(min_sig / ($base::NUMBER as u64).pow(2), 0)
309            );
310            $crate::macros::test_macros::assert_eq_bignum!(
311                BigNum::new(max_sig, 3) >> 4,
312                BigNum::new(max_sig / $base::NUMBER as u64, 0)
313            );
314            $crate::macros::test_macros::assert_eq_bignum!(
315                BigNum::new(max_sig, 1266) >> 1243,
316                BigNum::new(max_sig, 23)
317            );
318        }};
319    }
320
321    macro_rules! test_relations {
322        ($base:ident) => {{
323            use rand::{
324                distributions::{Distribution, Uniform},
325                thread_rng,
326            };
327            use $crate::traits::{Pred, Succ};
328
329            type BigNum = BigNumBase<$base>;
330            let base = $base::NUMBER as u64;
331
332            let dist: Uniform<BigNum> = Uniform::new(BigNum::from(0), BigNum::new(1, u64::MAX / 2));
333            let rng = &mut thread_rng();
334            let nums = dist.sample_iter(rng).take(100);
335
336            for n in nums {
337                $crate::macros::test_macros::assert_eq_bignum!(n + n, n * 2);
338                $crate::macros::test_macros::assert_close_bignum!(
339                    (0u64..base).fold(BigNum::from(0), |acc, _| acc + n),
340                    n * base
341                );
342                $crate::macros::test_macros::assert_eq_bignum!(base * n + base * n, 2 * base * n);
343                $crate::macros::test_macros::assert_eq_bignum!(n / base / base, n / (base * base));
344                $crate::macros::test_macros::assert_eq_bignum!(n * 0, n / (n.succ()));
345                $crate::macros::test_macros::assert_eq_bignum!(n + 0, n / 1);
346                $crate::macros::test_macros::assert_eq_bignum!(n / n, BigNum::from(1));
347                $crate::macros::test_macros::assert_eq_bignum!(n << 3, n * base.pow(3));
348                $crate::macros::test_macros::assert_eq_bignum!(n >> 3, n / base.pow(3));
349                $crate::macros::test_macros::assert_eq_bignum!(n.succ().pred(), n);
350                $crate::macros::test_macros::assert_eq_bignum!(n.pred().succ(), n);
351            }
352        }};
353    }
354
355    macro_rules! test_sum {
356        ($base:ident) => {{
357            type BigNum = BigNumBase<$base>;
358            let base = $base::NUMBER as u64;
359
360            let a: [BigNum; 10] = [BigNum::from(base); 10];
361            let b: [BigNum; 10] = [BigNum::from(1); 10];
362
363            $crate::macros::test_macros::assert_eq_bignum!(
364                BigNum::from(base * 10),
365                a.into_iter().sum::<BigNum>()
366            );
367            $crate::macros::test_macros::assert_eq_bignum!(
368                BigNum::from(10),
369                b.into_iter().sum::<BigNum>()
370            );
371        }};
372    }
373
374    macro_rules! test_prod {
375        ($base:ident) => {{
376            type BigNum = BigNumBase<$base>;
377            let base = $base::NUMBER as u64;
378            let min_sig = $base::calculate_ranges().1.min();
379            let min_exp = $base::calculate_ranges().0.min();
380
381            let a: [BigNum; 10] = [BigNum::from(base); 10];
382            let b: [BigNum; 10] = [BigNum::from(1); 10];
383            let c: [BigNum; 10] = [BigNum::from(min_sig); 10];
384
385            $crate::macros::test_macros::assert_eq_bignum!(
386                BigNum::new(1, 10),
387                a.into_iter().product::<BigNum>()
388            );
389            $crate::macros::test_macros::assert_eq_bignum!(
390                BigNum::from(1),
391                b.into_iter().product::<BigNum>()
392            );
393            $crate::macros::test_macros::assert_eq_bignum!(
394                BigNum::new(1, min_exp as u64 * 10),
395                c.into_iter().product::<BigNum>()
396            );
397        }};
398    }
399
400    // Runs some non-base specific tests
401    macro_rules! test_base {
402        ($base:ident) => {{
403            crate::macros::test_macros::test_add!($base);
404            crate::macros::test_macros::test_sub!($base);
405            crate::macros::test_macros::test_mul!($base);
406            crate::macros::test_macros::test_div!($base);
407            crate::macros::test_macros::test_succ!($base);
408            crate::macros::test_macros::test_pred!($base);
409            crate::macros::test_macros::test_shl!($base);
410            crate::macros::test_macros::test_shr!($base);
411            crate::macros::test_macros::test_relations!($base);
412            crate::macros::test_macros::test_sum!($base);
413            crate::macros::test_macros::test_prod!($base);
414        }};
415    }
416
417    macro_rules! create_and_test_base {
418        ($base:ident, $num:literal) => {
419            $crate::create_default_base!($base, $num);
420            test_base!($base);
421        };
422    }
423
424    pub(crate) use assert_close_bignum;
425    pub(crate) use assert_eq_bignum;
426
427    pub(crate) use create_and_test_base;
428    pub(crate) use test_base;
429
430    pub(crate) use test_add;
431    pub(crate) use test_div;
432    pub(crate) use test_mul;
433    pub(crate) use test_pred;
434    pub(crate) use test_prod;
435    pub(crate) use test_relations;
436    pub(crate) use test_shl;
437    pub(crate) use test_shr;
438    pub(crate) use test_sub;
439    pub(crate) use test_succ;
440    pub(crate) use test_sum;
441}
442
443macro_rules! impl_for_types {
444    ($($ty:ty),+) => {
445        $(
446            impl<T> From<$ty> for $crate::BigNumBase<T> where T: $crate::Base {
447                fn from(value: $ty) -> Self {
448                    Self::new(value as u64, 0)
449                }
450            }
451
452            impl<T> std::ops::Add<$ty> for $crate::BigNumBase<T> where T: $crate::Base {
453                type Output = Self;
454
455                fn add(self, rhs: $ty) -> Self::Output {
456                    self + $crate::BigNumBase::from(rhs)
457                }
458            }
459
460            impl<T> std::ops::Add<$crate::BigNumBase<T>> for $ty where T: $crate::Base {
461                type Output = $crate::BigNumBase<T>;
462
463                fn add(self, rhs: $crate::BigNumBase<T>) -> Self::Output {
464                    rhs + $crate::BigNumBase::from(self)
465                }
466            }
467
468            impl<T> std::ops::AddAssign<$ty> for $crate::BigNumBase<T> where T: $crate::Base {
469                fn add_assign(&mut self, rhs: $ty) {
470                    *self = *self + $crate::BigNumBase::from(rhs);
471                }
472            }
473
474            impl<T> std::ops::Sub<$ty> for $crate::BigNumBase<T> where T: $crate::Base {
475                type Output = Self;
476
477                fn sub(self, rhs: $ty) -> Self::Output {
478                    self - $crate::BigNumBase::from(rhs)
479                }
480            }
481
482            impl<T> std::ops::Sub<$crate::BigNumBase<T>> for $ty where T: $crate::Base {
483                type Output = $crate::BigNumBase<T>;
484
485                fn sub(self, rhs: $crate::BigNumBase<T>) -> Self::Output {
486                    $crate::BigNumBase::from(self) - rhs
487                }
488            }
489
490            impl<T> std::ops::SubAssign<$ty> for $crate::BigNumBase<T> where T: $crate::Base {
491                fn sub_assign(&mut self, rhs: $ty) {
492                    *self = *self - $crate::BigNumBase::from(rhs);
493                }
494            }
495
496            impl<T> std::ops::Mul<$ty> for $crate::BigNumBase<T> where T: $crate::Base {
497                type Output = Self;
498
499                fn mul(self, rhs: $ty) -> Self::Output {
500                    self * $crate::BigNumBase::from(rhs)
501                }
502            }
503
504            impl<T> std::ops::Mul<$crate::BigNumBase<T>> for $ty where T: $crate::Base{
505                type Output = $crate::BigNumBase<T>;
506
507                fn mul(self, rhs: $crate::BigNumBase<T>) -> Self::Output {
508                    $crate::BigNumBase::from(self) * rhs
509                }
510            }
511
512            impl<T> std::ops::MulAssign<$ty> for $crate::BigNumBase<T> where T: $crate::Base {
513                fn mul_assign(&mut self, rhs: $ty){
514                    *self = *self * $crate::BigNumBase::from(rhs);
515                }
516            }
517
518            impl<T> std::ops::Div<$ty> for $crate::BigNumBase<T> where T: $crate::Base {
519                type Output = Self;
520
521                fn div(self, rhs: $ty) -> Self::Output {
522                    self / $crate::BigNumBase::from(rhs)
523                }
524            }
525
526            impl<T> std::ops::Div<$crate::BigNumBase<T>> for $ty where T: $crate::Base{
527                type Output = $crate::BigNumBase<T>;
528
529                fn div(self, rhs: $crate::BigNumBase<T>) -> Self::Output {
530                    $crate::BigNumBase::from(self) / rhs
531                }
532            }
533
534            impl<T> std::ops::DivAssign<$ty> for $crate::BigNumBase<T> where T: $crate::Base {
535                fn div_assign(&mut self, rhs: $ty){
536                    *self = *self / $crate::BigNumBase::from(rhs);
537                }
538            }
539        )+
540    };
541}
542impl_for_types!(u64);
543
544/// This macro creates a default `Base` implementation with a given name and number.
545///
546/// # Examples
547/// ```
548/// use bignumbe_rs::{create_default_base, BigNumBase};
549///
550/// create_default_base!(Base83, 83);
551/// type BigNum = BigNumBase<Base83>;
552///
553/// let bn1 = BigNum::from(83);
554///
555/// assert_eq!(bn1 >> 1, BigNum::from(1));
556/// ```
557#[macro_export]
558macro_rules! create_default_base {
559    ($name:ident, $num:literal) => {
560        #[derive(Debug, Clone, Copy)]
561        pub struct $name {
562            pub exp_range: $crate::ExpRange,
563            pub sig_range: $crate::SigRange,
564        }
565
566        impl $crate::Base for $name {
567            const NUMBER: u16 = $num;
568
569            fn new() -> Self {
570                let (exp_range, sig_range) = Self::calculate_ranges();
571                Self {
572                    exp_range,
573                    sig_range,
574                }
575            }
576
577            fn exp_range(&self) -> $crate::ExpRange {
578                self.exp_range
579            }
580
581            fn sig_range(&self) -> $crate::SigRange {
582                self.sig_range
583            }
584        }
585    };
586}
587
588#[cfg(test)]
589mod tests {
590    use crate::{
591        macros::test_macros::{create_and_test_base, test_base},
592        Base, BigNumBase,
593    };
594
595    #[test]
596    fn default_base_test() {
597        create_default_base!(Base7, 7);
598
599        type BigNum = BigNumBase<Base7>;
600
601        assert_eq!(BigNum::new(150, 2), BigNum::new_raw(150 * 49, 0));
602        assert_eq!(
603            BigNum::new(Base7::calculate_ranges().1 .1, 2) + BigNum::new(1, 2),
604            BigNum::new_raw(Base7::calculate_ranges().1 .0, 3)
605        );
606
607        assert_eq!(
608            BigNum::new(Base7::calculate_ranges().1 .1, 3) + BigNum::new(1, 2),
609            BigNum::new_raw(Base7::calculate_ranges().1 .1, 3)
610        );
611        assert_eq!(BigNum::new(u64::MAX, 0), BigNum::new(u64::MAX / 7, 1))
612    }
613
614    #[test]
615    fn test_many_bases() {
616        use crate::{Base, BigNumBase, Decimal, ExpRange, Octal, SigRange};
617        // Not doing Binary or Hex since these tests assume max_sig + 1 fits in u64
618        create_and_test_base!(Base61, 61);
619        create_and_test_base!(Base11142, 11142);
620        create_and_test_base!(Base942, 942);
621        create_and_test_base!(Base3292, 3292);
622        create_and_test_base!(Base1234, 1234);
623        create_and_test_base!(Base5678, 5678);
624        create_and_test_base!(Base9101, 9101);
625        create_and_test_base!(Base2345, 2345);
626        create_and_test_base!(Base6789, 6789);
627        create_and_test_base!(Base1112, 1112);
628        create_and_test_base!(Base3456, 3456);
629        create_and_test_base!(Base7890, 7890);
630        create_and_test_base!(Base1357, 1357);
631        create_and_test_base!(Base2468, 2468);
632        create_and_test_base!(Base65535, 65535);
633        create_and_test_base!(Ternary, 3);
634
635        test_base!(Octal);
636        test_base!(Decimal);
637    }
638
639    #[test]
640    #[cfg(feature = "macro")]
641    fn test_many_efficient_bases() {
642        use crate::{Base, BigNumBase, Decimal, ExpRange, Octal, SigRange};
643        use bignum_proc_macro::create_efficient_base;
644        create_efficient_base!(61);
645        create_efficient_base!(11142);
646        create_efficient_base!(942);
647        create_efficient_base!(3292);
648        create_efficient_base!(1234);
649        create_efficient_base!(5678);
650        create_efficient_base!(9101);
651        create_efficient_base!(2345);
652        create_efficient_base!(6789);
653        create_efficient_base!(1112);
654        create_efficient_base!(3456);
655        create_efficient_base!(7890);
656        create_efficient_base!(1357);
657        create_efficient_base!(2468);
658        create_efficient_base!(65535);
659        create_efficient_base!(3);
660
661        test_base!(__Base61);
662        test_base!(__Base11142);
663        test_base!(__Base942);
664        test_base!(__Base3292);
665        test_base!(__Base1234);
666        test_base!(__Base5678);
667        test_base!(__Base9101);
668        test_base!(__Base2345);
669        test_base!(__Base6789);
670        test_base!(__Base1112);
671        test_base!(__Base3456);
672        test_base!(__Base7890);
673        test_base!(__Base1357);
674        test_base!(__Base2468);
675        test_base!(__Base65535);
676        test_base!(__Base3);
677
678        test_base!(Octal);
679        test_base!(Decimal);
680    }
681}