devela/num/float/
ext_float.rs

1// devela::num::float::ext_float
2//
3//! Extention trait for floatin-point methods.
4//
5// IMPROVE: remove redundant methods implemented in `core`
6
7use super::shared_docs::*;
8#[cfg(_float··)]
9use crate::Float;
10use crate::{ExtFloatConst, Sign};
11
12#[doc = crate::TAG_NAMESPACE!()]
13/// Extension trait for floating-point types. Associated methods.
14///
15/// This trait can be more convenient to use than the [`Float`] struct,
16/// for non-const operations over primitive floating-point types.
17///
18/// # Features
19/// It depends on having any `_float_f[32|64]` features enabled.
20///
21/// `Float` has a few more methods implemented if the `dep_libm` feature is enabled.
22#[rustfmt::skip]
23pub trait ExtFloat: ExtFloatConst + Sized {
24
25    /// The largest integer less than or equal to `self`.
26    ///
27    /// # Formula
28    #[doc = FORMULA_FLOOR!()]
29    #[must_use]
30    fn floor(self) -> Self;
31
32    /// The smallest integer greater than or equal to `self`.
33    ///
34    /// # Formula
35    #[doc = FORMULA_CEIL!()]
36    #[must_use]
37    fn ceil(self) -> Self;
38
39    /// The nearest integer to `self`, default rounding, same as
40    /// [`round_ties_away`][ExtFloat::round_ties_away]
41    #[must_use]
42    fn round(self) -> Self;
43
44    /// The nearest integer to `self`, rounding ties away from `0.0`.
45    ///
46    /// # Formula
47    #[doc = FORMULA_ROUND_TIES_AWAY!()]
48    #[must_use]
49    fn round_ties_away(self) -> Self;
50
51    /// The nearest integer to `self`, rounding ties to the nearest even integer.
52    ///
53    /// # Formula
54    #[doc = FORMULA_ROUND_TIES_EVEN!()]
55    #[must_use]
56    fn round_ties_even(self) -> Self;
57
58    /// The nearest integer to `self`, rounding ties to the nearest odd integer.
59    ///
60    /// # Formula
61    #[doc = FORMULA_ROUND_TIES_ODD!()]
62    #[must_use]
63    fn round_ties_odd(self) -> Self;
64
65    /// The integral part of `self`.
66    ///
67    /// # Formula
68    #[doc = FORMULA_TRUNC!()]
69    #[must_use]
70    fn trunc(self) -> Self;
71
72    /// The fractional part of `self`.
73    ///
74    /// # Formula
75    #[doc = FORMULA_FRACT!()]
76    #[must_use]
77    fn fract(self) -> Self;
78
79    /// The integral and fractional parts ox `self`.
80    ///
81    /// # Formula
82    #[doc = FORMULA_SPLIT!()]
83    #[must_use]
84    fn split(self) -> (Self, Self);
85
86    /// The absolute value of `self`.
87    #[must_use]
88    fn abs(self) -> Self;
89
90    /// The negative absolute value of `self`.
91    #[must_use]
92    fn neg_abs(self) -> Self;
93
94    /// Returns the `Sign` of `self`.
95    fn sign(self) -> Sign;
96
97    /// Returns the `Sign` of `self`, except for zero.
98    fn sign_nonzero(self) -> Sign;
99
100    /// A number that represents the sign of `self`.
101    #[must_use]
102    fn signum(self) -> Self;
103
104    /// Flips the sign of `self`.
105    #[must_use]
106    fn flip_sign(self) -> Self;
107
108    /// Returns `true` if `self` has a positive sign.
109    #[must_use]
110    fn is_sign_positive(self) -> bool;
111
112    /// Returns `true` if `self` has a negative sign.
113    #[must_use]
114    fn is_sign_negative(self) -> bool;
115
116    /// Returns `true` if `self` is either 0.0 or -0.0.
117    #[must_use]
118    fn is_zero(self) -> bool;
119
120    /// Returns `true` if `self` has a positive sign and is not zero.
121    #[must_use]
122    fn is_sign_positive_nonzero(self) -> bool;
123
124    /// Returns `true` if `self` has a negative sign and is not zero.
125    #[must_use]
126    fn is_sign_negative_nonzero(self) -> bool;
127
128    /// A number composed of a magnitude of `self` and the sign of `sign`.
129    #[must_use]
130    fn copysign(self, sign: Self) -> Self;
131
132    /// Fused multiply-add. Computes `(self * mul) + add` with only one rounding error.
133    ///
134    /// With either `std` or `dep_libm` enabled it leverages compiler intrinsics,
135    /// otherwise it uses [`mul_add_fallback`][Float::mul_add_fallback].
136    #[must_use]
137    fn mul_add(self, mul: Self, add: Self) -> Self;
138
139    /// The euclidean division.
140    #[must_use]
141    fn div_euclid(self, rhs: Self) -> Self;
142
143    /// The least nonnegative remainder of `self % rhs`.
144    #[must_use]
145    fn rem_euclid(self, rhs: Self) -> Self;
146
147    /// Returns `self` between `[min..=max]` scaled to a new range `[u..=v]`.
148    ///
149    /// Values of `self` outside `[min..=max]` are not clamped and will result in extrapolation.
150    /// # Formula
151    #[doc = FORMULA_SCALE!()]
152    #[must_use]
153    fn scale(self, min: Self, max: Self, u: Self, v: Self) -> Self;
154
155    /// Calculates a linearly interpolated value between `u..=v`
156    /// based on the percentage `self` between `[0..=1]`.
157    ///
158    /// Values of `self` outside `[0..=1]` are not clamped and will result in extrapolation.
159    /// # Formula
160    #[doc = FORMULA_LERP!()]
161    #[must_use]
162    fn lerp(self, u: Self, v: Self) -> Self;
163
164    /// Raises `self` to the `y` floating point power.
165    ///
166    /// With either `std` or `dep_libm` enabled it leverages compiler intrinsics,
167    /// otherwise it's equal to [`powf_series`][Float::powf_series].
168    #[must_use]
169    fn powf(self, y: Self) -> Self;
170
171    /// Raises `self` to the `p` integer power.
172    #[must_use]
173    fn powi(self, p: i32) -> Self;
174
175    /// The square root.
176    ///
177    /// With either `std` or `dep_libm` enabled it leverages compiler intrinsics,
178    /// otherwise it's equal to [`sqrt_nr`][Float::sqrt_nr].
179    #[must_use]
180    fn sqrt(self) -> Self;
181
182    /// The square root calculated using the
183    /// [fast inverse square root algorithm](https://en.wikipedia.org/wiki/Fast_inverse_square_root).
184    #[must_use]
185    fn sqrt_fisr(self) -> Self;
186
187    /// $ 1 / \sqrt{x} $ the
188    /// [fast inverse square root algorithm](https://en.wikipedia.org/wiki/Fast_inverse_square_root).
189    #[must_use]
190    fn fisr(self) -> Self;
191
192    /// The cubic root.
193    ///
194    /// With either `std` or `dep_libm` enabled it leverages compiler intrinsics,
195    /// otherwise it's equal to [`cbrt_nr`][Float::cbrt_nr].
196    #[must_use]
197    fn cbrt(self) -> Self;
198
199    /// The hypothenuse (the euclidean distance).
200    ///
201    /// With either `std` or `dep_libm` enabled it leverages compiler intrinsics,
202    /// otherwise it's equal to [`hypot_nr`][Float::hypot_nr].
203    #[must_use]
204    fn hypot(self, rhs: Self) -> Self;
205
206    /// $e^x$ (the exponential function).
207    ///
208    /// The maximum values with a representable result are:
209    /// 88.722… for `f32` and 709.782… for `f64`.
210    ///
211    /// With both `std` and `dep_libm` disabled it leverages [`exp_series`][Float::exp_series]
212    /// with [`exp_series_terms`][Float::exp_series_terms].
213    #[must_use]
214    fn exp(self) -> Self;
215
216    /// $2^x$.
217    ///
218    /// With both `std` and `dep_libm` disabled it leverages [`exp2_series`][Float::exp2_series]
219    /// with [`exp2_series_terms`][Float::exp2_series_terms].
220    #[must_use]
221    fn exp2(self) -> Self;
222
223    /// The exponential minus 1, more accurately.
224    ///
225    /// With both `std` and `dep_libm` disabled it leverages [`exp_m1_series`][Float::exp_m1_series]
226    /// with [`exp_series_terms`][Float::exp_series_terms].
227    #[must_use]
228    fn exp_m1(self) -> Self;
229
230    /// The natural logarithm of `self`.
231    ///
232    /// With both `std` and `dep_libm` disabled it leverages [`ln_series`][Float::ln_series]
233    /// with [`ln_series_terms`][Float::ln_series_terms].
234    #[must_use]
235    fn ln(self) -> Self;
236
237    /// The natural logarithm of `self` plus 1, more accurately.
238    ///
239    /// With both `std` and `dep_libm` disabled it leverages [`ln_1p_series`][Float::ln_1p_series]
240    /// with [`ln_series_terms`][Float::ln_series_terms].
241    #[must_use]
242    fn ln_1p(self) -> Self;
243
244    /// The logarithm of `self` with respect to an arbitrary `base`.
245    ///
246    /// With both `std` and `dep_libm` disabled it leverages [`log_series`][Float::log_series]
247    /// with [`ln_series_terms`][Float::ln_series_terms].
248    #[must_use]
249    fn log(self, base: Self) -> Self;
250
251    /// The base 2 logarithm of `self`.
252    ///
253    /// With both `std` and `dep_libm` disabled it leverages [`log2_series`][Float::log2_series]
254    /// with [`ln_series_terms`][Float::ln_series_terms].
255    #[must_use]
256    fn log2(self) -> Self;
257
258    /// The base 10 logarithm of `self`.
259    ///
260    /// With both `std` and `dep_libm` disabled it leverages [`log10_series`][Float::log10_series]
261    /// with [`ln_series_terms`][Float::ln_series_terms].
262    #[must_use]
263    fn log10(self) -> Self;
264
265    /// The factorial.
266    ///
267    /// The maximum values with a representable result are:
268    /// 34 for `f32` and 170 for `f64`.
269    #[must_use]
270    fn factorial(n: u32) -> Self;
271
272    /// The sine.
273    ///
274    /// With both `std` and `dep_libm` disabled it leverages
275    /// [`sin_series`][Float::sin_series] with 8 terms.
276    #[must_use]
277    fn sin(self) -> Self;
278
279    /// The cosine.
280    ///
281    /// With both `std` and `dep_libm` disabled it leverages
282    /// [`cos_series`][Float::cos_series] with 8 terms.
283    #[must_use]
284    fn cos(self) -> Self;
285
286    /// Both the sine and cosine.
287    ///
288    /// With both `std` and `dep_libm` disabled it leverages
289    /// [`sin_cos_series`][Float::sin_cos_series] with 8 terms.
290    #[must_use]
291    fn sin_cos(self) -> (Self, Self);
292
293    /// The tangent.
294    ///
295    /// With both `std` and `dep_libm` disabled it leverages
296    /// [`tan_series`][Float::tan_series] with 8 terms.
297    #[must_use]
298    fn tan(self) -> Self;
299
300    /// The arc sine.
301    ///
302    /// With both `std` and `dep_libm` disabled it leverages [`asin_series`][Float::asin_series]
303    /// with [`asin_series_terms`][Float::asin_series_terms].
304    #[must_use]
305    fn asin(self) -> Self;
306
307    /// The arc cosine.
308    ///
309    /// With both `std` and `dep_libm` disabled it leverages [`acos_series`][Float::acos_series]
310    /// with [`acos_series_terms`][Float::acos_series_terms].
311    #[must_use]
312    fn acos(self) -> Self;
313
314    /// The arc tangent.
315    ///
316    /// With both `std` and `dep_libm` disabled it leverages [`atan_series`][Float::atan_series]
317    /// with [`atan_series_terms`][Float::atan_series_terms].
318    #[must_use]
319    fn atan(self) -> Self;
320
321    /// The arc tangent of two variables.
322    ///
323    /// With both `std` and `dep_libm` disabled it leverages [`atan2_series`][Float::atan2_series]
324    /// with [`atan_series_terms`][Float::atan_series_terms].
325    #[must_use]
326    fn atan2(self, other: Self) -> Self;
327
328    /// The hyperbolic sine.
329    ///
330    /// With both `std` and `dep_libm` disabled it leverages [`sinh_series`][Float::sinh_series]
331    /// with [`exp_series_terms`][Float::exp_series_terms].
332    #[must_use]
333    fn sinh(self) -> Self;
334
335    /// The hyperbolic cosine.
336    ///
337    /// With both `std` and `dep_libm` disabled it leverages [`cosh_series`][Float::cosh_series]
338    /// with [`exp_series_terms`][Float::exp_series_terms].
339    #[must_use]
340    fn cosh(self) -> Self;
341
342    /// The hyperbolic tangent.
343    ///
344    /// With both `std` and `dep_libm` disabled it leverages [`cosh_series`][Float::cosh_series]
345    /// with [`exp_series_terms`][Float::exp_series_terms].
346    #[must_use]
347    fn tanh(self) -> Self;
348
349    /// The inverse hyperbolic sine of `self`.
350    ///
351    /// With both `std` and `dep_libm` disabled it leverages [`asinh_series`][Float::asinh_series]
352    /// with [`ln_series_terms`][Float::ln_series_terms].
353    #[must_use]
354    fn asinh(self) -> Self;
355
356    /// The inverse hyperbolic cosine of `self`.
357    ///
358    /// With both `std` and `dep_libm` disabled it leverages [`acosh_series`][Float::acosh_series]
359    /// with [`ln_series_terms`][Float::ln_series_terms].
360    #[must_use]
361    fn acosh(self) -> Self;
362
363    /// The inverse hyperbolic tangent of `self`.
364    ///
365    /// With both `std` and `dep_libm` disabled it leverages [`atanh_series`][Float::atanh_series]
366    /// with [`ln_series_terms`][Float::ln_series_terms].
367    #[must_use]
368    fn atanh(self) -> Self;
369
370    /// The clamped value, propagating `NaN`.
371    #[must_use]
372    fn clamp_nan(self, min: Self, max: Self) -> Self;
373
374    /// The maximum of two numbers, propagating `NaN`.
375    #[must_use]
376    fn max_nan(self, other: Self) -> Self;
377
378    /// The minimum of two numbers, propagating `NaN`.
379    #[must_use]
380    fn min_nan(self, other: Self) -> Self;
381
382    /// The clamped value, using total order.
383    ///
384    /// # Features
385    /// This will only work if the corresponding `_cmp_[f32|f64]` feature is enabled,
386    /// otherwise it will return `NaN`.
387    #[must_use]
388    fn clamp_total(self, min: Self, max: Self) -> Self;
389
390    /// The maximum of two numbers using total order.
391    ///
392    /// # Features
393    /// This will only work if the corresponding `_cmp_[f32|f64]` feature is enabled,
394    /// otherwise it will return `NaN`.
395    #[must_use]
396    fn max_total(self, other: Self) -> Self;
397
398    /// The minimum of two numbers using total order.
399    ///
400    /// # Features
401    /// This will only work if the corresponding `_cmp_[f32|f64]` feature is enabled,
402    /// otherwise it will return `NaN`.
403    #[must_use]
404    fn min_total(self, other: Self) -> Self;
405
406    /// Evaluates a polynomial at the `self` point value, using [Horner's method].
407    ///
408    /// [Horner's method]: https://en.wikipedia.org/wiki/Horner%27s_method#Polynomial_evaluation_and_long_division
409    #[must_use]
410    fn eval_poly(self, coefficients: &[Self]) -> Self;
411
412    /// Approximates the derivative of the 1D function `f` at `x` point using step size `h`.
413    ///
414    /// Uses the [finite difference method].
415    ///
416    /// See also the [`autodiff`] attr macro, enabled with the `nightly_autodiff` feature.
417    ///
418    /// [finite difference method]: https://en.wikipedia.org/wiki/Finite_difference_method
419    /// [`autodiff`]: crate::autodiff
420    fn derivative<F>(f: F, x: Self, h: Self) -> Self
421    where
422        F: Fn(Self) -> Self;
423
424    /// Approximates the integral of the 1D function `f` over the range `[x, y]`
425    /// using `n` subdivisions.
426    ///
427    /// Uses the [Riemann Sum](https://en.wikipedia.org/wiki/Riemann_sum).
428    fn integrate<F>(f: F, x: Self, y: Self, n: usize) -> Self
429    where
430        F: Fn(Self) -> Self;
431
432    /// Approximates the partial derivative of the 2D function `f` at point (`x`, `y`)
433    /// with step size `h`, differentiating over `x`.
434    fn partial_derivative_x<F>(f: F, x: Self, y: Self, h: Self) -> Self
435    where
436        F: Fn(Self, Self) -> Self;
437
438    /// Approximates the partial derivative of the 2D function `f` at point (`x`, `y`)
439    /// with step size `h`, differentiating over `x`.
440    fn partial_derivative_y<F>(f: F, x: Self, y: Self, h: Self) -> Self
441    where
442        F: Fn(Self, Self) -> Self;
443}
444
445macro_rules! impl_float_ext {
446    () => {
447        impl_float_ext![
448            (f32, u32 | i32):"_float_f32":"_cmp_f32",
449            (f64, u32 | i32):"_float_f64":"_cmp_f32"];
450    };
451
452    // $f:   the floating-point type.
453    // $ue:  unsigned int type with the same bit-size.
454    // $ie:  the integer type for integer exponentiation.
455    // $cap: the capability feature that enables the given implementation. E.g "_float_f32".
456    // $cmp: the feature that enables the given implementation. E.g "_cmp_f32".
457    ($( ($f:ty, $ue:ty|$ie:ty): $cap:literal : $cmp:literal ),+) => {
458        $( impl_float_ext![@$f, $ue|$ie, $cap:$cmp]; )+
459    };
460    (@$f:ty, $ue:ty|$ie:ty, $cap:literal : $cmp:literal) => {
461        #[cfg(feature = $cap )]
462        #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
463        impl ExtFloat for $f {
464            fn floor(self) -> Self { Float(self).floor().0 }
465
466            fn ceil(self) -> Self { Float(self).ceil().0 }
467
468            fn round(self) -> Self { Float(self).round_ties_away().0 }
469
470            fn round_ties_away(self) -> Self { Float(self).round_ties_away().0 }
471
472            fn round_ties_even(self) -> Self { Float(self).round_ties_even().0 }
473
474            fn round_ties_odd(self) -> Self { Float(self).round_ties_odd().0 }
475
476            fn trunc(self) -> Self { Float(self).trunc().0 }
477
478            fn fract(self) -> Self { Float(self).fract().0 }
479
480            fn split(self) -> (Self, Self) { let (i, f) = Float(self).split(); (i.0, f.0) }
481
482            fn abs(self) -> Self { Float(self).abs().0 }
483
484            fn neg_abs(self) -> Self { Float(self).neg_abs().0 }
485
486            fn sign(self) -> Sign { Float(self).sign() }
487
488            fn sign_nonzero(self) -> Sign { Float(self).sign_nonzero() }
489
490            fn signum(self) -> Self { Float(self).signum().0 }
491
492            fn flip_sign(self) -> Self { Float(self).flip_sign().0 }
493
494            fn is_sign_positive(self) -> bool { Float(self).is_sign_positive() }
495
496            fn is_sign_negative(self) -> bool { Float(self).is_sign_negative() }
497
498            fn is_zero(self) -> bool { Float(self).is_zero() }
499
500            fn is_sign_positive_nonzero(self) -> bool {
501                Float(self).is_sign_positive_nonzero() }
502
503            fn is_sign_negative_nonzero(self) -> bool {
504                Float(self).is_sign_negative_nonzero() }
505
506            fn copysign(self, sign: Self) -> Self { Float(self).copysign(sign).0 }
507
508            #[cfg(any(feature = "std", feature = "dep_libm"))]
509            fn mul_add(self, mul: Self, add: Self) -> Self {
510                Float(self).mul_add(mul, add).0 }
511            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
512            fn mul_add(self, mul: Self, add: Self) -> Self {
513                Float(self).mul_add_fallback(mul, add).0
514            }
515
516            fn div_euclid(self, rhs: Self) -> Self { Float(self).div_euclid(rhs).0 }
517
518            fn rem_euclid(self, rhs: Self) -> Self { Float(self).rem_euclid(rhs).0 }
519
520            fn scale(self, min: Self, max: Self, u: Self, v: Self) -> Self {
521                Float(self).scale(min, max, u, v).0 }
522            fn lerp(self, u: Self, v: Self) -> Self { Float(self).lerp(u, v).0 }
523
524            #[cfg(any(feature = "std", feature = "dep_libm"))]
525            fn powf(self, y: Self) -> Self { Float(self).powf(y).0 }
526            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
527            fn powf(self, y: Self) -> Self {
528                Float(self).powf_series(y, Float(self).ln_series_terms()).0
529            }
530
531            fn powi(self, p: $ie) -> Self { Float(self).powi(p).0 }
532
533            #[cfg(any(feature = "std", feature = "dep_libm"))]
534            fn sqrt(self) -> Self { Float(self).sqrt().0 }
535            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
536            fn sqrt(self) -> Self { Float(self).sqrt_nr().0 }
537
538            fn sqrt_fisr(self) -> Self { Float(self).sqrt_fisr().0 }
539
540            fn fisr(self) -> Self { Float(self).fisr().0 }
541
542            #[cfg(any(feature = "std", feature = "dep_libm"))]
543            fn cbrt(self) -> Self { Float(self).cbrt().0 }
544            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
545            fn cbrt(self) -> Self { Float(self).cbrt_nr().0 }
546
547            #[cfg(any(feature = "std", feature = "dep_libm"))]
548            fn hypot(self, rhs: Self) -> Self { Float(self).hypot(rhs).0 }
549            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
550            fn hypot(self, rhs: Self) -> Self { Float(self).hypot_nr(rhs).0 }
551
552            #[cfg(any(feature = "std", feature = "dep_libm"))]
553            fn exp(self) -> Self { Float(self).exp().0 }
554            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
555            fn exp(self) -> Self {
556                Float(self).exp_series(Float(self).exp_series_terms()).0 }
557
558            #[cfg(any(feature = "std", feature = "dep_libm"))]
559            fn exp2(self) -> Self { Float(self).exp2().0 }
560            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
561            fn exp2(self) -> Self {
562                Float(self).exp2_series(Float(self).exp2_series_terms()).0 }
563
564            #[cfg(any(feature = "std", feature = "dep_libm"))]
565            fn exp_m1(self) -> Self { Float(self).exp_m1().0 }
566            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
567            fn exp_m1(self) -> Self {
568                Float(self).exp_m1_series(Float(self).exp_series_terms()).0
569            }
570
571            #[cfg(any(feature = "std", feature = "dep_libm"))]
572            fn ln(self) -> Self { Float(self).ln().0 }
573            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
574            fn ln(self) -> Self {
575                Float(self).ln_series(Float(self).ln_series_terms()).0 }
576
577            #[cfg(any(feature = "std", feature = "dep_libm"))]
578            fn ln_1p(self) -> Self { Float(self).ln_1p().0 }
579            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
580            fn ln_1p(self) -> Self {
581                Float(self).ln_1p_series(Float(self).ln_series_terms()).0 }
582
583            #[cfg(any(feature = "std", feature = "dep_libm"))]
584            fn log(self, base: Self) -> Self { Float(self).log(base).0 }
585            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
586            fn log(self, base: Self) -> Self {
587                Float(self).log_series(base, Float(self).ln_series_terms()).0 }
588
589            #[cfg(any(feature = "std", feature = "dep_libm"))]
590            fn log2(self) -> Self { Float(self).log2().0 }
591            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
592            fn log2(self) -> Self {
593                Float(self).log2_series(Float(self).ln_series_terms()).0 }
594
595            #[cfg(any(feature = "std", feature = "dep_libm"))]
596            fn log10(self) -> Self { Float(self).log10().0 }
597            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
598            fn log10(self) -> Self {
599                Float(self).log10_series(Float(self).ln_series_terms()).0 }
600
601            fn factorial(a: $ue) -> Self { Float::<Self>::factorial(a).0 }
602
603            #[cfg(any(feature = "std", feature = "dep_libm"))]
604            fn sin(self) -> Self { Float(self).sin().0 }
605            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
606            fn sin(self) -> Self { Float(self).sin_series(8).0 }
607
608            #[cfg(any(feature = "std", feature = "dep_libm"))]
609            fn cos(self) -> Self { Float(self).cos().0 }
610            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
611            fn cos(self) -> Self { Float(self).cos_series(8).0 }
612
613            #[cfg(any(feature = "std", feature = "dep_libm"))]
614            fn sin_cos(self) -> (Self, Self) { let (s, c) = Float(self).sin_cos(); (s.0, c.0) }
615            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
616            fn sin_cos(self) -> (Self, Self) {
617                let (s, c) = Float(self).sin_cos_series(8); (s.0, c.0) }
618            #[cfg(any(feature = "std", feature = "dep_libm"))]
619            fn tan(self) -> Self { Float(self).tan().0 }
620            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
621            fn tan(self) -> Self { Float(self).tan_series(8).0 }
622
623            #[cfg(any(feature = "std", feature = "dep_libm"))]
624            fn asin(self) -> Self { Float(self).asin().0 }
625            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
626            fn asin(self) -> Self {
627                Float(self).asin_series(Float(self).asin_series_terms()).0 }
628
629            #[cfg(any(feature = "std", feature = "dep_libm"))]
630            fn acos(self) -> Self { Float(self).acos().0 }
631            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
632            fn acos(self) -> Self {
633                Float(self).acos_series(Float(self).acos_series_terms()).0 }
634
635            #[cfg(any(feature = "std", feature = "dep_libm"))]
636            fn atan(self) -> Self { Float(self).atan().0 }
637            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
638            fn atan(self) -> Self {
639                Float(self).atan_series(Float(self).atan_series_terms()).0 }
640
641            #[cfg(any(feature = "std", feature = "dep_libm"))]
642            fn atan2(self, other: Self) -> Self { Float(self).atan2(other).0 }
643            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
644            fn atan2(self, other: Self) -> Self {
645                Float(self).atan2_series(other, Float(self).atan_series_terms()).0 }
646
647            #[cfg(any(feature = "std", feature = "dep_libm"))]
648            fn sinh(self) -> Self { Float(self).sinh().0 }
649            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
650            fn sinh(self) -> Self {
651                Float(self).sinh_series(Float(self).exp_series_terms()).0 }
652
653            #[cfg(any(feature = "std", feature = "dep_libm"))]
654            fn cosh(self) -> Self { Float(self).cosh().0 }
655            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
656            fn cosh(self) -> Self {
657                Float(self).cosh_series(Float(self).exp_series_terms()).0 }
658
659            #[cfg(any(feature = "std", feature = "dep_libm"))]
660            fn tanh(self) -> Self { Float(self).tanh().0 }
661            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
662            fn tanh(self) -> Self {
663                Float(self).tanh_series(Float(self).exp_series_terms()).0 }
664
665            #[cfg(any(feature = "std", feature = "dep_libm"))]
666            fn asinh(self) -> Self { Float(self).asinh().0 }
667            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
668            fn asinh(self) -> Self {
669                Float(self).asinh_series(Float(self).exp_series_terms()).0 }
670
671            #[cfg(any(feature = "std", feature = "dep_libm"))]
672            fn acosh(self) -> Self { Float(self).acosh().0 }
673            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
674            fn acosh(self) -> Self {
675                Float(self).acosh_series(Float(self).exp_series_terms()).0 }
676
677            #[cfg(any(feature = "std", feature = "dep_libm"))]
678            fn atanh(self) -> Self { Float(self).atanh().0 }
679            #[cfg(not(any(feature = "std", feature = "dep_libm")))]
680            fn atanh(self) -> Self {
681                Float(self).atanh_series(Float(self).exp_series_terms()).0 }
682
683            fn clamp_nan(self, min: Self, max: Self) -> Self { Float(self).clamp_nan(min, max).0 }
684
685            fn max_nan(self, other: Self) -> Self { Float(self).max_nan(other).0 }
686
687            fn min_nan(self, other: Self) -> Self { Float(self).min_nan(other).0 }
688
689            #[cfg(feature = $cmp)]
690            fn clamp_total(self, min: Self, max: Self) -> Self {
691                Float(self).clamp_total(min, max).0
692            }
693            #[cfg(not(feature = $cmp))]
694            fn clamp_total(self, _: Self, _: Self) -> Self { <$f>::NAN }
695
696            #[cfg(feature = $cmp)]
697            fn max_total(self, other: Self) -> Self { Float(self).max_total(other).0 }
698            #[cfg(not(feature = $cmp))]
699            fn max_total(self, _: Self) -> Self { <$f>::NAN }
700
701            #[cfg(feature = $cmp)]
702            fn min_total(self, other: Self) -> Self { Float(self).min_total(other).0 }
703            #[cfg(not(feature = $cmp))]
704            fn min_total(self, _: Self) -> Self { <$f>::NAN }
705
706            fn eval_poly(self, coefficients: &[Self]) -> Self {
707                Float(self).eval_poly(coefficients).0
708            }
709
710            fn derivative<F>(f: F, x: Self, h: Self) -> Self
711            where F: Fn(Self) -> Self {
712                Float::<Self>::derivative(f, x, h).0
713            }
714            fn integrate<F>(f: F, x: Self, y: Self, n: usize) -> Self
715            where F: Fn(Self) -> Self {
716                Float::<Self>::integrate(f, x, y, n).0
717            }
718
719            fn partial_derivative_x<F>(f: F, x: Self, y: Self, h: Self) -> Self
720            where
721                F: Fn(Self, Self) -> Self,
722            {
723                Float::<Self>::partial_derivative_x(f, x, y, h).0
724            }
725
726            fn partial_derivative_y<F>(f: F, x: Self, y: Self, h: Self) -> Self
727            where
728                F: Fn(Self, Self) -> Self,
729            {
730                Float::<Self>::partial_derivative_y(f, x, y, h).0
731            }
732        }
733    }
734}
735impl_float_ext!();