// Adapted from https://github.com/Alexhuszagh/rust-lexical. use crate::lexical::algorithm::*; use crate::lexical::num::Float; #[test] fn float_fast_path_test() { // valid let mantissa = (1 << f32::MANTISSA_SIZE) - 1; let (min_exp, max_exp) = f32::exponent_limit(); for exp in min_exp..=max_exp { let f = fast_path::(mantissa, exp); assert!(f.is_some(), "should be valid {:?}.", (mantissa, exp)); } // Check slightly above valid exponents let f = fast_path::(123, 15); assert_eq!(f, Some(1.23e+17)); // Exponent is 1 too high, pushes over the mantissa. let f = fast_path::(123, 16); assert!(f.is_none()); // Mantissa is too large, checked_mul should overflow. let f = fast_path::(mantissa, 11); assert!(f.is_none()); // invalid exponents let (min_exp, max_exp) = f32::exponent_limit(); let f = fast_path::(mantissa, min_exp - 1); assert!(f.is_none(), "exponent under min_exp"); let f = fast_path::(mantissa, max_exp + 1); assert!(f.is_none(), "exponent above max_exp"); } #[test] fn double_fast_path_test() { // valid let mantissa = (1 << f64::MANTISSA_SIZE) - 1; let (min_exp, max_exp) = f64::exponent_limit(); for exp in min_exp..=max_exp { let f = fast_path::(mantissa, exp); assert!(f.is_some(), "should be valid {:?}.", (mantissa, exp)); } // invalid exponents let (min_exp, max_exp) = f64::exponent_limit(); let f = fast_path::(mantissa, min_exp - 1); assert!(f.is_none(), "exponent under min_exp"); let f = fast_path::(mantissa, max_exp + 1); assert!(f.is_none(), "exponent above max_exp"); assert_eq!( Some(0.04628372940652459), fast_path::(4628372940652459, -17) ); assert_eq!(None, fast_path::(26383446160308229, -272)); } #[test] fn moderate_path_test() { let (f, valid) = moderate_path::(1234567890, -1, false); assert!(valid, "should be valid"); assert_eq!(f.into_float::(), 123456789.0); let (f, valid) = moderate_path::(1234567891, -1, false); assert!(valid, "should be valid"); assert_eq!(f.into_float::(), 123456789.1); let (f, valid) = moderate_path::(12345678912, -2, false); assert!(valid, "should be valid"); assert_eq!(f.into_float::(), 123456789.12); let (f, valid) = moderate_path::(123456789123, -3, false); assert!(valid, "should be valid"); assert_eq!(f.into_float::(), 123456789.123); let (f, valid) = moderate_path::(1234567891234, -4, false); assert!(valid, "should be valid"); assert_eq!(f.into_float::(), 123456789.1234); let (f, valid) = moderate_path::(12345678912345, -5, false); assert!(valid, "should be valid"); assert_eq!(f.into_float::(), 123456789.12345); let (f, valid) = moderate_path::(123456789123456, -6, false); assert!(valid, "should be valid"); assert_eq!(f.into_float::(), 123456789.123456); let (f, valid) = moderate_path::(1234567891234567, -7, false); assert!(valid, "should be valid"); assert_eq!(f.into_float::(), 123456789.1234567); let (f, valid) = moderate_path::(12345678912345679, -8, false); assert!(valid, "should be valid"); assert_eq!(f.into_float::(), 123456789.12345679); let (f, valid) = moderate_path::(4628372940652459, -17, false); assert!(valid, "should be valid"); assert_eq!(f.into_float::(), 0.04628372940652459); let (f, valid) = moderate_path::(26383446160308229, -272, false); assert!(valid, "should be valid"); assert_eq!(f.into_float::(), 2.6383446160308229e-256); let (_, valid) = moderate_path::(26383446160308230, -272, false); assert!(!valid, "should be invalid"); }