use lexical_parse_float::float::{self, RawFloat}; use lexical_parse_float::limits::ExactFloat; use lexical_util::num::Float; #[test] fn exponent_fast_path_test() { assert_eq!(f32::min_exponent_fast_path(10), -10); assert_eq!(f32::max_exponent_fast_path(10), 10); assert_eq!(f32::max_exponent_disguised_fast_path(10), 17); assert_eq!(f64::min_exponent_fast_path(10), -22); assert_eq!(f64::max_exponent_fast_path(10), 22); assert_eq!(f64::max_exponent_disguised_fast_path(10), 37); } fn slow_f32_power(exponent: usize, radix: u32) -> f32 { let mut value: f32 = 1.0; for _ in 0..exponent { value *= radix as f32; } value } fn slow_f64_power(exponent: usize, radix: u32) -> f64 { let mut value: f64 = 1.0; for _ in 0..exponent { value *= radix as f64; } value } fn pow_fast_path(radix: u32) { for exponent in 0..f32::exponent_limit(radix).1 + 1 { let exponent = exponent as usize; let actual = f32::pow_fast_path(exponent, radix); assert_eq!(actual, slow_f32_power(exponent, radix)); } for exponent in 0..f64::exponent_limit(radix).1 + 1 { let exponent = exponent as usize; let actual = f64::pow_fast_path(exponent, radix); assert_eq!(actual, slow_f64_power(exponent, radix)); } } #[test] #[cfg_attr(miri, ignore)] fn pow_fast_path_test() { pow_fast_path(10); if cfg!(feature = "power-of-two") { pow_fast_path(2); pow_fast_path(4); pow_fast_path(8); pow_fast_path(16); pow_fast_path(32); } if cfg!(feature = "radix") { pow_fast_path(3); pow_fast_path(5); pow_fast_path(6); pow_fast_path(7); pow_fast_path(9); pow_fast_path(11); pow_fast_path(12); pow_fast_path(13); pow_fast_path(14); pow_fast_path(15); pow_fast_path(17); pow_fast_path(18); pow_fast_path(19); pow_fast_path(20); pow_fast_path(21); pow_fast_path(22); pow_fast_path(23); pow_fast_path(24); pow_fast_path(25); pow_fast_path(26); pow_fast_path(27); pow_fast_path(28); pow_fast_path(29); pow_fast_path(30); pow_fast_path(31); pow_fast_path(33); pow_fast_path(34); pow_fast_path(35); pow_fast_path(36); } } fn slow_int_power(exponent: usize, radix: u32) -> u64 { let mut value: u64 = 1; for _ in 0..exponent { value *= radix as u64; } value } fn int_pow_fast_path(radix: u32) { for exponent in 0..f64::mantissa_limit(radix) { let exponent = exponent as usize; let actual = f64::int_pow_fast_path(exponent, radix); assert_eq!(actual, slow_int_power(exponent, radix)); } } #[test] fn int_pow_fast_path_test() { int_pow_fast_path(10); if cfg!(feature = "power-of-two") { int_pow_fast_path(2); int_pow_fast_path(4); int_pow_fast_path(8); int_pow_fast_path(16); int_pow_fast_path(32); } if cfg!(feature = "radix") { int_pow_fast_path(3); int_pow_fast_path(5); int_pow_fast_path(6); int_pow_fast_path(7); int_pow_fast_path(9); int_pow_fast_path(11); int_pow_fast_path(12); int_pow_fast_path(13); int_pow_fast_path(14); int_pow_fast_path(15); int_pow_fast_path(17); int_pow_fast_path(18); int_pow_fast_path(19); int_pow_fast_path(20); int_pow_fast_path(21); int_pow_fast_path(22); int_pow_fast_path(23); int_pow_fast_path(24); int_pow_fast_path(25); int_pow_fast_path(26); int_pow_fast_path(27); int_pow_fast_path(28); int_pow_fast_path(29); int_pow_fast_path(30); int_pow_fast_path(31); int_pow_fast_path(33); int_pow_fast_path(34); int_pow_fast_path(35); int_pow_fast_path(36); } } fn extended_to_float(mantissa: u64, exponent: i32, expected: F) { let fp = float::ExtendedFloat80 { mant: mantissa, exp: exponent, }; assert_eq!(float::extended_to_float::(fp), expected); } #[test] fn extended_to_float_test() { let max_mant = (1 << f64::MANTISSA_SIZE) - 1; let max_exp = f64::INFINITE_POWER - 1; extended_to_float::(0, 0, 0.0); extended_to_float::(1, 0, 5e-324); extended_to_float::(max_mant, max_exp, f64::MAX); extended_to_float::(0, 1076, 9007199254740992.0); extended_to_float::(1, 1076, 9007199254740994.0); }