use approx::{AbsDiffEq, RelativeEq, UlpsEq};
use core::fmt::{Debug, Display};
use core::iter::{Product, Sum};
use core::ops::{AddAssign, DivAssign, MulAssign, SubAssign};
pub trait Float:
num_traits::Float
+ Debug
+ Display
+ Default
+ AddAssign
+ SubAssign
+ MulAssign
+ DivAssign
+ Sum
+ Product
+ AbsDiffEq<Epsilon = Self>
+ RelativeEq
+ UlpsEq
+ 'static
{
const TWO: Self;
const PI: Self;
fn from_i8(value: i8) -> Self;
fn from_usize(value: usize) -> Self;
fn from_f64(value: f64) -> Self;
}
impl Float for f32 {
const TWO: Self = 2.0;
const PI: Self = std::f32::consts::PI;
#[inline]
fn from_i8(value: i8) -> Self {
value as Self
}
#[inline]
fn from_usize(value: usize) -> Self {
value as Self
}
#[inline]
fn from_f64(value: f64) -> Self {
value as Self
}
}
impl Float for f64 {
const TWO: Self = 2.0;
const PI: Self = std::f64::consts::PI;
#[inline]
fn from_i8(value: i8) -> Self {
value as Self
}
#[inline]
fn from_usize(value: usize) -> Self {
value as Self
}
#[inline]
fn from_f64(value: f64) -> Self {
value
}
}
#[cfg(test)]
mod tests {
use super::*;
use proptest::prelude::*;
proptest! {
#[test]
fn f64_from_i8_roundtrip(x in -128i8..127) {
let f = f64::from_i8(x);
prop_assert_eq!(f as i8, x);
}
#[test]
fn f32_from_i8_roundtrip(x in -128i8..127) {
let f = f32::from_i8(x);
prop_assert_eq!(f as i8, x);
}
}
}