1use core;
2use core::ops::Neg;
3use core::cmp::PartialOrd;
4use core::clone::Clone;
5use num_traits::{Num, Bounded};
6use num_integer::Integer;
7
8pub trait Abs {
9 type Output: Num;
10 fn abs(&self) -> Self::Output;
11 fn sign(&self) -> Self::Output;
12}
13
14macro_rules! impl_abs {
15 ($($num:ty)*) => ($(
16 impl Abs for $num {
17 type Output = $num;
18 #[inline]
19 fn abs(&self) -> $num {
20 self.clone().abs()
21 }
22 fn sign(&self) -> $num {
23 self.signum()
24 }
25 }
26 impl<'a> Abs for &'a $num {
27 type Output = $num;
28 #[inline]
29 fn abs(&self) -> $num {
30 self.clone().abs()
31 }
32 fn sign(&self) -> $num {
33 self.clone().signum()
34 }
35 }
36 )*)
37}
38
39impl_abs!(f32 f64);
40
41pub trait Sqrt {
42 type Output: Num;
43 fn sqrt(self) -> Self::Output;
44}
45
46macro_rules! impl_sqrt {
47 ($($num:ty)*) => ($(
48 impl Sqrt for $num {
49 type Output = $num;
50 #[inline]
51 fn sqrt(self) -> Self {
52 self.sqrt()
53 }
54 }
55 impl<'a> Sqrt for &'a $num {
56 type Output = $num;
57 #[inline]
58 fn sqrt(self) -> $num {
59 self.clone().sqrt()
60 }
61 }
62 )*)
63}
64
65impl_sqrt!(f32 f64);
66
67pub trait GeneralFloat: Num + PartialOrd {
68 type Exponent: Integer;
69 fn radix() -> Self;
70 fn bit_size() -> Self::Exponent;
71 fn epsilon() -> Self;
72 fn radix_powi(p: Self::Exponent) -> Self;
73}
74
75pub trait BinaryFloat: Num + PartialOrd {
76 type Expo: Integer;
77 fn bits() -> Self::Expo;
78 fn eps() -> Self;
79 fn two_powi(p: Self::Expo) -> Self;
80}
81
82impl<T: BinaryFloat> GeneralFloat for T {
83 type Exponent = T::Expo;
84 #[inline]
85 fn radix() -> T {
86 T::one() + T::one()
87 }
88 #[inline]
89 fn bit_size() -> T::Expo {
90 T::bits()
91 }
92 #[inline]
93 fn epsilon() -> T {
94 T::eps()
95 }
96 #[inline]
97 fn radix_powi(p: T::Expo) -> T {
98 T::two_powi(p)
99 }
100}
101
102pub trait BoundedFloat: Bounded + GeneralFloat {
103 fn max_exponent() -> Self::Exponent;
104 fn min_exponent() -> Self::Exponent;
105}
106
107pub trait Overflow: Num + PartialOrd {
108 fn overflow() -> Self;
109 fn neg_overflow() -> Self;
110}
111
112pub trait Infinite: Num + PartialOrd {
113 fn infinity() -> Self;
114 fn neg_infinity() -> Self;
115 fn is_infinite(&self) -> bool;
116}
117
118impl<T: Infinite> Overflow for T {
119 #[inline]
120 fn overflow() -> Self {
121 T::infinity()
122 }
123 #[inline]
124 fn neg_overflow() -> Self {
125 T::neg_infinity()
126 }
127}
128
129pub trait Underflow: Num {
130 fn min_positive() -> Self;
131 fn unit_underflow() -> Self;
132}
133
134pub trait IEEE754Float
135 : Abs<Output=Self> + Sqrt<Output = Self> + Neg<Output = Self> +
136 BinaryFloat + BoundedFloat + Infinite + Underflow
137 {
138 fn nan() -> Self;
139}
140
141macro_rules! impl_fxx {
142 ($fxx:ident, $expo:ty, [$emin:expr,$emax:expr], $bits:expr) => (
143 impl BinaryFloat for $fxx {
144 type Expo = $expo;
145 #[inline]
146 fn bits() -> Self::Expo{
147 $bits
148 }
149 #[inline]
150 fn eps() -> Self{
151 core::$fxx::EPSILON
152 }
153 #[inline]
154 fn two_powi(p: Self::Expo) -> Self{
155 $fxx::radix().powi(p)
156 }
157 }
158 impl BoundedFloat for $fxx {
159 #[inline]
160 fn max_exponent() -> Self::Exponent{
161 $emax
162 }
163 #[inline]
164 fn min_exponent() -> Self::Exponent{
165 $emin
166 }
167 }
168 impl Infinite for $fxx {
169 #[inline]
170 fn infinity() -> Self{
171 core::$fxx::INFINITY
172 }
173 #[inline]
174 fn neg_infinity() -> Self{
175 core::$fxx::NEG_INFINITY
176 }
177 #[inline]
178 fn is_infinite(&self) -> bool{
179 $fxx::is_infinite(*self)
180 }
181 }
182 impl Underflow for $fxx {
183 #[inline]
184 fn min_positive() -> Self{
185 core::$fxx::MIN_POSITIVE
186 }
187 #[inline]
188 fn unit_underflow() -> Self{
189 core::$fxx::MIN_POSITIVE * core::$fxx::EPSILON
190 }
191 }
192 impl IEEE754Float for $fxx {
193 #[inline]
194 fn nan() -> Self {
195 core::$fxx::NAN
196 }
197 }
198 )
199}
200
201impl_fxx!(f32, i32, [-126, 127], 24);
202impl_fxx!(f64, i32, [-1022, 1023], 53);
203
204mod tests {
205 #[test]
206 fn f64abs() {
207 use super::{Abs,IEEE754Float};
208 assert!((-1.0).abs() == <f64 as Abs>::abs(&-1.0f64));
209 assert!(f64::nan().is_nan());
210 }
211}