1 // Adapted from https://github.com/Alexhuszagh/rust-lexical.
2 
3 use crate::lexical::algorithm::*;
4 use crate::lexical::num::Float;
5 
6 #[test]
float_fast_path_test()7 fn float_fast_path_test() {
8     // valid
9     let mantissa = (1 << f32::MANTISSA_SIZE) - 1;
10     let (min_exp, max_exp) = f32::exponent_limit();
11     for exp in min_exp..=max_exp {
12         let f = fast_path::<f32>(mantissa, exp);
13         assert!(f.is_some(), "should be valid {:?}.", (mantissa, exp));
14     }
15 
16     // Check slightly above valid exponents
17     let f = fast_path::<f32>(123, 15);
18     assert_eq!(f, Some(1.23e+17));
19 
20     // Exponent is 1 too high, pushes over the mantissa.
21     let f = fast_path::<f32>(123, 16);
22     assert!(f.is_none());
23 
24     // Mantissa is too large, checked_mul should overflow.
25     let f = fast_path::<f32>(mantissa, 11);
26     assert!(f.is_none());
27 
28     // invalid exponents
29     let (min_exp, max_exp) = f32::exponent_limit();
30     let f = fast_path::<f32>(mantissa, min_exp - 1);
31     assert!(f.is_none(), "exponent under min_exp");
32 
33     let f = fast_path::<f32>(mantissa, max_exp + 1);
34     assert!(f.is_none(), "exponent above max_exp");
35 }
36 
37 #[test]
double_fast_path_test()38 fn double_fast_path_test() {
39     // valid
40     let mantissa = (1 << f64::MANTISSA_SIZE) - 1;
41     let (min_exp, max_exp) = f64::exponent_limit();
42     for exp in min_exp..=max_exp {
43         let f = fast_path::<f64>(mantissa, exp);
44         assert!(f.is_some(), "should be valid {:?}.", (mantissa, exp));
45     }
46 
47     // invalid exponents
48     let (min_exp, max_exp) = f64::exponent_limit();
49     let f = fast_path::<f64>(mantissa, min_exp - 1);
50     assert!(f.is_none(), "exponent under min_exp");
51 
52     let f = fast_path::<f64>(mantissa, max_exp + 1);
53     assert!(f.is_none(), "exponent above max_exp");
54 
55     assert_eq!(
56         Some(0.04628372940652459),
57         fast_path::<f64>(4628372940652459, -17)
58     );
59     assert_eq!(None, fast_path::<f64>(26383446160308229, -272));
60 }
61 
62 #[test]
moderate_path_test()63 fn moderate_path_test() {
64     let (f, valid) = moderate_path::<f64>(1234567890, -1, false);
65     assert!(valid, "should be valid");
66     assert_eq!(f.into_float::<f64>(), 123456789.0);
67 
68     let (f, valid) = moderate_path::<f64>(1234567891, -1, false);
69     assert!(valid, "should be valid");
70     assert_eq!(f.into_float::<f64>(), 123456789.1);
71 
72     let (f, valid) = moderate_path::<f64>(12345678912, -2, false);
73     assert!(valid, "should be valid");
74     assert_eq!(f.into_float::<f64>(), 123456789.12);
75 
76     let (f, valid) = moderate_path::<f64>(123456789123, -3, false);
77     assert!(valid, "should be valid");
78     assert_eq!(f.into_float::<f64>(), 123456789.123);
79 
80     let (f, valid) = moderate_path::<f64>(1234567891234, -4, false);
81     assert!(valid, "should be valid");
82     assert_eq!(f.into_float::<f64>(), 123456789.1234);
83 
84     let (f, valid) = moderate_path::<f64>(12345678912345, -5, false);
85     assert!(valid, "should be valid");
86     assert_eq!(f.into_float::<f64>(), 123456789.12345);
87 
88     let (f, valid) = moderate_path::<f64>(123456789123456, -6, false);
89     assert!(valid, "should be valid");
90     assert_eq!(f.into_float::<f64>(), 123456789.123456);
91 
92     let (f, valid) = moderate_path::<f64>(1234567891234567, -7, false);
93     assert!(valid, "should be valid");
94     assert_eq!(f.into_float::<f64>(), 123456789.1234567);
95 
96     let (f, valid) = moderate_path::<f64>(12345678912345679, -8, false);
97     assert!(valid, "should be valid");
98     assert_eq!(f.into_float::<f64>(), 123456789.12345679);
99 
100     let (f, valid) = moderate_path::<f64>(4628372940652459, -17, false);
101     assert!(valid, "should be valid");
102     assert_eq!(f.into_float::<f64>(), 0.04628372940652459);
103 
104     let (f, valid) = moderate_path::<f64>(26383446160308229, -272, false);
105     assert!(valid, "should be valid");
106     assert_eq!(f.into_float::<f64>(), 2.6383446160308229e-256);
107 
108     let (_, valid) = moderate_path::<f64>(26383446160308230, -272, false);
109     assert!(!valid, "should be invalid");
110 }
111