111 lines
3.8 KiB
Rust
111 lines
3.8 KiB
Rust
// 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::<f32>(mantissa, exp);
|
|
assert!(f.is_some(), "should be valid {:?}.", (mantissa, exp));
|
|
}
|
|
|
|
// Check slightly above valid exponents
|
|
let f = fast_path::<f32>(123, 15);
|
|
assert_eq!(f, Some(1.23e+17));
|
|
|
|
// Exponent is 1 too high, pushes over the mantissa.
|
|
let f = fast_path::<f32>(123, 16);
|
|
assert!(f.is_none());
|
|
|
|
// Mantissa is too large, checked_mul should overflow.
|
|
let f = fast_path::<f32>(mantissa, 11);
|
|
assert!(f.is_none());
|
|
|
|
// invalid exponents
|
|
let (min_exp, max_exp) = f32::exponent_limit();
|
|
let f = fast_path::<f32>(mantissa, min_exp - 1);
|
|
assert!(f.is_none(), "exponent under min_exp");
|
|
|
|
let f = fast_path::<f32>(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::<f64>(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::<f64>(mantissa, min_exp - 1);
|
|
assert!(f.is_none(), "exponent under min_exp");
|
|
|
|
let f = fast_path::<f64>(mantissa, max_exp + 1);
|
|
assert!(f.is_none(), "exponent above max_exp");
|
|
|
|
assert_eq!(
|
|
Some(0.04628372940652459),
|
|
fast_path::<f64>(4628372940652459, -17)
|
|
);
|
|
assert_eq!(None, fast_path::<f64>(26383446160308229, -272));
|
|
}
|
|
|
|
#[test]
|
|
fn moderate_path_test() {
|
|
let (f, valid) = moderate_path::<f64>(1234567890, -1, false);
|
|
assert!(valid, "should be valid");
|
|
assert_eq!(f.into_float::<f64>(), 123456789.0);
|
|
|
|
let (f, valid) = moderate_path::<f64>(1234567891, -1, false);
|
|
assert!(valid, "should be valid");
|
|
assert_eq!(f.into_float::<f64>(), 123456789.1);
|
|
|
|
let (f, valid) = moderate_path::<f64>(12345678912, -2, false);
|
|
assert!(valid, "should be valid");
|
|
assert_eq!(f.into_float::<f64>(), 123456789.12);
|
|
|
|
let (f, valid) = moderate_path::<f64>(123456789123, -3, false);
|
|
assert!(valid, "should be valid");
|
|
assert_eq!(f.into_float::<f64>(), 123456789.123);
|
|
|
|
let (f, valid) = moderate_path::<f64>(1234567891234, -4, false);
|
|
assert!(valid, "should be valid");
|
|
assert_eq!(f.into_float::<f64>(), 123456789.1234);
|
|
|
|
let (f, valid) = moderate_path::<f64>(12345678912345, -5, false);
|
|
assert!(valid, "should be valid");
|
|
assert_eq!(f.into_float::<f64>(), 123456789.12345);
|
|
|
|
let (f, valid) = moderate_path::<f64>(123456789123456, -6, false);
|
|
assert!(valid, "should be valid");
|
|
assert_eq!(f.into_float::<f64>(), 123456789.123456);
|
|
|
|
let (f, valid) = moderate_path::<f64>(1234567891234567, -7, false);
|
|
assert!(valid, "should be valid");
|
|
assert_eq!(f.into_float::<f64>(), 123456789.1234567);
|
|
|
|
let (f, valid) = moderate_path::<f64>(12345678912345679, -8, false);
|
|
assert!(valid, "should be valid");
|
|
assert_eq!(f.into_float::<f64>(), 123456789.12345679);
|
|
|
|
let (f, valid) = moderate_path::<f64>(4628372940652459, -17, false);
|
|
assert!(valid, "should be valid");
|
|
assert_eq!(f.into_float::<f64>(), 0.04628372940652459);
|
|
|
|
let (f, valid) = moderate_path::<f64>(26383446160308229, -272, false);
|
|
assert!(valid, "should be valid");
|
|
assert_eq!(f.into_float::<f64>(), 2.6383446160308229e-256);
|
|
|
|
let (_, valid) = moderate_path::<f64>(26383446160308230, -272, false);
|
|
assert!(!valid, "should be invalid");
|
|
}
|