// 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 malachite_base::num::basic::traits::Zero; use malachite_base::num::conversion::traits::PowerOf2Digits; use malachite_base::num::logic::traits::LowMask; use malachite_base::rational_sequences::RationalSequence; use malachite_base::vecs::vec_from_str; use malachite_nz::natural::Natural; use malachite_nz::test_util::generators::{ large_type_gen_var_23, natural_vec_unsigned_pair_gen_var_1, }; use malachite_q::Rational; #[test] fn test_from_power_of_2_digits() { let test = |log_base, before: &str, after_nr: &str, after_r: &str, out: &str| { let before: Vec = vec_from_str(before).unwrap(); let after_nr: Vec = vec_from_str(after_nr).unwrap(); let after_r: Vec = vec_from_str(after_r).unwrap(); let x = Rational::from_power_of_2_digits_ref( log_base, &before, &RationalSequence::from_slices(&after_nr, &after_r), ); assert!(x.is_valid()); assert_eq!(x.to_string(), out); assert_eq!( Rational::from_power_of_2_digits( log_base, before, RationalSequence::from_vecs(after_nr, after_r) ), x ); }; test(1, "[]", "[]", "[]", "0"); test(1, "[]", "[0, 0]", "[0]", "0"); test(10, "[]", "[]", "[]", "0"); test(1, "[1]", "[]", "[]", "1"); test(10, "[1]", "[]", "[]", "1"); test(1, "[]", "[]", "[1]", "1"); test(1, "[]", "[1]", "[]", "1/2"); test(10, "[]", "[512]", "[]", "1/2"); test(1, "[]", "[]", "[0, 1]", "1/3"); test(10, "[]", "[]", "[341]", "1/3"); test(1, "[1]", "[0]", "[0, 1]", "7/6"); test(10, "[1]", "[170]", "[682]", "7/6"); test(1, "[1, 1]", "[]", "[0, 0, 1]", "22/7"); test(10, "[3]", "[]", "[146, 292, 585]", "22/7"); test( 1, "[1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \ 1]", "[]", "[0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, \ 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, \ 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1]", "936851431250/1397", ); test( 10, "[53, 563, 639]", "[]", "[393, 635, 522, 643, 587, 135, 619]", "936851431250/1397", ); } #[test] #[should_panic] fn from_power_of_2_digits_fail() { Rational::from_power_of_2_digits(0, Vec::new(), RationalSequence::from_vec(Vec::new())); } #[test] #[should_panic] fn from_power_of_2_digits_ref_fail() { Rational::from_power_of_2_digits_ref(0, &[], &RationalSequence::from_vec(Vec::new())); } #[test] fn from_power_of_2_digits_properties() { large_type_gen_var_23().test_properties(|(log_base, before_point, after_point)| { let x = Rational::from_power_of_2_digits(log_base, before_point.clone(), after_point.clone()); assert!(x.is_valid()); assert_eq!( Rational::from_power_of_2_digits_ref(log_base, &before_point, &after_point), x ); assert!(x >= 0u32); if before_point.last() != Some(&Natural::ZERO) && after_point.slices_ref().1 != [Natural::ZERO] && after_point.slices_ref().1 != [Natural::low_mask(log_base)] && !(after_point.slices_ref().1.is_empty() && after_point.slices_ref().0.last() == Some(&Natural::ZERO)) { assert_eq!( x.into_power_of_2_digits(log_base), (before_point, after_point) ); } }); natural_vec_unsigned_pair_gen_var_1().test_properties(|(digits, log_base)| { assert_eq!( Natural::from_power_of_2_digits_asc(log_base, digits.iter().cloned()).unwrap(), Rational::from_power_of_2_digits( log_base, digits.to_vec(), RationalSequence::from_vec(Vec::new()) ) ); }); }