use core::fmt;
use core::iter::{Product, Sum};
use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, Sub, SubAssign};
mod sealed {
pub trait Sealed {}
impl Sealed for f32 {}
impl Sealed for f64 {}
}
pub trait Float:
Copy
+ Default
+ PartialEq
+ PartialOrd
+ fmt::Debug
+ fmt::Display
+ fmt::LowerExp
+ Add<Output = Self>
+ Sub<Output = Self>
+ Mul<Output = Self>
+ Div<Output = Self>
+ Rem<Output = Self>
+ Neg<Output = Self>
+ AddAssign
+ SubAssign
+ MulAssign
+ DivAssign
+ Sum
+ Product
+ Send
+ Sync
+ 'static
+ sealed::Sealed
{
const ZERO: Self;
const ONE: Self;
const TWO: Self;
const HALF: Self;
const PI: Self;
const INFINITY: Self;
const NAN: Self;
const EPSILON: Self;
const MIN_POSITIVE: Self;
const MAX: Self;
const MANTISSA_DIGITS: u32;
fn from_f64(x: f64) -> Self;
fn to_f64(self) -> f64;
fn abs(self) -> Self;
fn sqrt(self) -> Self;
fn hypot(self, other: Self) -> Self;
fn atan2(self, other: Self) -> Self;
fn sin_cos(self) -> (Self, Self);
fn exp(self) -> Self;
fn ln(self) -> Self;
fn ln_1p(self) -> Self;
fn powi(self, n: i32) -> Self;
fn mul_add(self, a: Self, b: Self) -> Self;
fn copysign(self, sign: Self) -> Self;
fn max(self, other: Self) -> Self;
fn min(self, other: Self) -> Self;
fn is_finite(self) -> bool;
fn is_infinite(self) -> bool;
fn is_nan(self) -> bool;
fn is_sign_negative(self) -> bool;
}
macro_rules! float {
($t:ident) => {
impl Float for $t {
const ZERO: Self = 0.0;
const ONE: Self = 1.0;
const TWO: Self = 2.0;
const HALF: Self = 0.5;
const PI: Self = core::$t::consts::PI;
const INFINITY: Self = $t::INFINITY;
const NAN: Self = $t::NAN;
const EPSILON: Self = $t::EPSILON;
const MIN_POSITIVE: Self = $t::MIN_POSITIVE;
const MAX: Self = $t::MAX;
const MANTISSA_DIGITS: u32 = $t::MANTISSA_DIGITS;
#[inline]
fn from_f64(x: f64) -> Self {
x as $t
}
#[inline]
fn to_f64(self) -> f64 {
self as f64
}
#[inline]
fn abs(self) -> Self {
$t::abs(self)
}
#[inline]
fn sqrt(self) -> Self {
$t::sqrt(self)
}
#[inline]
fn hypot(self, other: Self) -> Self {
$t::hypot(self, other)
}
#[inline]
fn atan2(self, other: Self) -> Self {
$t::atan2(self, other)
}
#[inline]
fn sin_cos(self) -> (Self, Self) {
$t::sin_cos(self)
}
#[inline]
fn exp(self) -> Self {
$t::exp(self)
}
#[inline]
fn ln(self) -> Self {
$t::ln(self)
}
#[inline]
fn ln_1p(self) -> Self {
$t::ln_1p(self)
}
#[inline]
fn powi(self, n: i32) -> Self {
$t::powi(self, n)
}
#[inline]
fn mul_add(self, a: Self, b: Self) -> Self {
$t::mul_add(self, a, b)
}
#[inline]
fn copysign(self, sign: Self) -> Self {
$t::copysign(self, sign)
}
#[inline]
fn max(self, other: Self) -> Self {
$t::max(self, other)
}
#[inline]
fn min(self, other: Self) -> Self {
$t::min(self, other)
}
#[inline]
fn is_finite(self) -> bool {
$t::is_finite(self)
}
#[inline]
fn is_infinite(self) -> bool {
$t::is_infinite(self)
}
#[inline]
fn is_nan(self) -> bool {
$t::is_nan(self)
}
#[inline]
fn is_sign_negative(self) -> bool {
$t::is_sign_negative(self)
}
}
};
}
float!(f32);
float!(f64);