use std::f32;
use std::f64;
use std::fmt::Debug;
use std::ops::Add;
use std::ops::Div;
use std::ops::Mul;
use std::ops::Neg;
use std::ops::Sub;
pub trait FloatType:
Sized
+ Copy
+ Debug
+ From<i16>
+ PartialEq
+ PartialOrd
+ Neg<Output = Self>
+ Add<Output = Self>
+ Sub<Output = Self>
+ Mul<Output = Self>
+ Div<Output = Self>
{
fn zero() -> Self;
fn one() -> Self;
fn one_third() -> Self;
fn pi() -> Self;
fn two_third_pi() -> Self;
fn sqrt(self) -> Self;
fn cbrt(self) -> Self {
if self < Self::zero() {
-(-self).powf(Self::one_third())
} else {
self.powf(Self::one_third())
}
}
fn atan(self) -> Self;
fn acos(self) -> Self;
fn sin(self) -> Self;
fn cos(self) -> Self;
fn abs(self) -> Self;
fn powf(self, n: Self) -> Self;
}
impl FloatType for f32 {
#[inline]
fn zero() -> Self {
0f32
}
#[inline]
fn one_third() -> Self {
1f32 / 3f32
}
#[inline]
fn one() -> Self {
1f32
}
#[inline]
fn two_third_pi() -> Self {
2f32 * f32::consts::FRAC_PI_3
}
#[inline]
fn pi() -> Self {
f32::consts::PI
}
fn sqrt(self) -> Self {
self.sqrt()
}
fn atan(self) -> Self {
self.atan()
}
fn acos(self) -> Self {
self.acos()
}
fn sin(self) -> Self {
self.sin()
}
fn cos(self) -> Self {
self.cos()
}
fn abs(self) -> Self {
self.abs()
}
fn powf(self, n: Self) -> Self {
self.powf(n)
}
}
impl FloatType for f64 {
#[inline]
fn zero() -> Self {
0f64
}
#[inline]
fn one_third() -> Self {
1f64 / 3f64
}
#[inline]
fn one() -> Self {
1f64
}
#[inline]
fn two_third_pi() -> Self {
2f64 * f64::consts::FRAC_PI_3
}
#[inline]
fn pi() -> Self {
f64::consts::PI
}
fn sqrt(self) -> Self {
self.sqrt()
}
fn atan(self) -> Self {
self.atan()
}
fn acos(self) -> Self {
self.acos()
}
fn sin(self) -> Self {
self.sin()
}
fn cos(self) -> Self {
self.cos()
}
fn abs(self) -> Self {
self.abs()
}
fn powf(self, n: Self) -> Self {
self.powf(n)
}
}
#[test]
fn test_float_cbrt() {
assert_eq!(-8f64.cbrt(), -2f64);
assert_eq!(8f64.cbrt(), 2f64);
assert_eq!(0f32.cbrt(), 0f32);
}