// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use itertools::Itertools; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::digits::general_digits::unsigned_to_digits_asc_naive; use malachite_base::num::conversion::traits::{Digits, ExactFrom, SaturatingFrom, WrappingFrom}; use malachite_base::test_util::generators::{ unsigned_gen, unsigned_gen_var_4, unsigned_pair_gen_var_6, }; use std::panic::catch_unwind; #[test] pub fn test_to_digits_asc() { fn test + PrimitiveUnsigned, U: PrimitiveUnsigned>(x: T, base: U, out: &[U]) { assert_eq!(x.to_digits_asc(&base), out); } test::(0, 64, &[]); test::(2, 64, &[2]); test::(123, 8, &[3, 7, 1]); test::(1000000, 256, &[64, 66, 15]); test::(1000000, 256, &[64, 66, 15]); test::(1000, 2, &[0, 0, 0, 1, 0, 1, 1, 1, 1, 1]); test::(0, 3, &[]); test::(2, 3, &[2]); test::(123456, 3, &[0, 1, 1, 0, 0, 1, 1, 2, 0, 0, 2]); test::(123456, 10, &[6, 5, 4, 3, 2, 1]); test::(123456, 100, &[56, 34, 12]); test::(123456, 123, &[87, 19, 8]); } fn to_digits_asc_fail_helper + PrimitiveUnsigned, U: PrimitiveUnsigned>() { assert_panic!(T::exact_from(100).to_digits_asc(&U::ZERO)); assert_panic!(T::exact_from(100).to_digits_asc(&U::ONE)); if T::WIDTH < U::WIDTH { assert_panic!(T::exact_from(100).to_digits_asc(&U::power_of_2(T::WIDTH))); } } #[test] fn to_digits_asc_fail() { apply_fn_to_unsigneds_and_unsigneds!(to_digits_asc_fail_helper); } #[test] pub fn test_to_digits_desc() { fn test + PrimitiveUnsigned, U: PrimitiveUnsigned>(x: T, base: U, out: &[U]) { assert_eq!(x.to_digits_desc(&base), out); } test::(0, 64, &[]); test::(2, 64, &[2]); test::(123, 8, &[1, 7, 3]); test::(1000000, 256, &[15, 66, 64]); test::(1000000, 256, &[15, 66, 64]); test::(1000, 2, &[1, 1, 1, 1, 1, 0, 1, 0, 0, 0]); test::(0, 3, &[]); test::(2, 3, &[2]); test::(123456, 3, &[2, 0, 0, 2, 1, 1, 0, 0, 1, 1, 0]); test::(123456, 10, &[1, 2, 3, 4, 5, 6]); test::(123456, 100, &[12, 34, 56]); test::(123456, 123, &[8, 19, 87]); } fn to_digits_desc_fail_helper + PrimitiveUnsigned, U: PrimitiveUnsigned>() { assert_panic!(T::exact_from(100).to_digits_desc(&U::ZERO)); assert_panic!(T::exact_from(100).to_digits_desc(&U::ONE)); if T::WIDTH < U::WIDTH { assert_panic!(T::exact_from(100).to_digits_desc(&U::power_of_2(T::WIDTH))); } } #[test] fn to_digits_desc_fail() { apply_fn_to_unsigneds_and_unsigneds!(to_digits_desc_fail_helper); } fn to_digits_asc_helper< T: Digits + ExactFrom + PrimitiveUnsigned, U: PrimitiveUnsigned + SaturatingFrom + WrappingFrom, >() { unsigned_pair_gen_var_6::().test_properties(|(u, base)| { let digits = u.to_digits_asc(&base); assert_eq!(unsigned_to_digits_asc_naive(&u, base), digits); assert_eq!( T::from_digits_asc(&base, digits.iter().copied()).unwrap(), u ); if u != T::ZERO { assert_ne!(*digits.last().unwrap(), U::ZERO); } assert_eq!( digits.iter().copied().rev().collect_vec(), u.to_digits_desc(&base) ); if u != T::ZERO { assert_eq!( u64::exact_from(digits.len()), u.floor_log_base(T::exact_from(base)) + 1 ); } assert!(digits.iter().all(|&digit| digit <= base)); }); unsigned_gen::().test_properties(|u| { assert_eq!( u.to_digits_asc(&U::TWO) .into_iter() .map(|digit| digit == U::ONE) .collect_vec(), u.to_bits_asc() ); }); unsigned_gen_var_4::().test_properties(|base| { assert!(T::ZERO.to_digits_asc(&base).is_empty()); }); } #[test] fn to_digits_asc_properties() { apply_fn_to_unsigneds_and_unsigneds!(to_digits_asc_helper); } fn to_digits_desc_helper< T: Digits + ExactFrom + PrimitiveUnsigned, U: PrimitiveUnsigned + SaturatingFrom, >() { unsigned_pair_gen_var_6::().test_properties(|(u, base)| { let digits = u.to_digits_desc(&base); assert_eq!( T::from_digits_desc(&base, digits.iter().copied()).unwrap(), u ); if u != T::ZERO { assert_ne!(digits[0], U::ZERO); } assert_eq!( digits.iter().copied().rev().collect_vec(), u.to_digits_asc(&base) ); if u != T::ZERO { assert_eq!( u64::exact_from(digits.len()), u.floor_log_base(T::exact_from(base)) + 1 ); } assert!(digits.iter().all(|&digit| digit <= base)); }); unsigned_gen::().test_properties(|u| { assert_eq!( u.to_digits_desc(&U::TWO) .into_iter() .map(|digit| digit == U::ONE) .collect_vec(), u.to_bits_desc() ); }); unsigned_gen_var_4::().test_properties(|base| { assert!(T::ZERO.to_digits_desc(&base).is_empty()); }); } #[test] fn to_digits_desc_properties() { apply_fn_to_unsigneds_and_unsigneds!(to_digits_desc_helper); }