use half::f16;
pub trait ExactFrom {
#[allow(dead_code)]
fn exact_from_f16(source: f16) -> Option<Self>
where
Self: Sized;
fn exact_from_f32(source: f32) -> Option<Self>
where
Self: Sized;
fn exact_from_f64(source: f64) -> Option<Self>
where
Self: Sized;
fn exact_from_u64(source: u64) -> Option<Self>
where
Self: Sized;
#[allow(dead_code)]
fn exact_from_i64(source: i64) -> Option<Self>
where
Self: Sized;
#[allow(dead_code)]
fn exact_from_u128(source: u128) -> Option<Self>
where
Self: Sized;
#[allow(dead_code)]
fn exact_from_i128(source: i128) -> Option<Self>
where
Self: Sized;
}
impl ExactFrom for i16 {
fn exact_from_f16(source: f16) -> Option<Self> {
let source = source.to_f64();
if !source.is_finite() {
return None;
}
if source <= -32768.0 || source >= 32768.0 {
return None;
}
if source.fract() != 0.0 {
return None;
}
Some(source as i16)
}
fn exact_from_f32(source: f32) -> Option<Self> {
if !source.is_finite() {
return None;
}
if source <= -32769.0 || source >= 32768.0 {
return None;
}
if source.fract() != 0.0 {
return None;
}
Some(source as i16)
}
fn exact_from_f64(source: f64) -> Option<Self> {
if !source.is_finite() {
return None;
}
if source <= -32769.0 || source >= 32768.0 {
return None;
}
if source.fract() != 0.0 {
return None;
}
Some(source as i16)
}
fn exact_from_u64(source: u64) -> Option<Self>
where
Self: Sized,
{
if source > 32767 {
return None;
}
Some(source as i16)
}
fn exact_from_i64(source: i64) -> Option<Self>
where
Self: Sized,
{
if !(-32768..=32767).contains(&source) {
return None;
}
Some(source as i16)
}
fn exact_from_u128(source: u128) -> Option<Self>
where
Self: Sized,
{
if source > 32767 {
return None;
}
Some(source as i16)
}
fn exact_from_i128(source: i128) -> Option<Self>
where
Self: Sized,
{
if !(-32768..=32767).contains(&source) {
return None;
}
Some(source as i16)
}
}
impl ExactFrom for i32 {
fn exact_from_f16(source: f16) -> Option<Self> {
let source = source.to_f64();
if !source.is_finite() {
return None;
}
if source.fract() != 0.0 {
return None;
}
Some(source as i32)
}
fn exact_from_f32(source: f32) -> Option<Self> {
if !source.is_finite() {
return None;
}
if source <= -2147483904.0 || source >= 2147483648.0 {
return None;
}
if source.fract() != 0.0 {
return None;
}
Some(source as i32)
}
fn exact_from_f64(source: f64) -> Option<Self> {
if !source.is_finite() {
return None;
}
if source <= -2147483649.0 || source >= 2147483648.0 {
return None;
}
if source.fract() != 0.0 {
return None;
}
Some(source as i32)
}
fn exact_from_u64(source: u64) -> Option<Self>
where
Self: Sized,
{
if source > 2147483647 {
return None;
}
Some(source as i32)
}
fn exact_from_i64(source: i64) -> Option<Self>
where
Self: Sized,
{
if !(-2147483648..=2147483647).contains(&source) {
return None;
}
Some(source as i32)
}
fn exact_from_u128(source: u128) -> Option<Self>
where
Self: Sized,
{
if source > 2147483647 {
return None;
}
Some(source as i32)
}
fn exact_from_i128(source: i128) -> Option<Self>
where
Self: Sized,
{
if !(-2147483648..=2147483647).contains(&source) {
return None;
}
Some(source as i32)
}
}
impl ExactFrom for i64 {
fn exact_from_f16(source: f16) -> Option<Self> {
let source = source.to_f64();
if !source.is_finite() {
return None;
}
if source.fract() != 0.0 {
return None;
}
Some(source as i64)
}
fn exact_from_f32(source: f32) -> Option<Self> {
if !source.is_finite() {
return None;
}
if source <= -9223373136366403584.0 || source >= 9223372036854775808.0 {
return None;
}
if source.fract() != 0.0 {
return None;
}
Some(source as i64)
}
fn exact_from_f64(source: f64) -> Option<Self> {
if !source.is_finite() {
return None;
}
if source <= -9223372036854777856.0 || source >= 9223372036854775808.0 {
return None;
}
if source.fract() != 0.0 {
return None;
}
Some(source as i64)
}
fn exact_from_u64(source: u64) -> Option<Self>
where
Self: Sized,
{
if source > 9223372036854775807 {
return None;
}
Some(source as i64)
}
fn exact_from_i64(source: i64) -> Option<Self>
where
Self: Sized,
{
Some(source)
}
fn exact_from_u128(source: u128) -> Option<Self>
where
Self: Sized,
{
if source > 9223372036854775807 {
return None;
}
Some(source as i64)
}
fn exact_from_i128(source: i128) -> Option<Self>
where
Self: Sized,
{
if !((i64::MIN as i128)..=(i64::MAX as i128)).contains(&source) {
return None;
}
Some(source as i64)
}
}
impl ExactFrom for i128 {
fn exact_from_f16(source: f16) -> Option<Self> {
let source = source.to_f64();
if !source.is_finite() {
return None;
}
if source.fract() != 0.0 {
return None;
}
Some(source as i128)
}
fn exact_from_f32(source: f32) -> Option<Self> {
if !source.is_finite() {
return None;
}
if source.fract() != 0.0 {
return None;
}
Some(source as i128)
}
fn exact_from_f64(source: f64) -> Option<Self> {
if !source.is_finite() {
return None;
}
if source.fract() != 0.0 {
return None;
}
Some(source as i128)
}
fn exact_from_u64(source: u64) -> Option<Self>
where
Self: Sized,
{
Some(source as i128)
}
fn exact_from_i64(source: i64) -> Option<Self>
where
Self: Sized,
{
Some(source as i128)
}
fn exact_from_u128(source: u128) -> Option<Self>
where
Self: Sized,
{
if source > i128::MAX as u128 {
return None;
}
Some(source as i128)
}
fn exact_from_i128(source: i128) -> Option<Self>
where
Self: Sized,
{
Some(source)
}
}
impl ExactFrom for u16 {
fn exact_from_f16(source: f16) -> Option<Self> {
let source = source.to_f64();
if !source.is_finite() {
return None;
}
if source <= -1.0 {
return None;
}
if source.fract() != 0.0 {
return None;
}
Some(source as u16)
}
fn exact_from_f32(source: f32) -> Option<Self> {
if !source.is_finite() {
return None;
}
if source <= -1.0 || source >= 65536.0 {
return None;
}
if source.fract() != 0.0 {
return None;
}
Some(source as u16)
}
fn exact_from_f64(source: f64) -> Option<Self> {
if !source.is_finite() {
return None;
}
if source <= -1.0 || source >= 65536.0 {
return None;
}
if source.fract() != 0.0 {
return None;
}
Some(source as u16)
}
fn exact_from_u64(source: u64) -> Option<Self>
where
Self: Sized,
{
if source > 65535 {
return None;
}
Some(source as u16)
}
fn exact_from_i64(source: i64) -> Option<Self>
where
Self: Sized,
{
if !(0..=65535).contains(&source) {
return None;
}
Some(source as u16)
}
fn exact_from_u128(source: u128) -> Option<Self>
where
Self: Sized,
{
if source > 65535 {
return None;
}
Some(source as u16)
}
fn exact_from_i128(source: i128) -> Option<Self>
where
Self: Sized,
{
if !(0..=65535).contains(&source) {
return None;
}
Some(source as u16)
}
}
impl ExactFrom for u32 {
fn exact_from_f16(source: f16) -> Option<Self> {
let source = source.to_f64();
if !source.is_finite() {
return None;
}
if source <= -1.0 {
return None;
}
if source.fract() != 0.0 {
return None;
}
Some(source as u32)
}
fn exact_from_f32(source: f32) -> Option<Self> {
if !source.is_finite() {
return None;
}
if source <= -1.0 || source >= 4294967296.0 {
return None;
}
if source.fract() != 0.0 {
return None;
}
Some(source as u32)
}
fn exact_from_f64(source: f64) -> Option<Self> {
if !source.is_finite() {
return None;
}
if source <= -1.0 || source >= 4294967296.0 {
return None;
}
if source.fract() != 0.0 {
return None;
}
Some(source as u32)
}
fn exact_from_u64(source: u64) -> Option<Self>
where
Self: Sized,
{
if source > 4294967295 {
return None;
}
Some(source as u32)
}
fn exact_from_i64(source: i64) -> Option<Self>
where
Self: Sized,
{
if !(0..=4294967295).contains(&source) {
return None;
}
Some(source as u32)
}
fn exact_from_u128(source: u128) -> Option<Self>
where
Self: Sized,
{
if source > 4294967295 {
return None;
}
Some(source as u32)
}
fn exact_from_i128(source: i128) -> Option<Self>
where
Self: Sized,
{
if !(0..=4294967295).contains(&source) {
return None;
}
Some(source as u32)
}
}
impl ExactFrom for u64 {
fn exact_from_f16(source: f16) -> Option<Self> {
let source = source.to_f64();
if !source.is_finite() {
return None;
}
if source <= -1.0 {
return None;
}
if source.fract() != 0.0 {
return None;
}
Some(source as u64)
}
fn exact_from_f32(source: f32) -> Option<Self> {
if !source.is_finite() {
return None;
}
if source <= -1.0 || source >= 18446744073709551616.0 {
return None;
}
if source.fract() != 0.0 {
return None;
}
Some(source as u64)
}
fn exact_from_f64(source: f64) -> Option<Self> {
if !source.is_finite() {
return None;
}
if source <= -1.0 || source >= 18446744073709551616.0 {
return None;
}
if source.fract() != 0.0 {
return None;
}
Some(source as u64)
}
fn exact_from_u64(source: u64) -> Option<Self>
where
Self: Sized,
{
Some(source)
}
fn exact_from_i64(source: i64) -> Option<Self>
where
Self: Sized,
{
if source < 0 {
return None;
}
Some(source as u64)
}
fn exact_from_u128(source: u128) -> Option<Self>
where
Self: Sized,
{
if source > u64::MAX as u128 {
return None;
}
Some(source as u64)
}
fn exact_from_i128(source: i128) -> Option<Self>
where
Self: Sized,
{
if !(0..=u64::MAX as i128).contains(&source) {
return None;
}
Some(source as u64)
}
}
impl ExactFrom for u128 {
fn exact_from_f16(source: f16) -> Option<Self> {
let source = source.to_f64();
if !source.is_finite() {
return None;
}
if source <= -1.0 {
return None;
}
if source.fract() != 0.0 {
return None;
}
Some(source as u128)
}
fn exact_from_f32(source: f32) -> Option<Self> {
if !source.is_finite() {
return None;
}
if source <= -1.0 {
return None;
}
if source.fract() != 0.0 {
return None;
}
Some(source as u128)
}
fn exact_from_f64(source: f64) -> Option<Self> {
if !source.is_finite() {
return None;
}
if source <= -1.0 {
return None;
}
if source.fract() != 0.0 {
return None;
}
Some(source as u128)
}
fn exact_from_u64(source: u64) -> Option<Self>
where
Self: Sized,
{
Some(source as u128)
}
fn exact_from_i64(source: i64) -> Option<Self>
where
Self: Sized,
{
if source < 0 {
return None;
}
Some(source as u128)
}
fn exact_from_u128(source: u128) -> Option<Self>
where
Self: Sized,
{
Some(source)
}
fn exact_from_i128(source: i128) -> Option<Self>
where
Self: Sized,
{
if source < 0 {
return None;
}
Some(source as u128)
}
}
impl ExactFrom for f16 {
fn exact_from_f16(source: f16) -> Option<Self> {
if source.is_nan() {
return Some(f16::NAN);
}
Some(source)
}
fn exact_from_f32(source: f32) -> Option<Self> {
if source.is_nan() {
return Some(f16::NAN);
}
if source.is_infinite() {
return Some(f16::from_f32(source));
}
if source > f16::MAX.to_f32() || source < f16::MIN.to_f32() {
return None;
}
let f = f16::from_f32(source);
if f.to_f32() == source { Some(f) } else { None }
}
fn exact_from_f64(source: f64) -> Option<Self> {
if source.is_nan() {
return Some(f16::NAN);
}
if source.is_infinite() {
return Some(f16::from_f64(source));
}
if source > f16::MAX.to_f64() || source < f16::MIN.to_f64() {
return None;
}
let f = f16::from_f64(source);
if f.to_f64() == source { Some(f) } else { None }
}
fn exact_from_u64(source: u64) -> Option<Self>
where
Self: Sized,
{
let f = f16::from_f64(source as f64);
if f.is_infinite() {
return None;
}
if f.to_f64() as u64 == source {
Some(f)
} else {
None
}
}
fn exact_from_i64(source: i64) -> Option<Self>
where
Self: Sized,
{
let f = f16::from_f64(source as f64);
if f.is_infinite() {
return None;
}
if f.to_f64() as i64 == source {
Some(f)
} else {
None
}
}
fn exact_from_u128(source: u128) -> Option<Self>
where
Self: Sized,
{
let f = f16::from_f64(source as f64);
if f.is_infinite() {
return None;
}
if f.to_f64() as u128 == source {
Some(f)
} else {
None
}
}
fn exact_from_i128(source: i128) -> Option<Self>
where
Self: Sized,
{
let f = f16::from_f64(source as f64);
if f.is_infinite() {
return None;
}
if f.to_f64() as i128 == source {
Some(f)
} else {
None
}
}
}
impl ExactFrom for f32 {
fn exact_from_f16(source: f16) -> Option<Self> {
if source.is_nan() {
return Some(f32::NAN);
}
Some(source.to_f32())
}
fn exact_from_f32(source: f32) -> Option<Self> {
if source.is_nan() {
return Some(f32::NAN);
}
Some(source)
}
fn exact_from_f64(source: f64) -> Option<Self> {
if source.is_nan() {
return Some(f32::NAN);
}
let f = source as f32;
if f as f64 == source { Some(f) } else { None }
}
fn exact_from_u64(source: u64) -> Option<Self>
where
Self: Sized,
{
let f = source as f32;
if f as u64 == source { Some(f) } else { None }
}
fn exact_from_i64(source: i64) -> Option<Self>
where
Self: Sized,
{
let f = source as f32;
if f as i64 == source { Some(f) } else { None }
}
fn exact_from_u128(source: u128) -> Option<Self>
where
Self: Sized,
{
let f = source as f32;
if f.is_infinite() {
return None;
}
if f as u128 == source { Some(f) } else { None }
}
fn exact_from_i128(source: i128) -> Option<Self>
where
Self: Sized,
{
if !(-0x8000_0000_i128..=0x7FFF_FFFF_i128).contains(&source) {
return None;
}
let abs_source = source.unsigned_abs();
if abs_source <= 0xFF_FFFF_u128 {
return Some(source as f32);
}
let trailing_zeros = abs_source.trailing_zeros();
if (25..=31).contains(&trailing_zeros) {
return Some(source as f32);
}
None
}
}
impl ExactFrom for f64 {
fn exact_from_f16(source: f16) -> Option<Self> {
if source.is_nan() {
return Some(f64::NAN);
}
Some(source.to_f64())
}
fn exact_from_f32(source: f32) -> Option<Self> {
if source.is_nan() {
return Some(f64::NAN);
}
Some(source as f64)
}
fn exact_from_f64(source: f64) -> Option<Self> {
if source.is_nan() {
return Some(f64::NAN);
}
Some(source)
}
fn exact_from_u64(source: u64) -> Option<Self>
where
Self: Sized,
{
let f = source as f64;
if f as u64 == source { Some(f) } else { None }
}
fn exact_from_i64(source: i64) -> Option<Self>
where
Self: Sized,
{
let f = source as f64;
if f as i64 == source { Some(f) } else { None }
}
fn exact_from_u128(source: u128) -> Option<Self>
where
Self: Sized,
{
let f = source as f64;
if f as u128 == source { Some(f) } else { None }
}
fn exact_from_i128(source: i128) -> Option<Self>
where
Self: Sized,
{
if !(-0x8000_0000_0000_0000_i128..=0x7FFF_FFFF_FFFF_FFFF_i128)
.contains(&source)
{
return None;
}
let abs_source = source.unsigned_abs();
if abs_source <= 0xF_FFFF_FFFF_FFFF_u128 {
return Some(source as f64);
}
let trailing_zeros = abs_source.trailing_zeros();
if (53..=63).contains(&trailing_zeros) {
return Some(source as f64);
}
None
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn text_exact_i16() {
assert_eq!(i16::exact_from_f16(f16::from_f64(21.0)), Some(21));
assert_eq!(i16::exact_from_f16(f16::from_f64(21.5)), None);
assert_eq!(i16::exact_from_f16(f16::from_f64(f64::NAN)), None);
assert_eq!(i16::exact_from_f16(f16::from_f64(f64::INFINITY)), None);
assert_eq!(i16::exact_from_f16(f16::from_f64(f64::NEG_INFINITY)), None);
assert_eq!(i16::exact_from_f32(21.0f32), Some(21));
assert_eq!(i16::exact_from_f32(21.5f32), None);
assert_eq!(i16::exact_from_f32(f32::NAN), None);
assert_eq!(i16::exact_from_f32(f32::INFINITY), None);
assert_eq!(i16::exact_from_f32(f32::NEG_INFINITY), None);
assert_eq!(i16::exact_from_f64(21.0), Some(21));
assert_eq!(i16::exact_from_f64(21.5), None);
assert_eq!(i16::exact_from_f64(f64::NAN), None);
assert_eq!(i16::exact_from_f64(f64::INFINITY), None);
assert_eq!(i16::exact_from_f64(f64::NEG_INFINITY), None);
assert_eq!(i16::exact_from_u64(21u64), Some(21));
assert_eq!(i16::exact_from_u64(u64::MAX), None);
assert_eq!(i16::exact_from_u64(65536u64), None);
assert_eq!(i16::exact_from_i64(21i64), Some(21));
assert_eq!(i16::exact_from_i64(-21i64), Some(-21));
assert_eq!(i16::exact_from_i64(i64::MAX), None);
assert_eq!(i16::exact_from_i64(i64::MIN), None);
assert_eq!(i16::exact_from_i64(-65536i64), None);
assert_eq!(i16::exact_from_u128(21u128), Some(21));
assert_eq!(i16::exact_from_u128(u128::MAX), None);
assert_eq!(i16::exact_from_u128(65536u128), None);
assert_eq!(i16::exact_from_i128(21i128), Some(21));
assert_eq!(i16::exact_from_i128(-21i128), Some(-21));
assert_eq!(i16::exact_from_i128(i128::MAX), None);
assert_eq!(i16::exact_from_i128(i128::MIN), None);
assert_eq!(i16::exact_from_i128(-65536i128), None);
}
#[test]
fn test_exact_i32() {
assert_eq!(i32::exact_from_f16(f16::from_f64(21.0)), Some(21));
assert_eq!(i32::exact_from_f16(f16::from_f64(21.5)), None);
assert_eq!(i32::exact_from_f16(f16::from_f64(f64::NAN)), None);
assert_eq!(i32::exact_from_f16(f16::from_f64(f64::INFINITY)), None);
assert_eq!(i32::exact_from_f16(f16::from_f64(f64::NEG_INFINITY)), None);
assert_eq!(i32::exact_from_f32(21.0f32), Some(21));
assert_eq!(i32::exact_from_f32(21.5f32), None);
assert_eq!(i32::exact_from_f32(f32::NAN), None);
assert_eq!(i32::exact_from_f32(f32::INFINITY), None);
assert_eq!(i32::exact_from_f32(f32::NEG_INFINITY), None);
assert_eq!(i32::exact_from_f64(21.0), Some(21));
assert_eq!(i32::exact_from_f64(21.5), None);
assert_eq!(i32::exact_from_f64(f64::NAN), None);
assert_eq!(i32::exact_from_f64(f64::INFINITY), None);
assert_eq!(i32::exact_from_f64(f64::NEG_INFINITY), None);
assert_eq!(i32::exact_from_u64(21u64), Some(21));
assert_eq!(i32::exact_from_u64(u64::MAX), None);
assert_eq!(i32::exact_from_u64(4294967296u64), None);
assert_eq!(i32::exact_from_i64(21i64), Some(21));
assert_eq!(i32::exact_from_i64(-21i64), Some(-21));
assert_eq!(i32::exact_from_i64(i64::MAX), None);
assert_eq!(i32::exact_from_i64(i64::MIN), None);
assert_eq!(i32::exact_from_i64(-4294967296i64), None);
assert_eq!(i32::exact_from_u128(21u128), Some(21));
assert_eq!(i32::exact_from_u128(u128::MAX), None);
assert_eq!(i32::exact_from_u128(4294967296u128), None);
assert_eq!(i32::exact_from_i128(21i128), Some(21));
assert_eq!(i32::exact_from_i128(-21i128), Some(-21));
assert_eq!(i32::exact_from_i128(i128::MAX), None);
assert_eq!(i32::exact_from_i128(i128::MIN), None);
assert_eq!(i32::exact_from_i128(-4294967296i128), None);
}
#[test]
fn test_exact_i64() {
assert_eq!(i64::exact_from_f16(f16::from_f64(21.0)), Some(21));
assert_eq!(i64::exact_from_f16(f16::from_f64(21.5)), None);
assert_eq!(i64::exact_from_f16(f16::from_f64(f64::NAN)), None);
assert_eq!(i64::exact_from_f16(f16::from_f64(f64::INFINITY)), None);
assert_eq!(i64::exact_from_f16(f16::from_f64(f64::NEG_INFINITY)), None);
assert_eq!(i64::exact_from_f32(21.0f32), Some(21));
assert_eq!(i64::exact_from_f32(21.5f32), None);
assert_eq!(i64::exact_from_f32(f32::NAN), None);
assert_eq!(i64::exact_from_f32(f32::INFINITY), None);
assert_eq!(i64::exact_from_f32(f32::NEG_INFINITY), None);
assert_eq!(i64::exact_from_f64(21.0), Some(21));
assert_eq!(i64::exact_from_f64(21.5), None);
assert_eq!(i64::exact_from_f64(f64::NAN), None);
assert_eq!(i64::exact_from_f64(f64::INFINITY), None);
assert_eq!(i64::exact_from_f64(f64::NEG_INFINITY), None);
assert_eq!(i64::exact_from_u64(21u64), Some(21));
assert_eq!(i64::exact_from_u64(u64::MAX), None);
assert_eq!(i64::exact_from_u64(9223372036854775809u64), None);
assert_eq!(i64::exact_from_i64(21i64), Some(21));
assert_eq!(i64::exact_from_i64(-21i64), Some(-21));
assert_eq!(i64::exact_from_i64(i64::MAX), Some(9223372036854775807));
assert_eq!(i64::exact_from_i64(i64::MIN), Some(-9223372036854775808));
assert_eq!(i64::exact_from_u128(21u128), Some(21));
assert_eq!(i64::exact_from_u128(u128::MAX), None);
assert_eq!(i64::exact_from_u128(9223372036854775809u128), None);
assert_eq!(i64::exact_from_i128(21i128), Some(21));
assert_eq!(i64::exact_from_i128(-21i128), Some(-21));
assert_eq!(i64::exact_from_i128(i128::MAX), None);
assert_eq!(i64::exact_from_i128(i128::MIN), None);
}
#[test]
fn test_exact_i128() {
assert_eq!(i128::exact_from_f16(f16::from_f64(21.0)), Some(21));
assert_eq!(i128::exact_from_f16(f16::from_f64(21.5)), None);
assert_eq!(i128::exact_from_f16(f16::from_f64(f64::NAN)), None);
assert_eq!(i128::exact_from_f16(f16::from_f64(f64::INFINITY)), None);
assert_eq!(
i128::exact_from_f16(f16::from_f64(f64::NEG_INFINITY)),
None
);
assert_eq!(i128::exact_from_f32(21.0f32), Some(21));
assert_eq!(i128::exact_from_f32(21.5f32), None);
assert_eq!(i128::exact_from_f32(f32::NAN), None);
assert_eq!(i128::exact_from_f32(f32::INFINITY), None);
assert_eq!(i128::exact_from_f32(f32::NEG_INFINITY), None);
assert_eq!(i128::exact_from_f64(21.0), Some(21));
assert_eq!(i128::exact_from_f64(21.5), None);
assert_eq!(i128::exact_from_f64(f64::NAN), None);
assert_eq!(i128::exact_from_f64(f64::INFINITY), None);
assert_eq!(i128::exact_from_f64(f64::NEG_INFINITY), None);
assert_eq!(i128::exact_from_u64(21u64), Some(21));
assert_eq!(i128::exact_from_u64(u64::MAX), Some(u64::MAX as i128));
assert_eq!(i128::exact_from_i64(21i64), Some(21));
assert_eq!(i128::exact_from_i64(-21i64), Some(-21));
assert_eq!(i128::exact_from_i64(i64::MAX), Some(i64::MAX as i128));
assert_eq!(i128::exact_from_i64(i64::MIN), Some(i64::MIN as i128));
assert_eq!(i128::exact_from_u128(21u128), Some(21));
assert_eq!(i128::exact_from_u128(u128::MAX), None);
assert_eq!(i128::exact_from_i128(21i128), Some(21));
assert_eq!(i128::exact_from_i128(-21i128), Some(-21));
assert_eq!(i128::exact_from_i128(i128::MAX), Some(i128::MAX));
assert_eq!(i128::exact_from_i128(i128::MIN), Some(i128::MIN));
}
#[test]
fn test_exact_u16() {
assert_eq!(u16::exact_from_f16(f16::from_f64(21.0)), Some(21));
assert_eq!(u16::exact_from_f16(f16::from_f64(21.5)), None);
assert_eq!(u16::exact_from_f16(f16::from_f64(f64::NAN)), None);
assert_eq!(u16::exact_from_f16(f16::from_f64(f64::INFINITY)), None);
assert_eq!(u16::exact_from_f16(f16::from_f64(f64::NEG_INFINITY)), None);
assert_eq!(u16::exact_from_f32(21.0f32), Some(21));
assert_eq!(u16::exact_from_f32(21.5f32), None);
assert_eq!(u16::exact_from_f32(f32::NAN), None);
assert_eq!(u16::exact_from_f32(f32::INFINITY), None);
assert_eq!(u16::exact_from_f32(f32::NEG_INFINITY), None);
assert_eq!(u16::exact_from_f64(21.0), Some(21));
assert_eq!(u16::exact_from_f64(21.5), None);
assert_eq!(u16::exact_from_f64(f64::NAN), None);
assert_eq!(u16::exact_from_f64(f64::INFINITY), None);
assert_eq!(u16::exact_from_f64(f64::NEG_INFINITY), None);
assert_eq!(u16::exact_from_u64(21u64), Some(21));
assert_eq!(u16::exact_from_u64(u64::MAX), None);
assert_eq!(u16::exact_from_u64(65536u64), None);
assert_eq!(u16::exact_from_i64(21i64), Some(21));
assert_eq!(u16::exact_from_i64(-21i64), None);
assert_eq!(u16::exact_from_i64(i64::MAX), None);
assert_eq!(u16::exact_from_i64(i64::MIN), None);
assert_eq!(u16::exact_from_i64(-65536i64), None);
assert_eq!(u16::exact_from_u128(21u128), Some(21));
assert_eq!(u16::exact_from_u128(u128::MAX), None);
assert_eq!(u16::exact_from_u128(65536u128), None);
assert_eq!(u16::exact_from_i128(21i128), Some(21));
assert_eq!(u16::exact_from_i128(-21i128), None);
assert_eq!(u16::exact_from_i128(i128::MAX), None);
assert_eq!(u16::exact_from_i128(i128::MIN), None);
assert_eq!(u16::exact_from_i128(-65536i128), None);
}
#[test]
fn test_exact_u32() {
assert_eq!(u32::exact_from_f16(f16::from_f64(21.0)), Some(21));
assert_eq!(u32::exact_from_f16(f16::from_f64(21.5)), None);
assert_eq!(u32::exact_from_f16(f16::from_f64(f64::NAN)), None);
assert_eq!(u32::exact_from_f16(f16::from_f64(f64::INFINITY)), None);
assert_eq!(u32::exact_from_f16(f16::from_f64(f64::NEG_INFINITY)), None);
assert_eq!(u32::exact_from_f32(21.0f32), Some(21));
assert_eq!(u32::exact_from_f32(21.5f32), None);
assert_eq!(u32::exact_from_f32(f32::NAN), None);
assert_eq!(u32::exact_from_f32(f32::INFINITY), None);
assert_eq!(u32::exact_from_f32(f32::NEG_INFINITY), None);
assert_eq!(u32::exact_from_f64(21.0), Some(21));
assert_eq!(u32::exact_from_f64(21.5), None);
assert_eq!(u32::exact_from_f64(f64::NAN), None);
assert_eq!(u32::exact_from_f64(f64::INFINITY), None);
assert_eq!(u32::exact_from_f64(f64::NEG_INFINITY), None);
assert_eq!(u32::exact_from_u64(21u64), Some(21));
assert_eq!(u32::exact_from_u64(u64::MAX), None);
assert_eq!(u32::exact_from_u64(4294967296u64), None);
assert_eq!(u32::exact_from_i64(21i64), Some(21));
assert_eq!(u32::exact_from_i64(-21i64), None);
assert_eq!(u32::exact_from_i64(i64::MAX), None);
assert_eq!(u32::exact_from_i64(i64::MIN), None);
assert_eq!(u32::exact_from_i64(-4294967296i64), None);
assert_eq!(u32::exact_from_u128(21u128), Some(21));
assert_eq!(u32::exact_from_u128(u128::MAX), None);
assert_eq!(u32::exact_from_u128(4294967296u128), None);
assert_eq!(u32::exact_from_i128(21i128), Some(21));
assert_eq!(u32::exact_from_i128(-21i128), None);
assert_eq!(u32::exact_from_i128(i128::MAX), None);
assert_eq!(u32::exact_from_i128(i128::MIN), None);
assert_eq!(u32::exact_from_i128(-4294967296i128), None);
}
#[test]
fn test_exact_u64() {
assert_eq!(u64::exact_from_f16(f16::from_f64(21.0)), Some(21));
assert_eq!(u64::exact_from_f16(f16::from_f64(21.5)), None);
assert_eq!(u64::exact_from_f16(f16::from_f64(f64::NAN)), None);
assert_eq!(u64::exact_from_f16(f16::from_f64(f64::INFINITY)), None);
assert_eq!(u64::exact_from_f16(f16::from_f64(f64::NEG_INFINITY)), None);
assert_eq!(u64::exact_from_f32(21.0f32), Some(21));
assert_eq!(u64::exact_from_f32(21.5f32), None);
assert_eq!(u64::exact_from_f32(f32::NAN), None);
assert_eq!(u64::exact_from_f32(f32::INFINITY), None);
assert_eq!(u64::exact_from_f32(f32::NEG_INFINITY), None);
assert_eq!(u64::exact_from_f64(21.0), Some(21));
assert_eq!(u64::exact_from_f64(21.5), None);
assert_eq!(u64::exact_from_f64(f64::NAN), None);
assert_eq!(u64::exact_from_f64(f64::INFINITY), None);
assert_eq!(u64::exact_from_f64(f64::NEG_INFINITY), None);
assert_eq!(u64::exact_from_u64(21u64), Some(21));
assert_eq!(u64::exact_from_u64(u64::MAX), Some(18446744073709551615));
assert_eq!(u64::exact_from_i64(21i64), Some(21));
assert_eq!(u64::exact_from_i64(-21i64), None);
assert_eq!(u64::exact_from_i64(i64::MAX), Some(9223372036854775807));
assert_eq!(u64::exact_from_i64(i64::MIN), None);
assert_eq!(u64::exact_from_u128(21u128), Some(21));
assert_eq!(u64::exact_from_u128(u128::MAX), None);
assert_eq!(u64::exact_from_i128(21i128), Some(21));
assert_eq!(u64::exact_from_i128(-21i128), None);
assert_eq!(u64::exact_from_i128(i128::MAX), None);
assert_eq!(u64::exact_from_i128(i128::MIN), None);
}
#[test]
fn test_exact_u128() {
assert_eq!(u128::exact_from_f16(f16::from_f64(21.0)), Some(21));
assert_eq!(u128::exact_from_f16(f16::from_f64(21.5)), None);
assert_eq!(u128::exact_from_f16(f16::from_f64(f64::NAN)), None);
assert_eq!(u128::exact_from_f16(f16::from_f64(f64::INFINITY)), None);
assert_eq!(
u128::exact_from_f16(f16::from_f64(f64::NEG_INFINITY)),
None
);
assert_eq!(u128::exact_from_f32(21.0f32), Some(21));
assert_eq!(u128::exact_from_f32(21.5f32), None);
assert_eq!(u128::exact_from_f32(f32::NAN), None);
assert_eq!(u128::exact_from_f32(f32::INFINITY), None);
assert_eq!(u128::exact_from_f32(f32::NEG_INFINITY), None);
assert_eq!(u128::exact_from_f64(21.0), Some(21));
assert_eq!(u128::exact_from_f64(21.5), None);
assert_eq!(u128::exact_from_f64(f64::NAN), None);
assert_eq!(u128::exact_from_f64(f64::INFINITY), None);
assert_eq!(u128::exact_from_f64(f64::NEG_INFINITY), None);
assert_eq!(u128::exact_from_u64(21u64), Some(21));
assert_eq!(u128::exact_from_u64(u64::MAX), Some(u64::MAX as u128));
assert_eq!(u128::exact_from_i64(21i64), Some(21));
assert_eq!(u128::exact_from_i64(-21i64), None);
assert_eq!(u128::exact_from_i64(i64::MAX), Some(i64::MAX as u128));
assert_eq!(u128::exact_from_i64(i64::MIN), None);
assert_eq!(u128::exact_from_u128(21u128), Some(21));
assert_eq!(u128::exact_from_u128(u128::MAX), Some(u128::MAX));
assert_eq!(u128::exact_from_i128(21i128), Some(21));
assert_eq!(u128::exact_from_i128(-21i128), None);
assert_eq!(u128::exact_from_i128(i128::MAX), Some(i128::MAX as u128));
assert_eq!(u128::exact_from_i128(i128::MIN), None);
}
#[test]
fn test_exact_f16() {
assert_eq!(
f16::exact_from_f16(f16::from_f64(21.0)),
Some(f16::from_f64(21.0))
);
assert_eq!(
f16::exact_from_f16(f16::from_f64(21.5)),
Some(f16::from_f64(21.5))
);
assert!(f16::exact_from_f16(f16::NAN).unwrap().is_nan());
assert_eq!(f16::exact_from_f16(f16::INFINITY), Some(f16::INFINITY));
assert_eq!(
f16::exact_from_f16(f16::NEG_INFINITY),
Some(f16::NEG_INFINITY)
);
assert_eq!(f16::exact_from_f32(21.0f32), Some(f16::from_f64(21.0)));
assert_eq!(f16::exact_from_f32(21.5f32), Some(f16::from_f64(21.5)));
assert!(f16::exact_from_f32(f32::NAN).unwrap().is_nan());
assert_eq!(f16::exact_from_f32(f32::INFINITY), Some(f16::INFINITY));
assert_eq!(
f16::exact_from_f32(f32::NEG_INFINITY),
Some(f16::NEG_INFINITY)
);
assert_eq!(f16::exact_from_f64(21.0), Some(f16::from_f64(21.0)));
assert_eq!(f16::exact_from_f64(21.5), Some(f16::from_f64(21.5)));
assert!(f16::exact_from_f64(f64::NAN).unwrap().is_nan());
assert_eq!(
f16::exact_from_f64(f64::INFINITY),
Some(f16::from_f64(f64::INFINITY))
);
assert_eq!(
f16::exact_from_f64(f64::NEG_INFINITY),
Some(f16::from_f64(f64::NEG_INFINITY))
);
assert_eq!(f16::exact_from_u64(21u64), Some(f16::from_f64(21.0)));
assert_eq!(f16::exact_from_u64(u64::MAX), None);
assert_eq!(f16::exact_from_u64(65536u64), None);
assert_eq!(f16::exact_from_i64(21i64), Some(f16::from_f64(21.0)));
assert_eq!(f16::exact_from_i64(-21i64), Some(f16::from_f64(-21.0)));
assert_eq!(f16::exact_from_i64(i64::MAX), None);
assert_eq!(f16::exact_from_i64(i64::MIN), None);
assert_eq!(f16::exact_from_i64(-65536i64), None);
assert_eq!(f16::exact_from_u128(21u128), Some(f16::from_f64(21.0)));
assert_eq!(f16::exact_from_u128(u128::MAX), None);
assert_eq!(f16::exact_from_u128(65536u128), None);
assert_eq!(f16::exact_from_i128(21i128), Some(f16::from_f64(21.0)));
assert_eq!(f16::exact_from_i128(-21i128), Some(f16::from_f64(-21.0)));
assert_eq!(f16::exact_from_i128(i128::MAX), None);
assert_eq!(f16::exact_from_i128(i128::MIN), None);
assert_eq!(f16::exact_from_i128(-65536i128), None);
}
#[test]
fn test_exact_f32() {
assert_eq!(f32::exact_from_f16(f16::from_f64(21.0)), Some(21.0f32));
assert_eq!(f32::exact_from_f16(f16::from_f64(21.5)), Some(21.5f32));
assert!(f32::exact_from_f16(f16::NAN).unwrap().is_nan());
assert_eq!(f32::exact_from_f16(f16::INFINITY), Some(f32::INFINITY));
assert_eq!(
f32::exact_from_f16(f16::NEG_INFINITY),
Some(f32::NEG_INFINITY)
);
assert_eq!(f32::exact_from_f32(21.0f32), Some(21.0f32));
assert_eq!(f32::exact_from_f32(21.5f32), Some(21.5f32));
assert!(f32::exact_from_f32(f32::NAN).unwrap().is_nan());
assert_eq!(f32::exact_from_f32(f32::INFINITY), Some(f32::INFINITY));
assert_eq!(
f32::exact_from_f32(f32::NEG_INFINITY),
Some(f32::NEG_INFINITY)
);
assert_eq!(f32::exact_from_f64(21.0), Some(21.0f32));
assert_eq!(f32::exact_from_f64(21.5), Some(21.5f32));
assert!(f32::exact_from_f64(f64::NAN).unwrap().is_nan());
assert_eq!(f32::exact_from_f64(f64::INFINITY), Some(f32::INFINITY));
assert_eq!(
f32::exact_from_f64(f64::NEG_INFINITY),
Some(f32::NEG_INFINITY)
);
assert_eq!(f32::exact_from_u64(21u64), Some(21.0f32));
assert_eq!(
f32::exact_from_u64(u64::MAX),
Some(18446744073709551616.0f32)
);
assert_eq!(f32::exact_from_u64(9223372036854775809u64), None);
assert_eq!(f32::exact_from_i64(21i64), Some(21.0f32));
assert_eq!(f32::exact_from_i64(-21i64), Some(-21.0f32));
assert_eq!(
f32::exact_from_i64(i64::MAX),
Some(9223372036854775808.0f32)
);
assert_eq!(
f32::exact_from_i64(i64::MIN),
Some(-9223372036854775808.0f32)
);
assert_eq!(f32::exact_from_i64(-9223372036854775807i64), None);
assert_eq!(f32::exact_from_u128(21u128), Some(21.0f32));
assert_eq!(f32::exact_from_u128(u128::MAX), None);
assert_eq!(f32::exact_from_u128(9223372036854775809u128), None);
assert_eq!(f32::exact_from_i128(21i128), Some(21.0f32));
assert_eq!(f32::exact_from_i128(-21i128), Some(-21.0f32));
assert_eq!(f32::exact_from_i128(i128::MAX), None);
assert_eq!(f32::exact_from_i128(i128::MIN), None);
assert_eq!(f32::exact_from_i128(-9223372036854775807i128), None);
}
#[test]
fn test_exact_f64() {
assert_eq!(f64::exact_from_f16(f16::from_f64(21.0)), Some(21.0));
assert_eq!(f64::exact_from_f16(f16::from_f64(21.5)), Some(21.5));
assert!(f64::exact_from_f16(f16::NAN).unwrap().is_nan());
assert_eq!(f64::exact_from_f16(f16::INFINITY), Some(f64::INFINITY));
assert_eq!(
f64::exact_from_f16(f16::NEG_INFINITY),
Some(f64::NEG_INFINITY)
);
assert_eq!(f64::exact_from_f32(21.0f32), Some(21.0));
assert_eq!(f64::exact_from_f32(21.5f32), Some(21.5));
assert!(f64::exact_from_f32(f32::NAN).unwrap().is_nan());
assert_eq!(f64::exact_from_f32(f32::INFINITY), Some(f64::INFINITY));
assert_eq!(
f64::exact_from_f32(f32::NEG_INFINITY),
Some(f64::NEG_INFINITY)
);
assert_eq!(f64::exact_from_f64(21.0), Some(21.0));
assert_eq!(f64::exact_from_f64(21.5), Some(21.5));
assert!(f64::exact_from_f64(f64::NAN).unwrap().is_nan());
assert_eq!(f64::exact_from_f64(f64::INFINITY), Some(f64::INFINITY));
assert_eq!(
f64::exact_from_f64(f64::NEG_INFINITY),
Some(f64::NEG_INFINITY)
);
assert_eq!(f64::exact_from_u64(21u64), Some(21.0));
assert_eq!(f64::exact_from_u64(u64::MAX), Some(18446744073709551616.0));
assert_eq!(f64::exact_from_u64(9223372036854775809u64), None);
assert_eq!(f64::exact_from_i64(21i64), Some(21.0));
assert_eq!(f64::exact_from_i64(-21i64), Some(-21.0));
assert_eq!(f64::exact_from_i64(i64::MAX), Some(9223372036854775807.0));
assert_eq!(f64::exact_from_i64(i64::MIN), Some(-9223372036854775808.0));
assert_eq!(f64::exact_from_i64(-9223372036854775807i64), None);
assert_eq!(f64::exact_from_u128(21u128), Some(21.0));
assert_eq!(f64::exact_from_u128(u128::MAX), Some(3.402823669209385e38));
assert_eq!(f64::exact_from_u128(9223372036854775809u128), None);
assert_eq!(f64::exact_from_i128(21i128), Some(21.0));
assert_eq!(f64::exact_from_i128(-21i128), Some(-21.0));
assert_eq!(f64::exact_from_i128(i128::MAX), None);
assert_eq!(f64::exact_from_i128(i128::MIN), None);
assert_eq!(f64::exact_from_i128(-9223372036854775807i128), None);
}
#[test]
fn test_exact_u64_from_f64() {
fn test_value(n: f64, i: Option<u64>) {
assert_eq!(u64::exact_from_f64(n), i);
}
test_value(1234.0, Some(1234));
test_value(-1234.0, None);
test_value(18446744073709550000.0, Some(18446744073709549568));
test_value(18446744073709552000.0, None);
test_value(0.0, Some(0));
test_value(-0.0, Some(0));
test_value(0.5, None);
test_value(-0.5, None);
test_value(f64::NAN, None);
test_value(f64::INFINITY, None);
test_value(f64::NEG_INFINITY, None);
test_value(9007199254740991.0, Some(9007199254740991)); test_value(1.0, Some(1));
test_value(5e-324, None);
test_value(u64::MAX as f64, None); test_value((u64::MAX - 1) as f64, None); test_value((u64::MAX - 2) as f64, None);
test_value(1.0000000000000002, None); test_value(4503599627370495.5, None);
test_value(f64::MIN_POSITIVE, None); test_value(f64::MAX, None); }
#[test]
fn test_exact_i64_from_f64_exact() {
fn test_value(n: f64, i: Option<i64>) {
assert_eq!(i64::exact_from_f64(n), i);
}
test_value(0.0, Some(0));
test_value(-0.0, Some(0));
test_value(0.5, None);
test_value(-0.5, None);
test_value(1234.0, Some(1234));
test_value(-1234.0, Some(-1234));
test_value(f64::NAN, None);
test_value(f64::INFINITY, None);
test_value(f64::NEG_INFINITY, None);
test_value(i64::MAX as f64, None);
test_value(i64::MIN as f64, Some(i64::MIN));
test_value(1e-308, None); test_value(-1e-308, None);
test_value((i64::MAX as f64) + 1.0, None);
test_value(1024.0, Some(1024));
test_value(-1024.0, Some(-1024));
test_value(1234.56, None);
test_value(-1234.56, None);
test_value(9007199254740991.0, Some(9007199254740991)); test_value(-9007199254740991.0, Some(-9007199254740991));
test_value(-9223372036854774784.0, Some(-9223372036854774784)); }
}