devela/num/float/wrapper/
libm_std.rs
1use crate::Float;
12
13#[cfg(feature = "dep_libm")]
14mod _libm {
15 use super::{super::super::shared_docs::*, impl_fp, Float};
16 use crate::{_dep::libm::Libm, iif};
17
18 impl_fp![libm:f*:
20 r"The largest integer less than or equal to `x`.
21 $$ \lfloor x \rfloor = \max \{ n \in \mathbb{Z} \,|\, n \leq x \} $$ "
22 floor = floor: ;
23 r"The smallest integer greater than or equal to `x`.
24 $$ \lceil x \rceil = \min \{ n \in \mathbb{Z} \,|\, n \geq x \} $$"
25 ceil = ceil: ;
26 "The nearest integer to itself, rounding ties away from `0.0`."
27 round = round_ties_away: ;
28 "The integral part."
29 trunc = trunc: ;
30 "Fused multiply-add. Computes (self * mul) + add with only one rounding error."
36 fma = mul_add: mul, add;
37 "Raises itself to the `p` floating point power."
40 pow = powf: p;
41 "Square root."
43 sqrt = sqrt: ;
44 "$e^x$ (the exponential function)."
45 exp = exp: ;
46 "$2^x$."
47 exp2 = exp2: ;
48 "$e^x -1$, more accurately for small values of `x`."
49 expm1 = exp_m1: ;
50 "The natural logarithm."
52 log = ln: ;
53 "The natural logarithm plus 1, more accurately."
54 log1p = ln_1p: ;
55 "The base 2 logarithm."
57 log2 = log2: ;
58 "The base 10 logarithm."
59 log10 = log10: ;
60 "The cubic root."
61 cbrt = cbrt: ;
62 "The hypothenuse (the euclidean distance)."
63 hypot = hypot: other;
64 "The sine."
65 sin = sin: ;
66 "The cosine."
67 cos = cos: ;
68 "The tangent."
69 tan = tan: ;
70 "The arc sine."
71 asin = asin: ;
72 "The arc cosine."
73 acos = acos: ;
74 "The arc tangent."
75 atan = atan: ;
76 "The arc tangent of two variables."
77 atan2 = atan2: other;
78 "The hyperbolic sine."
80 sinh = sinh: ;
81 "The hyperbolic cosine."
82 cosh = cosh: ;
83 "The hyperbolic tangent."
84 tanh = tanh: ;
85 "The inverse hyperbolic sine."
86 asinh = asinh: ;
87 "The inverse hyperbolic cosine."
88 acosh = acosh: ;
89 "The inverse hyperbolic tangent."
90 atanh = atanh: ;
91 "`10^x`."
97 exp10 = exp10: ;
98 "The gamma function. Generalizes the factorial function to complex numbers."
99 tgamma = gamma: ;
100 "The natural logarithm of the absolute value of the gamma function."
101 lgamma = lgamma: ;
102 "The error function."
103 erf = erf: ;
104 "The complementary error function (1 - erf)."
105 erfc = erfc: ;
106 "The bessel function of the first kind, of order 0."
107 j0 = j0: ;
108 "The bessel function of the first kind, of order 1."
109 j1 = j1: ;
110 "The bessel function of the second kind, of order 0."
112 y0 = y0: ;
113 "The bessel function of the second kind, of order 1."
114 y1 = y1:
115 ]; macro_rules! custom_impls {
122 () => {
123 custom_impls![(f32, i32):"_float_f32", (f64, i32):"_float_f64"];
124 };
125
126 ($( ($f:ty, $e:ty): $cap:literal ),+) => {
127 $( custom_impls![@$f, $e, $cap]; )+
128 };
129 (@$f:ty, $e:ty, $cap:literal) => {
130 #[doc = crate::doc_availability!(feature = $cap)]
131 #[cfg(feature = $cap )]
134 impl Float<$f> {
136 #[doc = FORMULA_FRACT!()]
139 pub fn fract(self) -> Float<$f> { Float(self.0 - Libm::<$f>::trunc(self.0)) }
140
141 #[doc = FORMULA_SPLIT!()]
144 pub fn split(self) -> (Float<$f>, Float<$f>) {
145 let (i, f) = Libm::<$f>::modf(self.0);
146 (Self(i), Self(f))
147 }
148
149 pub fn round_ties_even(self) -> Float<$f> {
151 let r = self.round_ties_away();
152 iif![r.0 % 2.0 == 0.0; r;
153 iif![(self - r).abs() == 0.5; r - self.signum(); r]]
154 }
155
156 pub fn powi(self, p: $e) -> Float<$f> { self.powf(p as $f) }
158
159 pub fn log(self, base: $f) -> Float<$f> {
161 Float(Float(base).ln().0 / self.ln().0)
163 }
164
165 pub fn sin_cos(self) -> (Float<$f>, Float<$f>) {
167 let (sin, cos) = Libm::<$f>::sincos(self.0);
168 (Float(sin), Float(cos))
169 }
170
171 pub fn lgamma_r(self) -> (Float<$f>, $e) {
176 let (f, sign) = Libm::<$f>::lgamma_r(self.0);
177 (Float(f), sign)
178 }
179 pub fn jn(self, n: $e) -> Float<$f> { Float(Libm::<$f>::jn(n, self.0)) }
181 pub fn yn(self, n: $e) -> Float<$f> { Float(Libm::<$f>::yn(n, self.0)) }
183 }
184 };
185 }
186 custom_impls!();
187}
188
189#[cfg(all(not(feature = "dep_libm"), feature = "std"))]
190mod _std {
191 use super::{super::super::shared_docs::*, impl_fp, Float};
192
193 impl_fp![std:f*:
195 r"The largest integer less than or equal to `x`.
196 $$ \lfloor x \rfloor = \max \{ n \in \mathbb{Z} \,|\, n \leq x \} $$ "
197 floor = floor: ;
198 r"The smallest integer greater than or equal to `x`.
199 $$ \lceil x \rceil = \min \{ n \in \mathbb{Z} \,|\, n \geq x \} $$"
200 ceil = ceil: ;
201 "The nearest integer to `x`, rounding ties away from `0.0`."
202 round = round_ties_away: ;
203 "The nearest integer to `x`, rounding ties to the nearest even integer."
204 round_ties_even = round_ties_even: ;
205 r"The integral part.
206 $$ \text{trunc}(x) = \begin{cases}
207 \lfloor x \rfloor, & \text{if } x \geq 0 \\
208 \lceil x \rceil, & \text{if } x < 0
209 \end{cases} $$"
210 trunc = trunc: ;
211 r"The fractional part.
212 $$ \text{fract}(x) = x - \text{trunc}(x) $$"
213 fract = fract: ;
214 "Fused multiply-add. Computes (self * mul) + add with only one rounding error."
219 mul_add = mul_add: mul, add;
220 "Raises itself to the `p` floating point power."
224 powf = powf: p;
225 "The square root."
227 sqrt = sqrt: ;
228 "$e^x$ (the exponential function)."
229 exp = exp: ;
230 "$2^x$."
231 exp2 = exp2: ;
232 "$e^x -1$, more accurately for small values of `x`."
233 exp_m1 = exp_m1: ;
234 "The natural logarithm."
235 ln = ln: ;
236 "The natural logarithm plus 1, more accurately."
237 ln_1p = ln_1p: ;
238 "The logarithm of the number with respect to an arbitrary base."
239 log = log: base;
240 "The base 2 logarithm."
241 log2 = log2: ;
242 "The base 10 logarithm."
243 log10 = log10: ;
244 "The cubic root."
245 cbrt = cbrt: ;
246 "The hypothenuse (the euclidean distance)."
247 hypot = hypot: other;
248 "The sine."
249 sin = sin: ;
250 "The cosine."
251 cos = cos: ;
252 "The tangent."
253 tan = tan: ;
254 "The arc sine."
255 asin = asin: ;
256 "The arc cosine."
257 acos = acos: ;
258 "The arc tangent."
259 atan = atan: ;
260 "The arc tangent of two variables."
261 atan2 = atan2: other;
262 "The hyperbolic sine."
264 sinh = sinh: ;
265 "The hyperbolic cosine."
266 cosh = cosh: ;
267 "The hyperbolic tangent."
268 tanh = tanh: ;
269 "The inverse hyperbolic sine."
270 asinh = asinh: ;
271 "The inverse hyperbolic cosine."
272 acosh = acosh: ;
273 "The inverse hyperbolic tangent."
274 atanh = atanh:
275 ]; macro_rules! custom_impls {
289 () => {
290 custom_impls![(f32, i32):"_float_f32", (f64, i32):"_float_f64"];
291 };
292 ($( ($f:ty, $e:ty): $cap:literal ),+) => {
293 $( custom_impls![@$f, $e, $cap]; )+
294 };
295 (@$f:ty, $e:ty, $cap:literal) => {
296 #[doc = crate::doc_availability!(feature = $cap)]
297 #[cfg(feature = $cap )]
300 impl Float<$f> {
302 pub fn powi(self, p: $e) -> Float<$f> { Float(<$f>::powi(self.0, p)) }
304 pub fn sin_cos(self) -> (Float<$f>, Float<$f>) {
306 let (sin, cos) = <$f>::sin_cos(self.0);
307 (Float(sin), Float(cos))
308 }
309 #[doc = FORMULA_SPLIT!()]
312 pub fn split(self) -> (Float<$f>, Float<$f>) {
313 let trunc = self.trunc();
314 (trunc, Float(self.0 - trunc.0))
315 }
316 }
317 };
318 }
319 custom_impls!();
320}
321
322#[cfg(all(not(feature = "dep_libm"), not(feature = "std")))]
323mod _no_std_no_libm {
324 use super::{super::super::shared_docs::*, Float};
325
326 macro_rules! custom_impls {
331 () => {
332 custom_impls![(f32, u32, i32):"_float_f32", (f64, u64, i32):"_float_f64"];
333 };
334 ($( ($f:ty, $uf:ty, $ie:ty) : $cap:literal ),+) => {
335 $( custom_impls![@$f, $uf, $ie, $cap]; )+
336 };
337 (@$f:ty, $uf:ty, $ie:ty, $cap:literal) => {
338 #[doc = crate::doc_availability!(feature = $cap)]
339 #[cfg(feature = $cap )]
342 impl Float<$f> {
344 #[doc = crate::FORMULA_FLOOR!()]
347 pub const fn floor(self) -> Float<$f> { self.const_floor() }
348
349 #[doc = FORMULA_CEIL!()]
352 pub const fn ceil(self) -> Float<$f> { self.const_ceil() }
353
354 pub const fn round(self) -> Float<$f> { self.const_round() }
358
359 #[doc = FORMULA_ROUND_TIES_AWAY!()]
365 pub const fn round_ties_away(self) -> Float<$f> {self.const_round_ties_away() }
366
367 #[doc = FORMULA_ROUND_TIES_EVEN!()]
370 pub const fn round_ties_even(self) -> Float<$f> { self.const_round_ties_even() }
371
372 #[doc = FORMULA_TRUNC!()]
377 pub const fn trunc(self) -> Float<$f> { self.const_trunc() }
383
384 #[doc = FORMULA_FRACT!()]
387 pub const fn fract(self) -> Float<$f> { self.const_fract() }
388
389 #[doc = FORMULA_SPLIT!()]
392 pub const fn split(self) -> (Float<$f>, Float<$f>) { self.const_split() }
393
394 pub const fn powi(self, p: $ie) -> Float<$f> { self.const_powi(p) }
396 }
397 };
398 }
399 custom_impls!();
400}
401
402#[cfg(any(feature = "dep_libm", feature = "std"))]
410macro_rules! impl_fp {
411 (
412 $lib:ident : f* : $($ops:tt)*
415 ) => {
416 impl_fp![$lib : f32 : $($ops)*];
417 impl_fp![$lib : f64 : $($ops)*];
418 };
419 (
420 $lib:ident : $f:ty : $($ops:tt)*
423 ) => { $crate::paste! {
424 #[doc = "# *This implementation block leverages the `" $lib "` feature.*"]
425 impl Float<$f> {
426 impl_fp![@$lib : $f : $($ops)*];
427 }
428 }};
429 (
430 @$lib:ident : $f:ty : $($doc:literal)? $opfn:ident = $op:ident : $($arg:ident),*
432 ; $($rest:tt)*
433 ) => {
434 impl_fp![@$lib : $f : $($doc)? $opfn = $op : $($arg),*];
435 impl_fp![@$lib : $f : $($rest)*];
436 };
437 (
438 @libm : $f:ty : $($doc:literal)? $opfn:ident = $op:ident : $($arg:ident),* $(;)?
440 ) => {
441 $(#[doc = $doc])?
442 pub fn $op(self, $($arg: $f),*) -> Float<$f> {
443 Float($crate::_dep::libm::Libm::<$f>::$opfn(self.0, $($arg),*))
444 }
445 };
446 (
447 @std : $f:ty : $($doc:literal)? $opfn:ident = $op:ident : $($arg:ident),* $(;)?
449 ) => {
450 $(#[doc = $doc])?
451 pub fn $op(self, $($arg: $f),*) -> Float<$f> {
452 Float(<$f>::$opfn(self.0, $($arg),*))
453 }
454 };
455}
456#[cfg(any(feature = "dep_libm", feature = "std"))]
457use impl_fp;