166 lines
4.5 KiB
Rust
166 lines
4.5 KiB
Rust
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<F: RawFloat>(mantissa: u64, exponent: i32, expected: F) {
|
|
let fp = float::ExtendedFloat80 {
|
|
mant: mantissa,
|
|
exp: exponent,
|
|
};
|
|
assert_eq!(float::extended_to_float::<F>(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::<f64>(0, 0, 0.0);
|
|
extended_to_float::<f64>(1, 0, 5e-324);
|
|
extended_to_float::<f64>(max_mant, max_exp, f64::MAX);
|
|
extended_to_float::<f64>(0, 1076, 9007199254740992.0);
|
|
extended_to_float::<f64>(1, 1076, 9007199254740994.0);
|
|
}
|