// 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::arithmetic::traits::Parity; use malachite_base::num::basic::floats::PrimitiveFloat; use malachite_base::num::basic::traits::NegativeInfinity; use malachite_base::num::comparison::traits::PartialOrdAbs; use malachite_base::num::conversion::from::UnsignedFromFloatError; use malachite_base::num::conversion::traits::{ConvertibleFrom, ExactFrom, RoundingFrom}; use malachite_base::num::float::NiceFloat; use malachite_base::rounding_modes::RoundingMode::{self, *}; use malachite_nz::integer::Integer; use malachite_nz::natural::Natural; use malachite_nz::test_util::generators::{ integer_gen, integer_gen_var_1, integer_rounding_mode_pair_gen_var_1, }; use malachite_q::conversion::primitive_float_from_rational::FloatFromRationalError; use malachite_q::test_util::generators::{ rational_gen, rational_gen_var_4, rational_gen_var_5, rational_gen_var_6, rational_rounding_mode_pair_gen_var_5, }; use malachite_q::Rational; use std::cmp::Ordering::*; use std::panic::catch_unwind; use std::str::FromStr; #[test] fn test_f32_rounding_from_rational() { let max = Rational::exact_from(f32::MAX_FINITE); let test = |s: &str, rm: RoundingMode, out, o_out| { let u = Rational::from_str(s).unwrap(); let (f, o) = f32::rounding_from(&u, rm); assert_eq!(NiceFloat(f), NiceFloat(out)); assert_eq!(o, o_out); let (f, o) = f32::rounding_from(u.clone(), rm); assert_eq!(NiceFloat(f), NiceFloat(out)); assert_eq!(o, o_out); if rm == Down && u.lt_abs(&max) && NiceFloat(out) != NiceFloat(-0.0) { assert_eq!( NiceFloat(rug::Rational::from_str(s).unwrap().to_f32()), NiceFloat(out) ); } }; test("3", Exact, 3.0, Equal); test("-3", Exact, -3.0, Equal); test("123", Exact, 123.0, Equal); test("-123", Exact, -123.0, Equal); test("0", Exact, 0.0, Equal); test("1000000000", Exact, 1.0e9, Equal); test("-1000000000", Exact, -1.0e9, Equal); test("16777216", Exact, 1.6777216e7, Equal); test("-16777216", Exact, -1.6777216e7, Equal); test("16777218", Exact, 1.6777218e7, Equal); test("-16777218", Exact, -1.6777218e7, Equal); test("16777217", Floor, 1.6777216e7, Less); test("16777217", Down, 1.6777216e7, Less); test("16777217", Ceiling, 1.6777218e7, Greater); test("16777217", Up, 1.6777218e7, Greater); test("16777217", Nearest, 1.6777216e7, Less); test("-16777217", Floor, -1.6777218e7, Less); test("-16777217", Down, -1.6777216e7, Greater); test("-16777217", Ceiling, -1.6777216e7, Greater); test("-16777217", Up, -1.6777218e7, Less); test("-16777217", Nearest, -1.6777216e7, Greater); test("33554432", Exact, 3.3554432e7, Equal); test("-33554432", Exact, -3.3554432e7, Equal); test("33554436", Exact, 3.3554436e7, Equal); test("-33554436", Exact, -3.3554436e7, Equal); test("33554433", Floor, 3.3554432e7, Less); test("33554433", Down, 3.3554432e7, Less); test("33554433", Ceiling, 3.3554436e7, Greater); test("33554433", Up, 3.3554436e7, Greater); test("33554433", Nearest, 3.3554432e7, Less); test("-33554433", Floor, -3.3554436e7, Less); test("-33554433", Down, -3.3554432e7, Greater); test("-33554433", Ceiling, -3.3554432e7, Greater); test("-33554433", Up, -3.3554436e7, Less); test("-33554433", Nearest, -3.3554432e7, Greater); test("33554434", Nearest, 3.3554432e7, Less); test("-33554434", Nearest, -3.3554432e7, Greater); test("33554435", Nearest, 3.3554436e7, Greater); test("-33554435", Nearest, -3.3554436e7, Less); test( "340282346638528859811704183484516925439", Floor, 3.4028233e38, Less, ); test( "340282346638528859811704183484516925439", Down, 3.4028233e38, Less, ); test( "340282346638528859811704183484516925439", Ceiling, 3.4028235e38, Greater, ); test( "340282346638528859811704183484516925439", Up, 3.4028235e38, Greater, ); test( "340282346638528859811704183484516925439", Nearest, 3.4028235e38, Greater, ); test( "-340282346638528859811704183484516925439", Floor, -3.4028235e38, Less, ); test( "-340282346638528859811704183484516925439", Down, -3.4028233e38, Greater, ); test( "-340282346638528859811704183484516925439", Ceiling, -3.4028233e38, Greater, ); test( "-340282346638528859811704183484516925439", Up, -3.4028235e38, Less, ); test( "-340282346638528859811704183484516925439", Nearest, -3.4028235e38, Less, ); test( "340282346638528859811704183484516925440", Exact, 3.4028235e38, Equal, ); test( "-340282346638528859811704183484516925440", Exact, -3.4028235e38, Equal, ); test( "340282346638528859811704183484516925441", Floor, 3.4028235e38, Less, ); test( "340282346638528859811704183484516925441", Down, 3.4028235e38, Less, ); test( "340282346638528859811704183484516925441", Nearest, 3.4028235e38, Less, ); test( "340282346638528859811704183484516925441", Ceiling, f32::INFINITY, Greater, ); test( "340282346638528859811704183484516925441", Up, f32::INFINITY, Greater, ); test( "-340282346638528859811704183484516925441", Floor, f32::NEGATIVE_INFINITY, Less, ); test( "-340282346638528859811704183484516925441", Down, -3.4028235e38, Greater, ); test( "-340282346638528859811704183484516925441", Nearest, -3.4028235e38, Greater, ); test( "-340282346638528859811704183484516925441", Ceiling, -3.4028235e38, Greater, ); test( "-340282346638528859811704183484516925441", Up, f32::NEGATIVE_INFINITY, Less, ); test( "10000000000000000000000000000000000000000000000000000", Floor, 3.4028235e38, Less, ); test( "10000000000000000000000000000000000000000000000000000", Down, 3.4028235e38, Less, ); test( "10000000000000000000000000000000000000000000000000000", Nearest, 3.4028235e38, Less, ); test( "10000000000000000000000000000000000000000000000000000", Ceiling, f32::INFINITY, Greater, ); test( "10000000000000000000000000000000000000000000000000000", Up, f32::INFINITY, Greater, ); test( "-10000000000000000000000000000000000000000000000000000", Floor, f32::NEGATIVE_INFINITY, Less, ); test( "-10000000000000000000000000000000000000000000000000000", Down, -3.4028235e38, Greater, ); test( "-10000000000000000000000000000000000000000000000000000", Nearest, -3.4028235e38, Greater, ); test( "-10000000000000000000000000000000000000000000000000000", Ceiling, -3.4028235e38, Greater, ); test( "-10000000000000000000000000000000000000000000000000000", Up, f32::NEGATIVE_INFINITY, Less, ); test("1125899873419263", Floor, 1.12589984e15, Less); test("1125899873419263", Down, 1.12589984e15, Less); test("1125899873419263", Ceiling, 1.1258999e15, Greater); test("1125899873419263", Up, 1.1258999e15, Greater); test("1125899873419263", Nearest, 1.1258999e15, Greater); test("-1125899873419263", Floor, -1.1258999e15, Less); test("-1125899873419263", Down, -1.12589984e15, Greater); test("-1125899873419263", Ceiling, -1.12589984e15, Greater); test("-1125899873419263", Up, -1.1258999e15, Less); test("-1125899873419263", Nearest, -1.1258999e15, Less); test("1/2", Floor, 0.5, Equal); test("1/2", Down, 0.5, Equal); test("1/2", Ceiling, 0.5, Equal); test("1/2", Up, 0.5, Equal); test("1/2", Nearest, 0.5, Equal); test("1/2", Exact, 0.5, Equal); test("-1/2", Floor, -0.5, Equal); test("-1/2", Down, -0.5, Equal); test("-1/2", Ceiling, -0.5, Equal); test("-1/2", Up, -0.5, Equal); test("-1/2", Nearest, -0.5, Equal); test("-1/2", Exact, -0.5, Equal); test("1/3", Floor, 0.3333333, Less); test("1/3", Down, 0.3333333, Less); test("1/3", Ceiling, 0.33333334, Greater); test("1/3", Up, 0.33333334, Greater); test("1/3", Nearest, 0.33333334, Greater); test("-1/3", Floor, -0.33333334, Less); test("-1/3", Down, -0.3333333, Greater); test("-1/3", Ceiling, -0.3333333, Greater); test("-1/3", Up, -0.33333334, Less); test("-1/3", Nearest, -0.33333334, Less); // subnormal test( "1/10000000000000000000000000000000000000000", Floor, 1.0e-40, Less, ); test( "1/10000000000000000000000000000000000000000", Down, 1.0e-40, Less, ); test( "1/10000000000000000000000000000000000000000", Ceiling, 1.00001e-40, Greater, ); test( "1/10000000000000000000000000000000000000000", Up, 1.00001e-40, Greater, ); test( "1/10000000000000000000000000000000000000000", Nearest, 1.0e-40, Less, ); test( "-1/10000000000000000000000000000000000000000", Floor, -1.00001e-40, Less, ); test( "-1/10000000000000000000000000000000000000000", Down, -1.0e-40, Greater, ); test( "-1/10000000000000000000000000000000000000000", Ceiling, -1.0e-40, Greater, ); test( "-1/10000000000000000000000000000000000000000", Up, -1.00001e-40, Less, ); test( "-1/10000000000000000000000000000000000000000", Nearest, -1.0e-40, Greater, ); // less than subnormal test( "1/100000000000000000000000000000000000000000000000000", Floor, 0.0, Less, ); test( "1/100000000000000000000000000000000000000000000000000", Down, 0.0, Less, ); test( "1/100000000000000000000000000000000000000000000000000", Ceiling, 1.0e-45, Greater, ); test( "1/100000000000000000000000000000000000000000000000000", Up, 1.0e-45, Greater, ); test( "1/100000000000000000000000000000000000000000000000000", Nearest, 0.0, Less, ); test( "-1/100000000000000000000000000000000000000000000000000", Floor, -1.0e-45, Less, ); test( "-1/100000000000000000000000000000000000000000000000000", Down, -0.0, Greater, ); test( "-1/100000000000000000000000000000000000000000000000000", Ceiling, -0.0, Greater, ); test( "-1/100000000000000000000000000000000000000000000000000", Up, -1.0e-45, Less, ); test( "-1/100000000000000000000000000000000000000000000000000", Nearest, -0.0, Greater, ); // half of smallest positive test( "1/1427247692705959881058285969449495136382746624", Floor, 0.0, Less, ); test( "1/1427247692705959881058285969449495136382746624", Down, 0.0, Less, ); test( "1/1427247692705959881058285969449495136382746624", Ceiling, 1.0e-45, Greater, ); test( "1/1427247692705959881058285969449495136382746624", Up, 1.0e-45, Greater, ); test( "1/1427247692705959881058285969449495136382746624", Nearest, 0.0, Less, ); test( "-1/1427247692705959881058285969449495136382746624", Floor, -1.0e-45, Less, ); test( "-1/1427247692705959881058285969449495136382746624", Down, -0.0, Greater, ); test( "-1/1427247692705959881058285969449495136382746624", Ceiling, -0.0, Greater, ); test( "-1/1427247692705959881058285969449495136382746624", Up, -1.0e-45, Less, ); test( "-1/1427247692705959881058285969449495136382746624", Nearest, -0.0, Greater, ); // just over half of smallest positive; Nearest rounds up test( "88819109620612751463292030150471001/126765060022822940149670320537600000000000000000000000\ 000000000000000000000000000", Floor, 0.0, Less ); test( "88819109620612751463292030150471001/126765060022822940149670320537600000000000000000000000\ 000000000000000000000000000", Down, 0.0, Less ); test( "88819109620612751463292030150471001/126765060022822940149670320537600000000000000000000000\ 000000000000000000000000000", Ceiling, 1.0e-45, Greater ); test( "88819109620612751463292030150471001/126765060022822940149670320537600000000000000000000000\ 000000000000000000000000000", Up, 1.0e-45, Greater ); test( "88819109620612751463292030150471001/126765060022822940149670320537600000000000000000000000\ 000000000000000000000000000", Nearest, 1.0e-45, Greater ); test( "-88819109620612751463292030150471001/12676506002282294014967032053760000000000000000000000\ 0000000000000000000000000000", Floor, -1.0e-45, Less ); test( "-88819109620612751463292030150471001/12676506002282294014967032053760000000000000000000000\ 0000000000000000000000000000", Down, -0.0, Greater ); test( "-88819109620612751463292030150471001/12676506002282294014967032053760000000000000000000000\ 0000000000000000000000000000", Ceiling, -0.0, Greater ); test( "-88819109620612751463292030150471001/12676506002282294014967032053760000000000000000000000\ 0000000000000000000000000000", Up, -1.0e-45, Less ); test( "-88819109620612751463292030150471001/12676506002282294014967032053760000000000000000000000\ 0000000000000000000000000000", Nearest, -1.0e-45, Less ); // halfway between max subnormal and min normal test( "16777215/1427247692705959881058285969449495136382746624", Floor, 1.1754942e-38, Less, ); test( "16777215/1427247692705959881058285969449495136382746624", Down, 1.1754942e-38, Less, ); test( "16777215/1427247692705959881058285969449495136382746624", Ceiling, 1.1754944e-38, Greater, ); test( "16777215/1427247692705959881058285969449495136382746624", Up, 1.1754944e-38, Greater, ); test( "16777215/1427247692705959881058285969449495136382746624", Nearest, 1.1754944e-38, Greater, ); } #[test] fn f32_rounding_from_rational_fail() { assert_panic!(f32::rounding_from( Rational::from_str("340282346638528859811704183484516925439").unwrap(), Exact, )); assert_panic!(f32::rounding_from( Rational::from_str("340282346638528859811704183484516925441").unwrap(), Exact, )); assert_panic!(f32::rounding_from( Rational::from_str("16777217").unwrap(), Exact )); assert_panic!(f32::rounding_from( Rational::from_str("10000000000000000000000000000000000000000000000000000").unwrap(), Exact, )); assert_panic!(f32::rounding_from( Rational::from_str("1/10").unwrap(), Exact )); } #[test] fn f32_rounding_from_rational_ref_fail() { assert_panic!(f32::rounding_from( &Rational::from_str("340282346638528859811704183484516925439").unwrap(), Exact, )); assert_panic!(f32::rounding_from( &Rational::from_str("340282346638528859811704183484516925441").unwrap(), Exact, )); assert_panic!(f32::rounding_from( &Rational::from_str("16777217").unwrap(), Exact, )); assert_panic!(f32::rounding_from( &Rational::from_str("10000000000000000000000000000000000000000000000000000").unwrap(), Exact, )); assert_panic!(f32::rounding_from( &Rational::from_str("1/10").unwrap(), Exact )); } #[test] fn test_f64_rounding_from_rational() { let test = |s: &str, rm: RoundingMode, out, o_out| { let u = Rational::from_str(s).unwrap(); let (f, o) = f64::rounding_from(&u, rm); assert_eq!(NiceFloat(f), NiceFloat(out)); assert_eq!(o, o_out); let (f, o) = f64::rounding_from(u, rm); assert_eq!(NiceFloat(f), NiceFloat(out)); assert_eq!(o, o_out); if rm == Down { assert_eq!( NiceFloat(rug::Rational::from_str(s).unwrap().to_f64()), NiceFloat(out) ); } }; test("3", Exact, 3.0, Equal); test("-3", Exact, -3.0, Equal); test("123", Exact, 123.0, Equal); test("-123", Exact, -123.0, Equal); test("0", Exact, 0.0, Equal); test("100000000000000000000", Exact, 1.0e20, Equal); test("-100000000000000000000", Exact, -1.0e20, Equal); test("9007199254740992", Exact, 9.007199254740992e15, Equal); test("-9007199254740992", Exact, -9.007199254740992e15, Equal); test("9007199254740994", Exact, 9.007199254740994e15, Equal); test("-9007199254740994", Exact, -9.007199254740994e15, Equal); test("9007199254740993", Floor, 9.007199254740992e15, Less); test("9007199254740993", Down, 9.007199254740992e15, Less); test("9007199254740993", Ceiling, 9.007199254740994e15, Greater); test("9007199254740993", Up, 9.007199254740994e15, Greater); test("9007199254740993", Nearest, 9.007199254740992e15, Less); test("-9007199254740993", Floor, -9.007199254740994e15, Less); test("-9007199254740993", Down, -9.007199254740992e15, Greater); test("-9007199254740993", Ceiling, -9.007199254740992e15, Greater); test("-9007199254740993", Up, -9.007199254740994e15, Less); test("-9007199254740993", Nearest, -9.007199254740992e15, Greater); test("18014398509481984", Exact, 1.8014398509481984e16, Equal); test("-18014398509481984", Exact, -1.8014398509481984e16, Equal); test("18014398509481988", Exact, 1.8014398509481988e16, Equal); test("-18014398509481988", Exact, -1.8014398509481988e16, Equal); test("18014398509481985", Floor, 1.8014398509481984e16, Less); test("18014398509481985", Down, 1.8014398509481984e16, Less); test("18014398509481985", Ceiling, 1.8014398509481988e16, Greater); test("18014398509481985", Up, 1.8014398509481988e16, Greater); test("18014398509481985", Nearest, 1.8014398509481984e16, Less); test("-18014398509481985", Floor, -1.8014398509481988e16, Less); test("-18014398509481985", Down, -1.8014398509481984e16, Greater); test( "-18014398509481985", Ceiling, -1.8014398509481984e16, Greater, ); test("-18014398509481985", Up, -1.8014398509481988e16, Less); test( "-18014398509481985", Nearest, -1.8014398509481984e16, Greater, ); test("18014398509481986", Nearest, 1.8014398509481984e16, Less); test( "-18014398509481986", Nearest, -1.8014398509481984e16, Greater, ); test("18014398509481987", Nearest, 1.8014398509481988e16, Greater); test("-18014398509481987", Nearest, -1.8014398509481988e16, Less); test("1/2", Floor, 0.5, Equal); test("1/2", Down, 0.5, Equal); test("1/2", Ceiling, 0.5, Equal); test("1/2", Up, 0.5, Equal); test("1/2", Nearest, 0.5, Equal); test("1/2", Exact, 0.5, Equal); test("-1/2", Floor, -0.5, Equal); test("-1/2", Down, -0.5, Equal); test("-1/2", Ceiling, -0.5, Equal); test("-1/2", Up, -0.5, Equal); test("-1/2", Nearest, -0.5, Equal); test("-1/2", Exact, -0.5, Equal); test("1/3", Floor, 0.3333333333333333, Less); test("1/3", Down, 0.3333333333333333, Less); test("1/3", Ceiling, 0.33333333333333337, Greater); test("1/3", Up, 0.33333333333333337, Greater); test("1/3", Nearest, 0.3333333333333333, Less); test("-1/3", Floor, -0.33333333333333337, Less); test("-1/3", Down, -0.3333333333333333, Greater); test("-1/3", Ceiling, -0.3333333333333333, Greater); test("-1/3", Up, -0.33333333333333337, Less); test("-1/3", Nearest, -0.3333333333333333, Greater); } #[test] fn f64_rounding_from_rational_fail() { assert_panic!(f64::rounding_from(Rational::from_str( "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558\ 6327668781715404589535143824642343213268894641827684675467035375169860499105765512820762454\ 9009038932894407586850845513394230458323690322294816580855933212334827479782620414472316873\ 8177180919299881250404026184124858367").unwrap(), Exact) ); assert_panic!(f64::rounding_from(Rational::from_str( "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558\ 6327668781715404589535143824642343213268894641827684675467035375169860499105765512820762454\ 9009038932894407586850845513394230458323690322294816580855933212334827479782620414472316873\ 8177180919299881250404026184124858369").unwrap(), Exact) ); assert_panic!(f64::rounding_from( Rational::from_str("9007199254740993").unwrap(), Exact, )); assert_panic!(f64::rounding_from( Rational::from_str("1/10").unwrap(), Exact )); } #[test] fn f64_rounding_from_rational_ref_fail() { assert_panic!( f64::rounding_from(&Rational::from_str( "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558\ 6327668781715404589535143824642343213268894641827684675467035375169860499105765512820762454\ 9009038932894407586850845513394230458323690322294816580855933212334827479782620414472316873\ 8177180919299881250404026184124858367").unwrap(), Exact) ); assert_panic!( f64::rounding_from(&Rational::from_str( "17976931348623157081452742373170435679807056752584499659891747680315726078002858760589558\ 632766878171540458953514382464234321326889464182768467546703537516986049910576552820762454\ 900903893289440758685084551339423045832369032229481658085593321233482747978262044472316873\ 8177180919299881250404026184124858369").unwrap(), Exact) ); assert_panic!(f64::rounding_from( &Rational::from_str("9007199254740993").unwrap(), Exact, )); assert_panic!(f64::rounding_from( &Rational::from_str("1/10").unwrap(), Exact )); } #[test] fn test_f32_try_from_rational() { let test = |s: &str, out: Result| { let u = Rational::from_str(s).unwrap(); assert_eq!(f32::try_from(&u).map(NiceFloat), out.map(NiceFloat)); assert_eq!(f32::try_from(u.clone()).map(NiceFloat), out.map(NiceFloat)); assert_eq!(f32::convertible_from(u), out.is_ok()); }; test("3", Ok(3.0)); test("-3", Ok(-3.0)); test("123", Ok(123.0)); test("-123", Ok(-123.0)); test("0", Ok(0.0)); test("1000000000", Ok(1.0e9)); test("-1000000000", Ok(-1.0e9)); test("16777216", Ok(1.6777216e7)); test("-16777216", Ok(-1.6777216e7)); test("16777218", Ok(1.6777218e7)); test("-16777218", Ok(-1.6777218e7)); test("16777217", Err(FloatFromRationalError)); test("-16777217", Err(FloatFromRationalError)); test("33554432", Ok(3.3554432e7)); test("-33554432", Ok(-3.3554432e7)); test("33554436", Ok(3.3554436e7)); test("-33554436", Ok(-3.3554436e7)); test("33554433", Err(FloatFromRationalError)); test("-33554433", Err(FloatFromRationalError)); test("33554434", Err(FloatFromRationalError)); test("-33554434", Err(FloatFromRationalError)); test("33554435", Err(FloatFromRationalError)); test("-33554435", Err(FloatFromRationalError)); test( "340282346638528859811704183484516925439", Err(FloatFromRationalError), ); test( "-340282346638528859811704183484516925439", Err(FloatFromRationalError), ); test("340282346638528859811704183484516925440", Ok(3.4028235e38)); test( "-340282346638528859811704183484516925440", Ok(-3.4028235e38), ); test( "340282346638528859811704183484516925441", Err(FloatFromRationalError), ); test( "-340282346638528859811704183484516925441", Err(FloatFromRationalError), ); test( "10000000000000000000000000000000000000000000000000000", Err(FloatFromRationalError), ); test( "-10000000000000000000000000000000000000000000000000000", Err(FloatFromRationalError), ); test("1/2", Ok(0.5)); test("-1/2", Ok(-0.5)); test("1/3", Err(FloatFromRationalError)); test("-1/3", Err(FloatFromRationalError)); test( "1/713623846352979940529142984724747568191373312", Ok(f32::MIN_POSITIVE_SUBNORMAL), ); test( "-1/713623846352979940529142984724747568191373312", Ok(-f32::MIN_POSITIVE_SUBNORMAL), ); test( "8388607/713623846352979940529142984724747568191373312", Ok(f32::MAX_SUBNORMAL), ); test( "-8388607/713623846352979940529142984724747568191373312", Ok(-f32::MAX_SUBNORMAL), ); test( "1/85070591730234615865843651857942052864", Ok(f32::MIN_POSITIVE_NORMAL), ); test( "-1/85070591730234615865843651857942052864", Ok(-f32::MIN_POSITIVE_NORMAL), ); } #[test] fn test_f64_try_from_rational() { let test = |s: &str, out: Result| { let u = Rational::from_str(s).unwrap(); assert_eq!(f64::try_from(&u).map(NiceFloat), out.map(NiceFloat)); assert_eq!(f64::try_from(u.clone()).map(NiceFloat), out.map(NiceFloat)); assert_eq!(f64::convertible_from(u), out.is_ok()); }; test("3", Ok(3.0)); test("-3", Ok(-3.0)); test("123", Ok(123.0)); test("-123", Ok(-123.0)); test("0", Ok(0.0)); test("1000000000", Ok(1.0e9)); test("-1000000000", Ok(-1.0e9)); test("9007199254740992", Ok(9.007199254740992e15)); test("-9007199254740992", Ok(-9.007199254740992e15)); test("9007199254740994", Ok(9.007199254740994e15)); test("-9007199254740994", Ok(-9.007199254740994e15)); test("9007199254740993", Err(FloatFromRationalError)); test("-9007199254740993", Err(FloatFromRationalError)); test("18014398509481984", Ok(1.8014398509481984e16)); test("-18014398509481984", Ok(-1.8014398509481984e16)); test("18014398509481988", Ok(1.8014398509481988e16)); test("-18014398509481988", Ok(-1.8014398509481988e16)); test("18014398509481985", Err(FloatFromRationalError)); test("-18014398509481985", Err(FloatFromRationalError)); test("18014398509481986", Err(FloatFromRationalError)); test("-18014398509481986", Err(FloatFromRationalError)); test("18014398509481987", Err(FloatFromRationalError)); test("-18014398509481987", Err(FloatFromRationalError)); test( "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558\ 6327668781715404589535143824642343213268894641827684675467035375169860499105765512820762454\ 9009038932894407586850845513394230458323690322294816580855933212334827479782620414472316873\ 8177180919299881250404026184124858367", Err(FloatFromRationalError)); test( "-17976931348623157081452742373170435679807056752584499659891747680315726078002853876058955\ 8632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245\ 4900903893289440758685084551339423045832369032229481658085593321233482747978262041447231687\ 38177180919299881250404026184124858367", Err(FloatFromRationalError)); test( "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558\ 6327668781715404589535143824642343213268894641827684675467035375169860499105765512820762454\ 9009038932894407586850845513394230458323690322294816580855933212334827479782620414472316873\ 8177180919299881250404026184124858368", Ok(1.7976931348623157e308)); test( "-17976931348623157081452742373170435679807056752584499659891747680315726078002853876058955\ 8632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245\ 4900903893289440758685084551339423045832369032229481658085593321233482747978262041447231687\ 38177180919299881250404026184124858368", Ok(-1.7976931348623157e308)); test( "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558\ 6327668781715404589535143824642343213268894641827684675467035375169860499105765512820762454\ 9009038932894407586850845513394230458323690322294816580855933212334827479782620414472316873\ 8177180919299881250404026184124858369", Err(FloatFromRationalError)); test( "-17976931348623157081452742373170435679807056752584499659891747680315726078002853876058955\ 8632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245\ 4900903893289440758685084551339423045832369032229481658085593321233482747978262041447231687\ 38177180919299881250404026184124858369", Err(FloatFromRationalError)); test("1/2", Ok(0.5)); test("-1/2", Ok(-0.5)); test("1/3", Err(FloatFromRationalError)); test("-1/3", Err(FloatFromRationalError)); } #[test] fn test_f32_exact_from_rational() { let test = |s: &str, out| { let u = Rational::from_str(s).unwrap(); assert_eq!(NiceFloat(f32::exact_from(&u)), NiceFloat(out)); assert_eq!(NiceFloat(f32::exact_from(u)), NiceFloat(out)); }; test("3", 3.0); test("-3", -3.0); test("123", 123.0); test("-123", -123.0); test("0", 0.0); test("1000000000", 1.0e9); test("-1000000000", -1.0e9); test("16777216", 1.6777216e7); test("-16777216", -1.6777216e7); test("16777218", 1.6777218e7); test("-16777218", -1.6777218e7); test("33554432", 3.3554432e7); test("-33554432", -3.3554432e7); test("33554436", 3.3554436e7); test("-33554436", -3.3554436e7); test("340282346638528859811704183484516925440", 3.4028235e38); test("-340282346638528859811704183484516925440", -3.4028235e38); } #[test] fn f32_exact_from_rational_fail() { assert_panic!(f32::exact_from(Rational::from_str("16777217").unwrap())); assert_panic!(f32::exact_from(Rational::from_str("-16777217").unwrap())); assert_panic!(f32::exact_from(Rational::from_str("33554433").unwrap())); assert_panic!(f32::exact_from(Rational::from_str("-33554433").unwrap())); assert_panic!(f32::exact_from(Rational::from_str("33554434").unwrap())); assert_panic!(f32::exact_from(Rational::from_str("-33554434").unwrap())); assert_panic!(f32::exact_from(Rational::from_str("33554435").unwrap())); assert_panic!(f32::exact_from(Rational::from_str("-33554435").unwrap())); assert_panic!(f32::exact_from( Rational::from_str("340282346638528859811704183484516925439").unwrap() )); assert_panic!(f32::exact_from( Rational::from_str("-340282346638528859811704183484516925439").unwrap() )); assert_panic!(f32::exact_from( Rational::from_str("340282346638528859811704183484516925441").unwrap() )); assert_panic!(f32::exact_from( Rational::from_str("-340282346638528859811704183484516925441").unwrap() )); assert_panic!(f32::exact_from( Rational::from_str("340282346638528859811704183484516925441").unwrap() )); assert_panic!(f32::exact_from( Rational::from_str("-340282346638528859811704183484516925441").unwrap() )); assert_panic!(f32::exact_from( Rational::from_str("10000000000000000000000000000000000000000000000000000").unwrap(), )); assert_panic!(f32::exact_from( Rational::from_str("-10000000000000000000000000000000000000000000000000000").unwrap(), )); assert_panic!(f32::exact_from(Rational::from_str("1/3").unwrap())); assert_panic!(f32::exact_from(Rational::from_str("-1/3").unwrap())); } #[test] fn f32_exact_from_rational_ref_fail() { assert_panic!(f32::exact_from(&Rational::from_str("16777217").unwrap())); assert_panic!(f32::exact_from(&Rational::from_str("-16777217").unwrap())); assert_panic!(f32::exact_from(&Rational::from_str("33554433").unwrap())); assert_panic!(f32::exact_from(&Rational::from_str("-33554433").unwrap())); assert_panic!(f32::exact_from(&Rational::from_str("33554434").unwrap())); assert_panic!(f32::exact_from(&Rational::from_str("-33554434").unwrap())); assert_panic!(f32::exact_from(&Rational::from_str("33554435").unwrap())); assert_panic!(f32::exact_from(&Rational::from_str("-33554435").unwrap())); assert_panic!(f32::exact_from( &Rational::from_str("340282346638528859811704183484516925439").unwrap() )); assert_panic!(f32::exact_from( &Rational::from_str("-340282346638528859811704183484516925439").unwrap() )); assert_panic!(f32::exact_from( &Rational::from_str("340282346638528859811704183484516925441").unwrap() )); assert_panic!(f32::exact_from( &Rational::from_str("-340282346638528859811704183484516925441").unwrap() )); assert_panic!(f32::exact_from( &Rational::from_str("340282346638528859811704183484516925441").unwrap() )); assert_panic!(f32::exact_from( &Rational::from_str("-340282346638528859811704183484516925441").unwrap() )); assert_panic!(f32::exact_from( &Rational::from_str("10000000000000000000000000000000000000000000000000000").unwrap(), )); assert_panic!(f32::exact_from( &Rational::from_str("-10000000000000000000000000000000000000000000000000000").unwrap(), )); assert_panic!(f32::exact_from(&Rational::from_str("1/3").unwrap())); assert_panic!(f32::exact_from(&Rational::from_str("-1/3").unwrap())); } #[test] fn test_f64_exact_from_rational() { let test = |s: &str, out| { let u = Rational::from_str(s).unwrap(); assert_eq!(NiceFloat(f64::exact_from(&u)), NiceFloat(out)); assert_eq!(NiceFloat(f64::exact_from(u)), NiceFloat(out)); }; test("3", 3.0); test("-3", -3.0); test("123", 123.0); test("-123", -123.0); test("0", 0.0); test("1000000000", 1.0e9); test("-1000000000", -1.0e9); test("9007199254740992", 9.007199254740992e15); test("-9007199254740992", -9.007199254740992e15); test("9007199254740994", 9.007199254740994e15); test("-9007199254740994", -9.007199254740994e15); test("18014398509481984", 1.8014398509481984e16); test("-18014398509481984", -1.8014398509481984e16); test("18014398509481988", 1.8014398509481988e16); test("-18014398509481988", -1.8014398509481988e16); test( "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558\ 6327668781715404589535143824642343213268894641827684675467035375169860499105765512820762454\ 9009038932894407586850845513394230458323690322294816580855933212334827479782620414472316873\ 8177180919299881250404026184124858368", 1.7976931348623157e308); test( "-17976931348623157081452742373170435679807056752584499659891747680315726078002853876058955\ 8632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245\ 4900903893289440758685084551339423045832369032229481658085593321233482747978262041447231687\ 38177180919299881250404026184124858368", -1.7976931348623157e308); } #[test] fn f64_exact_from_rational_fail() { assert_panic!(f64::exact_from( Rational::from_str("18014398509481983").unwrap() )); assert_panic!(f64::exact_from( Rational::from_str("-18014398509481983").unwrap() )); assert_panic!(f64::exact_from( Rational::from_str("18014398509481985").unwrap() )); assert_panic!(f64::exact_from( Rational::from_str("-18014398509481985").unwrap() )); assert_panic!(f64::exact_from( Rational::from_str("18014398509481986").unwrap() )); assert_panic!(f64::exact_from( Rational::from_str("-18014398509481986").unwrap() )); assert_panic!(f64::exact_from( Rational::from_str("18014398509481987").unwrap() )); assert_panic!(f64::exact_from( Rational::from_str("-18014398509481987").unwrap() )); assert_panic!(f64::exact_from(Rational::from_str( "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558\ 6327668781715404589535143824642343213268894641827684675467035375169860499105765512820762454\ 9009038932894407586850845513394230458323690322294816580855933212334827479782620414472316873\ 8177180919299881250404026184124858367").unwrap())); assert_panic!(f64::exact_from(Rational::from_str( "-17976931348623157081452742373170435679807056752584499659891747680315726078002853876058955\ 8632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245\ 4900903893289440758685084551339423045832369032229481658085593321233482747978262041447231687\ 38177180919299881250404026184124858367").unwrap())); assert_panic!(f64::exact_from(Rational::from_str( "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558\ 6327668781715404589535143824642343213268894641827684675467035375169860499105765512820762454\ 9009038932894407586850845513394230458323690322294816580855933212334827479782620414472316873\ 8177180919299881250404026184124858369").unwrap())); assert_panic!(f64::exact_from(Rational::from_str( "-17976931348623157081452742373170435679807056752584499659891747680315726078002853876058955\ 8632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245\ 4900903893289440758685084551339423045832369032229481658085593321233482747978262041447231687\ 38177180919299881250404026184124858369").unwrap())); assert_panic!(f64::exact_from(Rational::from_str("1/3").unwrap())); assert_panic!(f64::exact_from(Rational::from_str("-1/3").unwrap())); } #[test] fn f64_exact_from_rational_ref_fail() { assert_panic!(f64::exact_from( &Rational::from_str("18014398509481983").unwrap() )); assert_panic!(f64::exact_from( &Rational::from_str("-18014398509481983").unwrap() )); assert_panic!(f64::exact_from( &Rational::from_str("18014398509481985").unwrap() )); assert_panic!(f64::exact_from( &Rational::from_str("-18014398509481985").unwrap() )); assert_panic!(f64::exact_from( &Rational::from_str("18014398509481986").unwrap() )); assert_panic!(f64::exact_from( &Rational::from_str("-18014398509481986").unwrap() )); assert_panic!(f64::exact_from( &Rational::from_str("18014398509481987").unwrap() )); assert_panic!(f64::exact_from( &Rational::from_str("-18014398509481987").unwrap() )); assert_panic!(f64::exact_from(&Rational::from_str( "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558\ 6327668781715404589535143824642343213268894641827684675467035375169860499105765512820762454\ 9009038932894407586850845513394230458323690322294816580855933212334827479782620414472316873\ 8177180919299881250404026184124858367").unwrap())); assert_panic!(f64::exact_from(&Rational::from_str( "-17976931348623157081452742373170435679807056752584499659891747680315726078002853876058955\ 8632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245\ 4900903893289440758685084551339423045832369032229481658085593321233482747978262041447231687\ 38177180919299881250404026184124858367").unwrap())); assert_panic!(f64::exact_from(&Rational::from_str( "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558\ 6327668781715404589535143824642343213268894641827684675467035375169860499105765512820762454\ 9009038932894407586850845513394230458323690322294816580855933212334827479782620414472316873\ 8177180919299881250404026184124858369").unwrap())); assert_panic!(f64::exact_from(&Rational::from_str( "-17976931348623157081452742373170435679807056752584499659891747680315726078002853876058955\ 8632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245\ 4900903893289440758685084551339423045832369032229481658085593321233482747978262041447231687\ 38177180919299881250404026184124858369").unwrap())); assert_panic!(f64::exact_from(&Rational::from_str("1/3").unwrap())); assert_panic!(f64::exact_from(&Rational::from_str("-1/3").unwrap())); } #[test] fn test_f32_convertible_from_rational() { let test = |s: &str, out| { let u = Rational::from_str(s).unwrap(); assert_eq!(f32::convertible_from(&u), out); assert_eq!(f32::convertible_from(u), out); }; test("3", true); test("-3", true); test("123", true); test("-123", true); test("0", true); test("1000000000", true); test("-1000000000", true); test("16777216", true); test("-16777216", true); test("16777218", true); test("-16777218", true); test("16777217", false); test("-16777217", false); test("33554432", true); test("-33554432", true); test("33554436", true); test("-33554436", true); test("33554433", false); test("-33554433", false); test("33554434", false); test("-33554434", false); test("33554435", false); test("-33554435", false); test("340282346638528859811704183484516925439", false); test("-340282346638528859811704183484516925439", false); test("340282346638528859811704183484516925440", true); test("-340282346638528859811704183484516925440", true); test("340282346638528859811704183484516925441", false); test("-340282346638528859811704183484516925441", false); test( "10000000000000000000000000000000000000000000000000000", false, ); test( "-10000000000000000000000000000000000000000000000000000", false, ); test("1/3", false); test("-1/3", false); } #[test] fn test_f64_convertible_from_rational() { let test = |s: &str, out| { let u = Rational::from_str(s).unwrap(); assert_eq!(f64::convertible_from(&u), out); assert_eq!(f64::convertible_from(u), out); }; test("3", true); test("-3", true); test("123", true); test("-123", true); test("0", true); test("1000000000", true); test("-1000000000", true); test("9007199254740992", true); test("-9007199254740992", true); test("9007199254740994", true); test("-9007199254740994", true); test("9007199254740993", false); test("-9007199254740993", false); test("18014398509481984", true); test("-18014398509481984", true); test("18014398509481988", true); test("-18014398509481988", true); test("18014398509481985", false); test("-18014398509481985", false); test("18014398509481986", false); test("-18014398509481986", false); test("18014398509481987", false); test("-18014398509481987", false); test( "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558\ 6327668781715404589535143824642343213268894641827684675467035375169860499105765512820762454\ 9009038932894407586850845513394230458323690322294816580855933212334827479782620414472316873\ 8177180919299881250404026184124858367", false); test( "-17976931348623157081452742373170435679807056752584499659891747680315726078002853876058955\ 8632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245\ 4900903893289440758685084551339423045832369032229481658085593321233482747978262041447231687\ 38177180919299881250404026184124858367", false); test( "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558\ 6327668781715404589535143824642343213268894641827684675467035375169860499105765512820762454\ 9009038932894407586850845513394230458323690322294816580855933212334827479782620414472316873\ 8177180919299881250404026184124858368", true); test( "-17976931348623157081452742373170435679807056752584499659891747680315726078002853876058955\ 8632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245\ 4900903893289440758685084551339423045832369032229481658085593321233482747978262041447231687\ 38177180919299881250404026184124858368", true); test( "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558\ 6327668781715404589535143824642343213268894641827684675467035375169860499105765512820762454\ 9009038932894407586850845513394230458323690322294816580855933212334827479782620414472316873\ 8177180919299881250404026184124858369", false); test( "-17976931348623157081452742373170435679807056752584499659891747680315726078002853876058955\ 8632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245\ 4900903893289440758685084551339423045832369032229481658085593321233482747978262041447231687\ 38177180919299881250404026184124858369", false); test("1/3", false); test("-1/3", false); } #[allow(clippy::trait_duplication_in_bounds)] fn float_rounding_from_rational_properties_helper< T: for<'a> ConvertibleFrom<&'a Integer> + for<'a> ConvertibleFrom<&'a Rational> + PartialOrd + PrimitiveFloat + RoundingFrom + for<'a> RoundingFrom<&'a Integer> + for<'a> RoundingFrom<&'a Rational>, >() where Rational: TryFrom, { rational_rounding_mode_pair_gen_var_5::().test_properties(|(x, rm)| { let (f, o) = T::rounding_from(&x, rm); let neg_f = if x == 0 { T::ZERO } else { -f }; let (f_alt, o_alt) = T::rounding_from(-&x, -rm); assert_eq!(NiceFloat(f_alt), NiceFloat(neg_f)); assert_eq!(o_alt, o.reverse()); let (f_alt, o_alt) = T::rounding_from(&x, rm); assert_eq!(NiceFloat(f_alt), NiceFloat(f)); assert_eq!(o_alt, o); assert_eq!(f.partial_cmp(&x), Some(o)); match (x >= 0, rm) { (_, Floor) | (true, Down) | (false, Up) => { assert_ne!(o, Greater); } (_, Ceiling) | (true, Up) | (false, Down) => { assert_ne!(o, Less); } (_, Exact) => assert_eq!(o, Equal), _ => {} } }); rational_gen_var_4::().test_properties(|n| { let (f, o) = T::rounding_from(&n, Exact); assert_eq!(o, Equal); let (f_alt, o_alt) = T::rounding_from(&n, Floor); assert_eq!(NiceFloat(f_alt), NiceFloat(f)); assert_eq!(o_alt, Equal); let (f_alt, o_alt) = T::rounding_from(&n, Down); assert_eq!(NiceFloat(f_alt), NiceFloat(f)); assert_eq!(o_alt, Equal); let (f_alt, o_alt) = T::rounding_from(&n, Ceiling); assert_eq!(NiceFloat(f_alt), NiceFloat(f)); assert_eq!(o_alt, Equal); let (f_alt, o_alt) = T::rounding_from(&n, Up); assert_eq!(NiceFloat(f_alt), NiceFloat(f)); assert_eq!(o_alt, Equal); let (f_alt, o_alt) = T::rounding_from(&n, Nearest); assert_eq!(NiceFloat(f_alt), NiceFloat(f)); assert_eq!(o_alt, Equal); assert_eq!(Rational::exact_from(f), n); }); rational_gen_var_5::().test_properties(|n| { let f_below = T::rounding_from(&n, Floor); assert_eq!(f_below.1, Less); let f_above = (f_below.0.next_higher(), Greater); if f_below.0.is_finite() { assert!(Rational::exact_from(f_below.0) < n); } if f_above.0.is_finite() { assert!(Rational::exact_from(f_above.0) > n); } let (f, o) = T::rounding_from(&n, Ceiling); assert_eq!(NiceFloat(f), NiceFloat(f_above.0)); assert_eq!(o, Greater); if n >= 0 { let (f, o) = T::rounding_from(&n, Down); assert_eq!(NiceFloat(f), NiceFloat(f_below.0)); assert_eq!(o, Less); let (f, o) = T::rounding_from(&n, Up); assert_eq!(NiceFloat(f), NiceFloat(f_above.0)); assert_eq!(o, Greater); } else { let (f, o) = T::rounding_from(&n, Down); assert_eq!(NiceFloat(f), NiceFloat(f_above.0)); assert_eq!(o, Greater); let (f, o) = T::rounding_from(&n, Up); assert_eq!(NiceFloat(f), NiceFloat(f_below.0)); assert_eq!(o, Less); } let (f, o) = T::rounding_from(&n, Nearest); assert!( (NiceFloat(f), o) == (NiceFloat(f_below.0), f_below.1) || (NiceFloat(f), o) == (NiceFloat(f_above.0), f_above.1) ); if f_below.0.is_finite() && f_above.0.is_finite() { let below_diff = &n - Rational::exact_from(f_below.0); let above_diff = Rational::exact_from(f_above.0) - &n; if NiceFloat(f) == NiceFloat(f_below.0) { assert!(below_diff <= above_diff); } else { assert!(below_diff >= above_diff); } } }); rational_gen_var_6::().test_properties(|n| { let floor = T::rounding_from(&n, Floor); assert_eq!(floor.1, Less); let ceiling = (floor.0.next_higher(), Greater); let nearest = T::rounding_from(&n, Nearest); assert_eq!( (NiceFloat(nearest.0), nearest.1), if floor.0.to_bits().even() { (NiceFloat(floor.0), floor.1) } else { (NiceFloat(ceiling.0), ceiling.1) } ); }); integer_rounding_mode_pair_gen_var_1::().test_properties(|(n, rm)| { let r: Rational = ExactFrom::exact_from(&n); let (f, o) = T::rounding_from(r, rm); let (f_alt, o_alt) = T::rounding_from(&n, rm); assert_eq!(NiceFloat(f), NiceFloat(f_alt)); assert_eq!(o, o_alt); }); } #[test] fn float_rounding_from_rational_properties() { apply_fn_to_primitive_floats!(float_rounding_from_rational_properties_helper); let max = Rational::exact_from(f32::MAX_FINITE); rational_gen().test_properties(|x| { if x.lt_abs(&max) { let f = f32::rounding_from(&x, Down).0; if NiceFloat(f) != NiceFloat(-0.0) { assert_eq!(NiceFloat(f), NiceFloat(rug::Rational::from(&x).to_f32())); } } assert_eq!( NiceFloat(f64::rounding_from(&x, Down).0), NiceFloat(rug::Rational::from(&x).to_f64()) ); }); } #[allow(clippy::trait_duplication_in_bounds)] fn float_try_from_rational_properties_helper< T: TryFrom + for<'a> TryFrom<&'a Integer> + for<'a> TryFrom<&'a Rational, Error = FloatFromRationalError> + for<'a> ConvertibleFrom<&'a Rational> + PrimitiveFloat + for<'a> RoundingFrom<&'a Rational>, >() where Natural: TryFrom, Rational: TryFrom, { rational_gen().test_properties(|n| { let of = T::try_from(&n); assert_eq!( T::try_from(n.clone()).map(NiceFloat), of.map(|f| NiceFloat(f)) ); assert_eq!( T::try_from(-&n).map(NiceFloat), of.map(|f| NiceFloat(if n == 0 { T::ZERO } else { -f })) ); }); rational_gen_var_4::().test_properties(|n| { let f = T::exact_from(&n); assert_eq!(NiceFloat(f), NiceFloat(T::rounding_from(&n, Exact).0)); assert_eq!(Rational::exact_from(f), n); }); rational_gen_var_5::().test_properties(|n| { assert!(T::try_from(n).is_err()); }); rational_gen_var_6::().test_properties(|n| { assert!(T::try_from(n).is_err()); }); integer_gen().test_properties(|n| { if let Ok(f) = T::try_from(&n) { let rn: Rational = From::from(&n); assert_eq!(NiceFloat(f), NiceFloat(T::exact_from(rn))); } }); integer_gen_var_1::().test_properties(|n| { let rn: Rational = From::from(&n); assert_eq!(NiceFloat(T::exact_from(&n)), NiceFloat(T::exact_from(rn))); }); } #[test] fn float_try_from_rational_properties() { apply_fn_to_primitive_floats!(float_try_from_rational_properties_helper); } #[allow(clippy::trait_duplication_in_bounds)] fn float_convertible_from_rational_properties_helper< T: ConvertibleFrom + for<'a> ConvertibleFrom<&'a Integer> + for<'a> ConvertibleFrom<&'a Rational> + PrimitiveFloat, >() where Rational: TryFrom, { rational_gen().test_properties(|n| { assert_eq!(T::convertible_from(&n), T::convertible_from(-n)); }); rational_gen_var_4::().test_properties(|n| { assert!(T::convertible_from(n)); }); rational_gen_var_5::().test_properties(|n| { assert!(!T::convertible_from(n)); }); rational_gen_var_6::().test_properties(|n| { assert!(!T::convertible_from(n)); }); integer_gen().test_properties(|n| { let rn: Rational = ExactFrom::exact_from(&n); assert_eq!(T::convertible_from(&n), T::convertible_from(&rn)); }); } #[test] fn float_convertible_from_rational_properties() { apply_fn_to_primitive_floats!(float_convertible_from_rational_properties_helper); }