A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://docs.rs/num-traits/0.2.19/x86_64-unknown-linux-gnu/src/num_traits/float.rs.html below:

float.rs - source

1use core::cmp::Ordering;
2use core::num::FpCategory;
3use core::ops::{Add, Div, Neg};
4
5use core::f32;
6use core::f64;
7
8use crate::{Num, NumCast, ToPrimitive};
9
10pub trait FloatCore: Num + NumCast + Neg<Output = Self> + PartialOrd + Copy {
14    fn infinity() -> Self;
30
31    fn neg_infinity() -> Self;
47
48    fn nan() -> Self;
64
65    fn neg_zero() -> Self;
83
84    fn min_value() -> Self;
100
101    fn min_positive_value() -> Self;
117
118    fn epsilon() -> Self;
134
135    fn max_value() -> Self;
151
152    #[inline]
170    #[allow(clippy::eq_op)]
171    fn is_nan(self) -> bool {
172        self != self
173    }
174
175    #[inline]
195    fn is_infinite(self) -> bool {
196        self == Self::infinity() || self == Self::neg_infinity()
197    }
198
199    #[inline]
218    fn is_finite(self) -> bool {
219        !(self.is_nan() || self.is_infinite())
220    }
221
222    #[inline]
241    fn is_normal(self) -> bool {
242        self.classify() == FpCategory::Normal
243    }
244
245    #[inline]
267    fn is_subnormal(self) -> bool {
268        self.classify() == FpCategory::Subnormal
269    }
270
271    fn classify(self) -> FpCategory;
294
295    #[inline]
318    fn floor(self) -> Self {
319        let f = self.fract();
320        if f.is_nan() || f.is_zero() {
321            self
322        } else if self < Self::zero() {
323            self - f - Self::one()
324        } else {
325            self - f
326        }
327    }
328
329    #[inline]
352    fn ceil(self) -> Self {
353        let f = self.fract();
354        if f.is_nan() || f.is_zero() {
355            self
356        } else if self > Self::zero() {
357            self - f + Self::one()
358        } else {
359            self - f
360        }
361    }
362
363    #[inline]
385    fn round(self) -> Self {
386        let one = Self::one();
387        let h = Self::from(0.5).expect("Unable to cast from 0.5");
388        let f = self.fract();
389        if f.is_nan() || f.is_zero() {
390            self
391        } else if self > Self::zero() {
392            if f < h {
393                self - f
394            } else {
395                self - f + one
396            }
397        } else if -f < h {
398            self - f
399        } else {
400            self - f - one
401        }
402    }
403
404    #[inline]
427    fn trunc(self) -> Self {
428        let f = self.fract();
429        if f.is_nan() {
430            self
431        } else {
432            self - f
433        }
434    }
435
436    #[inline]
459    fn fract(self) -> Self {
460        if self.is_zero() {
461            Self::zero()
462        } else {
463            self % Self::one()
464        }
465    }
466
467    #[inline]
488    fn abs(self) -> Self {
489        if self.is_sign_positive() {
490            return self;
491        }
492        if self.is_sign_negative() {
493            return -self;
494        }
495        Self::nan()
496    }
497
498    #[inline]
522    fn signum(self) -> Self {
523        if self.is_nan() {
524            Self::nan()
525        } else if self.is_sign_negative() {
526            -Self::one()
527        } else {
528            Self::one()
529        }
530    }
531
532    #[inline]
555    fn is_sign_positive(self) -> bool {
556        !self.is_sign_negative()
557    }
558
559    #[inline]
582    fn is_sign_negative(self) -> bool {
583        let (_, _, sign) = self.integer_decode();
584        sign < 0
585    }
586
587    #[inline]
607    fn min(self, other: Self) -> Self {
608        if self.is_nan() {
609            return other;
610        }
611        if other.is_nan() {
612            return self;
613        }
614        if self < other {
615            self
616        } else {
617            other
618        }
619    }
620
621    #[inline]
641    fn max(self, other: Self) -> Self {
642        if self.is_nan() {
643            return other;
644        }
645        if other.is_nan() {
646            return self;
647        }
648        if self > other {
649            self
650        } else {
651            other
652        }
653    }
654
655    fn clamp(self, min: Self, max: Self) -> Self {
682        crate::clamp(self, min, max)
683    }
684
685    #[inline]
704    fn recip(self) -> Self {
705        Self::one() / self
706    }
707
708    #[inline]
728    fn powi(mut self, mut exp: i32) -> Self {
729        if exp < 0 {
730            exp = exp.wrapping_neg();
731            self = self.recip();
732        }
733        super::pow(self, (exp as u32).to_usize().unwrap())
737    }
738
739    fn to_degrees(self) -> Self;
757
758    fn to_radians(self) -> Self;
776
777    fn integer_decode(self) -> (u64, i16, i8);
799}
800
801impl FloatCore for f32 {
802    constant! {
803        infinity() -> f32::INFINITY;
804        neg_infinity() -> f32::NEG_INFINITY;
805        nan() -> f32::NAN;
806        neg_zero() -> -0.0;
807        min_value() -> f32::MIN;
808        min_positive_value() -> f32::MIN_POSITIVE;
809        epsilon() -> f32::EPSILON;
810        max_value() -> f32::MAX;
811    }
812
813    #[inline]
814    fn integer_decode(self) -> (u64, i16, i8) {
815        integer_decode_f32(self)
816    }
817
818    forward! {
819        Self::is_nan(self) -> bool;
820        Self::is_infinite(self) -> bool;
821        Self::is_finite(self) -> bool;
822        Self::is_normal(self) -> bool;
823        Self::is_subnormal(self) -> bool;
824        Self::clamp(self, min: Self, max: Self) -> Self;
825        Self::classify(self) -> FpCategory;
826        Self::is_sign_positive(self) -> bool;
827        Self::is_sign_negative(self) -> bool;
828        Self::min(self, other: Self) -> Self;
829        Self::max(self, other: Self) -> Self;
830        Self::recip(self) -> Self;
831        Self::to_degrees(self) -> Self;
832        Self::to_radians(self) -> Self;
833    }
834
835    #[cfg(feature = "std")]
836    forward! {
837        Self::floor(self) -> Self;
838        Self::ceil(self) -> Self;
839        Self::round(self) -> Self;
840        Self::trunc(self) -> Self;
841        Self::fract(self) -> Self;
842        Self::abs(self) -> Self;
843        Self::signum(self) -> Self;
844        Self::powi(self, n: i32) -> Self;
845    }
846
847    #[cfg(all(not(feature = "std"), feature = "libm"))]
848    forward! {
849        libm::floorf as floor(self) -> Self;
850        libm::ceilf as ceil(self) -> Self;
851        libm::roundf as round(self) -> Self;
852        libm::truncf as trunc(self) -> Self;
853        libm::fabsf as abs(self) -> Self;
854    }
855
856    #[cfg(all(not(feature = "std"), feature = "libm"))]
857    #[inline]
858    fn fract(self) -> Self {
859        self - libm::truncf(self)
860    }
861}
862
863impl FloatCore for f64 {
864    constant! {
865        infinity() -> f64::INFINITY;
866        neg_infinity() -> f64::NEG_INFINITY;
867        nan() -> f64::NAN;
868        neg_zero() -> -0.0;
869        min_value() -> f64::MIN;
870        min_positive_value() -> f64::MIN_POSITIVE;
871        epsilon() -> f64::EPSILON;
872        max_value() -> f64::MAX;
873    }
874
875    #[inline]
876    fn integer_decode(self) -> (u64, i16, i8) {
877        integer_decode_f64(self)
878    }
879
880    forward! {
881        Self::is_nan(self) -> bool;
882        Self::is_infinite(self) -> bool;
883        Self::is_finite(self) -> bool;
884        Self::is_normal(self) -> bool;
885        Self::is_subnormal(self) -> bool;
886        Self::clamp(self, min: Self, max: Self) -> Self;
887        Self::classify(self) -> FpCategory;
888        Self::is_sign_positive(self) -> bool;
889        Self::is_sign_negative(self) -> bool;
890        Self::min(self, other: Self) -> Self;
891        Self::max(self, other: Self) -> Self;
892        Self::recip(self) -> Self;
893        Self::to_degrees(self) -> Self;
894        Self::to_radians(self) -> Self;
895    }
896
897    #[cfg(feature = "std")]
898    forward! {
899        Self::floor(self) -> Self;
900        Self::ceil(self) -> Self;
901        Self::round(self) -> Self;
902        Self::trunc(self) -> Self;
903        Self::fract(self) -> Self;
904        Self::abs(self) -> Self;
905        Self::signum(self) -> Self;
906        Self::powi(self, n: i32) -> Self;
907    }
908
909    #[cfg(all(not(feature = "std"), feature = "libm"))]
910    forward! {
911        libm::floor as floor(self) -> Self;
912        libm::ceil as ceil(self) -> Self;
913        libm::round as round(self) -> Self;
914        libm::trunc as trunc(self) -> Self;
915        libm::fabs as abs(self) -> Self;
916    }
917
918    #[cfg(all(not(feature = "std"), feature = "libm"))]
919    #[inline]
920    fn fract(self) -> Self {
921        self - libm::trunc(self)
922    }
923}
924
925#[cfg(any(feature = "std", feature = "libm"))]
932pub trait Float: Num + Copy + NumCast + PartialOrd + Neg<Output = Self> {
933    fn nan() -> Self;
943    fn infinity() -> Self;
956    fn neg_infinity() -> Self;
969    fn neg_zero() -> Self;
983
984    fn min_value() -> Self;
995
996    fn min_positive_value() -> Self;
1007
1008    fn epsilon() -> Self {
1024        Self::from(f32::EPSILON).expect("Unable to cast from f32::EPSILON")
1025    }
1026
1027    fn max_value() -> Self;
1037
1038    fn is_nan(self) -> bool;
1051
1052    fn is_infinite(self) -> bool;
1071
1072    fn is_finite(self) -> bool;
1090
1091    fn is_normal(self) -> bool;
1114
1115    #[inline]
1137    fn is_subnormal(self) -> bool {
1138        self.classify() == FpCategory::Subnormal
1139    }
1140
1141    fn classify(self) -> FpCategory;
1157
1158    fn floor(self) -> Self;
1170
1171    fn ceil(self) -> Self;
1183
1184    fn round(self) -> Self;
1197
1198    fn trunc(self) -> Self;
1210
1211    fn fract(self) -> Self;
1225
1226    fn abs(self) -> Self;
1245
1246    fn signum(self) -> Self;
1264
1265    fn is_sign_positive(self) -> bool;
1284
1285    fn is_sign_negative(self) -> bool;
1304
1305    fn mul_add(self, a: Self, b: Self) -> Self;
1324    fn recip(self) -> Self;
1335
1336    fn powi(self, n: i32) -> Self;
1349
1350    fn powf(self, n: Self) -> Self;
1361
1362    fn sqrt(self) -> Self;
1378
1379    fn exp(self) -> Self;
1394
1395    fn exp2(self) -> Self;
1408
1409    fn ln(self) -> Self;
1424
1425    fn log(self, base: Self) -> Self;
1443
1444    fn log2(self) -> Self;
1457
1458    fn log10(self) -> Self;
1471
1472    #[inline]
1484    fn to_degrees(self) -> Self {
1485        let halfpi = Self::zero().acos();
1486        let ninety = Self::from(90u8).unwrap();
1487        self * ninety / halfpi
1488    }
1489
1490    #[inline]
1502    fn to_radians(self) -> Self {
1503        let halfpi = Self::zero().acos();
1504        let ninety = Self::from(90u8).unwrap();
1505        self * halfpi / ninety
1506    }
1507
1508    fn max(self, other: Self) -> Self;
1519
1520    fn min(self, other: Self) -> Self;
1531
1532    fn clamp(self, min: Self, max: Self) -> Self {
1546        crate::clamp(self, min, max)
1547    }
1548
1549    fn abs_sub(self, other: Self) -> Self;
1567
1568    fn cbrt(self) -> Self;
1581
1582    fn hypot(self, other: Self) -> Self;
1597
1598    fn sin(self) -> Self;
1611
1612    fn cos(self) -> Self;
1625
1626    fn tan(self) -> Self;
1638
1639    fn asin(self) -> Self;
1655
1656    fn acos(self) -> Self;
1672
1673    fn atan(self) -> Self;
1687
1688    fn atan2(self, other: Self) -> Self;
1716
1717    fn sin_cos(self) -> (Self, Self);
1734
1735    fn exp_m1(self) -> Self;
1749
1750    fn ln_1p(self) -> Self;
1765
1766    fn sinh(self) -> Self;
1783
1784    fn cosh(self) -> Self;
1801
1802    fn tanh(self) -> Self;
1819
1820    fn asinh(self) -> Self;
1833
1834    fn acosh(self) -> Self;
1847
1848    fn atanh(self) -> Self;
1862
1863    fn integer_decode(self) -> (u64, i16, i8);
1883
1884    fn copysign(self, sign: Self) -> Self {
1906        if self.is_sign_negative() == sign.is_sign_negative() {
1907            self
1908        } else {
1909            self.neg()
1910        }
1911    }
1912}
1913
1914#[cfg(feature = "std")]
1915macro_rules! float_impl_std {
1916    ($T:ident $decode:ident) => {
1917        impl Float for $T {
1918            constant! {
1919                nan() -> $T::NAN;
1920                infinity() -> $T::INFINITY;
1921                neg_infinity() -> $T::NEG_INFINITY;
1922                neg_zero() -> -0.0;
1923                min_value() -> $T::MIN;
1924                min_positive_value() -> $T::MIN_POSITIVE;
1925                epsilon() -> $T::EPSILON;
1926                max_value() -> $T::MAX;
1927            }
1928
1929            #[inline]
1930            #[allow(deprecated)]
1931            fn abs_sub(self, other: Self) -> Self {
1932                <$T>::abs_sub(self, other)
1933            }
1934
1935            #[inline]
1936            fn integer_decode(self) -> (u64, i16, i8) {
1937                $decode(self)
1938            }
1939
1940            forward! {
1941                Self::is_nan(self) -> bool;
1942                Self::is_infinite(self) -> bool;
1943                Self::is_finite(self) -> bool;
1944                Self::is_normal(self) -> bool;
1945                Self::is_subnormal(self) -> bool;
1946                Self::classify(self) -> FpCategory;
1947                Self::clamp(self, min: Self, max: Self) -> Self;
1948                Self::floor(self) -> Self;
1949                Self::ceil(self) -> Self;
1950                Self::round(self) -> Self;
1951                Self::trunc(self) -> Self;
1952                Self::fract(self) -> Self;
1953                Self::abs(self) -> Self;
1954                Self::signum(self) -> Self;
1955                Self::is_sign_positive(self) -> bool;
1956                Self::is_sign_negative(self) -> bool;
1957                Self::mul_add(self, a: Self, b: Self) -> Self;
1958                Self::recip(self) -> Self;
1959                Self::powi(self, n: i32) -> Self;
1960                Self::powf(self, n: Self) -> Self;
1961                Self::sqrt(self) -> Self;
1962                Self::exp(self) -> Self;
1963                Self::exp2(self) -> Self;
1964                Self::ln(self) -> Self;
1965                Self::log(self, base: Self) -> Self;
1966                Self::log2(self) -> Self;
1967                Self::log10(self) -> Self;
1968                Self::to_degrees(self) -> Self;
1969                Self::to_radians(self) -> Self;
1970                Self::max(self, other: Self) -> Self;
1971                Self::min(self, other: Self) -> Self;
1972                Self::cbrt(self) -> Self;
1973                Self::hypot(self, other: Self) -> Self;
1974                Self::sin(self) -> Self;
1975                Self::cos(self) -> Self;
1976                Self::tan(self) -> Self;
1977                Self::asin(self) -> Self;
1978                Self::acos(self) -> Self;
1979                Self::atan(self) -> Self;
1980                Self::atan2(self, other: Self) -> Self;
1981                Self::sin_cos(self) -> (Self, Self);
1982                Self::exp_m1(self) -> Self;
1983                Self::ln_1p(self) -> Self;
1984                Self::sinh(self) -> Self;
1985                Self::cosh(self) -> Self;
1986                Self::tanh(self) -> Self;
1987                Self::asinh(self) -> Self;
1988                Self::acosh(self) -> Self;
1989                Self::atanh(self) -> Self;
1990                Self::copysign(self, sign: Self) -> Self;
1991            }
1992        }
1993    };
1994}
1995
1996#[cfg(all(not(feature = "std"), feature = "libm"))]
1997macro_rules! float_impl_libm {
1998    ($T:ident $decode:ident) => {
1999        constant! {
2000            nan() -> $T::NAN;
2001            infinity() -> $T::INFINITY;
2002            neg_infinity() -> $T::NEG_INFINITY;
2003            neg_zero() -> -0.0;
2004            min_value() -> $T::MIN;
2005            min_positive_value() -> $T::MIN_POSITIVE;
2006            epsilon() -> $T::EPSILON;
2007            max_value() -> $T::MAX;
2008        }
2009
2010        #[inline]
2011        fn integer_decode(self) -> (u64, i16, i8) {
2012            $decode(self)
2013        }
2014
2015        #[inline]
2016        fn fract(self) -> Self {
2017            self - Float::trunc(self)
2018        }
2019
2020        #[inline]
2021        fn log(self, base: Self) -> Self {
2022            self.ln() / base.ln()
2023        }
2024
2025        forward! {
2026            Self::is_nan(self) -> bool;
2027            Self::is_infinite(self) -> bool;
2028            Self::is_finite(self) -> bool;
2029            Self::is_normal(self) -> bool;
2030            Self::is_subnormal(self) -> bool;
2031            Self::clamp(self, min: Self, max: Self) -> Self;
2032            Self::classify(self) -> FpCategory;
2033            Self::is_sign_positive(self) -> bool;
2034            Self::is_sign_negative(self) -> bool;
2035            Self::min(self, other: Self) -> Self;
2036            Self::max(self, other: Self) -> Self;
2037            Self::recip(self) -> Self;
2038            Self::to_degrees(self) -> Self;
2039            Self::to_radians(self) -> Self;
2040        }
2041
2042        forward! {
2043            FloatCore::signum(self) -> Self;
2044            FloatCore::powi(self, n: i32) -> Self;
2045        }
2046    };
2047}
2048
2049fn integer_decode_f32(f: f32) -> (u64, i16, i8) {
2050    let bits: u32 = f.to_bits();
2051    let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 };
2052    let mut exponent: i16 = ((bits >> 23) & 0xff) as i16;
2053    let mantissa = if exponent == 0 {
2054        (bits & 0x7fffff) << 1
2055    } else {
2056        (bits & 0x7fffff) | 0x800000
2057    };
2058    exponent -= 127 + 23;
2060    (mantissa as u64, exponent, sign)
2061}
2062
2063fn integer_decode_f64(f: f64) -> (u64, i16, i8) {
2064    let bits: u64 = f.to_bits();
2065    let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 };
2066    let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16;
2067    let mantissa = if exponent == 0 {
2068        (bits & 0xfffffffffffff) << 1
2069    } else {
2070        (bits & 0xfffffffffffff) | 0x10000000000000
2071    };
2072    exponent -= 1023 + 52;
2074    (mantissa, exponent, sign)
2075}
2076
2077#[cfg(feature = "std")]
2078float_impl_std!(f32 integer_decode_f32);
2079#[cfg(feature = "std")]
2080float_impl_std!(f64 integer_decode_f64);
2081
2082#[cfg(all(not(feature = "std"), feature = "libm"))]
2083impl Float for f32 {
2084    float_impl_libm!(f32 integer_decode_f32);
2085
2086    #[inline]
2087    #[allow(deprecated)]
2088    fn abs_sub(self, other: Self) -> Self {
2089        libm::fdimf(self, other)
2090    }
2091
2092    forward! {
2093        libm::floorf as floor(self) -> Self;
2094        libm::ceilf as ceil(self) -> Self;
2095        libm::roundf as round(self) -> Self;
2096        libm::truncf as trunc(self) -> Self;
2097        libm::fabsf as abs(self) -> Self;
2098        libm::fmaf as mul_add(self, a: Self, b: Self) -> Self;
2099        libm::powf as powf(self, n: Self) -> Self;
2100        libm::sqrtf as sqrt(self) -> Self;
2101        libm::expf as exp(self) -> Self;
2102        libm::exp2f as exp2(self) -> Self;
2103        libm::logf as ln(self) -> Self;
2104        libm::log2f as log2(self) -> Self;
2105        libm::log10f as log10(self) -> Self;
2106        libm::cbrtf as cbrt(self) -> Self;
2107        libm::hypotf as hypot(self, other: Self) -> Self;
2108        libm::sinf as sin(self) -> Self;
2109        libm::cosf as cos(self) -> Self;
2110        libm::tanf as tan(self) -> Self;
2111        libm::asinf as asin(self) -> Self;
2112        libm::acosf as acos(self) -> Self;
2113        libm::atanf as atan(self) -> Self;
2114        libm::atan2f as atan2(self, other: Self) -> Self;
2115        libm::sincosf as sin_cos(self) -> (Self, Self);
2116        libm::expm1f as exp_m1(self) -> Self;
2117        libm::log1pf as ln_1p(self) -> Self;
2118        libm::sinhf as sinh(self) -> Self;
2119        libm::coshf as cosh(self) -> Self;
2120        libm::tanhf as tanh(self) -> Self;
2121        libm::asinhf as asinh(self) -> Self;
2122        libm::acoshf as acosh(self) -> Self;
2123        libm::atanhf as atanh(self) -> Self;
2124        libm::copysignf as copysign(self, other: Self) -> Self;
2125    }
2126}
2127
2128#[cfg(all(not(feature = "std"), feature = "libm"))]
2129impl Float for f64 {
2130    float_impl_libm!(f64 integer_decode_f64);
2131
2132    #[inline]
2133    #[allow(deprecated)]
2134    fn abs_sub(self, other: Self) -> Self {
2135        libm::fdim(self, other)
2136    }
2137
2138    forward! {
2139        libm::floor as floor(self) -> Self;
2140        libm::ceil as ceil(self) -> Self;
2141        libm::round as round(self) -> Self;
2142        libm::trunc as trunc(self) -> Self;
2143        libm::fabs as abs(self) -> Self;
2144        libm::fma as mul_add(self, a: Self, b: Self) -> Self;
2145        libm::pow as powf(self, n: Self) -> Self;
2146        libm::sqrt as sqrt(self) -> Self;
2147        libm::exp as exp(self) -> Self;
2148        libm::exp2 as exp2(self) -> Self;
2149        libm::log as ln(self) -> Self;
2150        libm::log2 as log2(self) -> Self;
2151        libm::log10 as log10(self) -> Self;
2152        libm::cbrt as cbrt(self) -> Self;
2153        libm::hypot as hypot(self, other: Self) -> Self;
2154        libm::sin as sin(self) -> Self;
2155        libm::cos as cos(self) -> Self;
2156        libm::tan as tan(self) -> Self;
2157        libm::asin as asin(self) -> Self;
2158        libm::acos as acos(self) -> Self;
2159        libm::atan as atan(self) -> Self;
2160        libm::atan2 as atan2(self, other: Self) -> Self;
2161        libm::sincos as sin_cos(self) -> (Self, Self);
2162        libm::expm1 as exp_m1(self) -> Self;
2163        libm::log1p as ln_1p(self) -> Self;
2164        libm::sinh as sinh(self) -> Self;
2165        libm::cosh as cosh(self) -> Self;
2166        libm::tanh as tanh(self) -> Self;
2167        libm::asinh as asinh(self) -> Self;
2168        libm::acosh as acosh(self) -> Self;
2169        libm::atanh as atanh(self) -> Self;
2170        libm::copysign as copysign(self, sign: Self) -> Self;
2171    }
2172}
2173
2174macro_rules! float_const_impl {
2175    ($(#[$doc:meta] $constant:ident,)+) => (
2176        #[allow(non_snake_case)]
2177        pub trait FloatConst {
2178            $(#[$doc] fn $constant() -> Self;)+
2179            #[doc = "Return the full circle constant `τ`."]
2180            #[inline]
2181            fn TAU() -> Self where Self: Sized + Add<Self, Output = Self> {
2182                Self::PI() + Self::PI()
2183            }
2184            #[doc = "Return `log10(2.0)`."]
2185            #[inline]
2186            fn LOG10_2() -> Self where Self: Sized + Div<Self, Output = Self> {
2187                Self::LN_2() / Self::LN_10()
2188            }
2189            #[doc = "Return `log2(10.0)`."]
2190            #[inline]
2191            fn LOG2_10() -> Self where Self: Sized + Div<Self, Output = Self> {
2192                Self::LN_10() / Self::LN_2()
2193            }
2194        }
2195        float_const_impl! { @float f32, $($constant,)+ }
2196        float_const_impl! { @float f64, $($constant,)+ }
2197    );
2198    (@float $T:ident, $($constant:ident,)+) => (
2199        impl FloatConst for $T {
2200            constant! {
2201                $( $constant() -> $T::consts::$constant; )+
2202                TAU() -> 6.28318530717958647692528676655900577;
2203                LOG10_2() -> 0.301029995663981195213738894724493027;
2204                LOG2_10() -> 3.32192809488736234787031942948939018;
2205            }
2206        }
2207    );
2208}
2209
2210float_const_impl! {
2211    #[doc = "Return Euler’s number."]
2212    E,
2213    #[doc = "Return `1.0 / π`."]
2214    FRAC_1_PI,
2215    #[doc = "Return `1.0 / sqrt(2.0)`."]
2216    FRAC_1_SQRT_2,
2217    #[doc = "Return `2.0 / π`."]
2218    FRAC_2_PI,
2219    #[doc = "Return `2.0 / sqrt(π)`."]
2220    FRAC_2_SQRT_PI,
2221    #[doc = "Return `π / 2.0`."]
2222    FRAC_PI_2,
2223    #[doc = "Return `π / 3.0`."]
2224    FRAC_PI_3,
2225    #[doc = "Return `π / 4.0`."]
2226    FRAC_PI_4,
2227    #[doc = "Return `π / 6.0`."]
2228    FRAC_PI_6,
2229    #[doc = "Return `π / 8.0`."]
2230    FRAC_PI_8,
2231    #[doc = "Return `ln(10.0)`."]
2232    LN_10,
2233    #[doc = "Return `ln(2.0)`."]
2234    LN_2,
2235    #[doc = "Return `log10(e)`."]
2236    LOG10_E,
2237    #[doc = "Return `log2(e)`."]
2238    LOG2_E,
2239    #[doc = "Return Archimedes’ constant `π`."]
2240    PI,
2241    #[doc = "Return `sqrt(2.0)`."]
2242    SQRT_2,
2243}
2244
2245pub trait TotalOrder {
2249    fn total_cmp(&self, other: &Self) -> Ordering;
2300}
2301macro_rules! totalorder_impl {
2302    ($T:ident, $I:ident, $U:ident, $bits:expr) => {
2303        impl TotalOrder for $T {
2304            #[inline]
2305            #[cfg(has_total_cmp)]
2306            fn total_cmp(&self, other: &Self) -> Ordering {
2307                Self::total_cmp(&self, other)
2309            }
2310            #[inline]
2311            #[cfg(not(has_total_cmp))]
2312            fn total_cmp(&self, other: &Self) -> Ordering {
2313                let mut left = self.to_bits() as $I;
2315                let mut right = other.to_bits() as $I;
2316
2317                left ^= (((left >> ($bits - 1)) as $U) >> 1) as $I;
2318                right ^= (((right >> ($bits - 1)) as $U) >> 1) as $I;
2319
2320                left.cmp(&right)
2321            }
2322        }
2323    };
2324}
2325totalorder_impl!(f64, i64, u64, 64);
2326totalorder_impl!(f32, i32, u32, 32);
2327
2328#[cfg(test)]
2329mod tests {
2330    use core::f64::consts;
2331
2332    const DEG_RAD_PAIRS: [(f64, f64); 7] = [
2333        (0.0, 0.),
2334        (22.5, consts::FRAC_PI_8),
2335        (30.0, consts::FRAC_PI_6),
2336        (45.0, consts::FRAC_PI_4),
2337        (60.0, consts::FRAC_PI_3),
2338        (90.0, consts::FRAC_PI_2),
2339        (180.0, consts::PI),
2340    ];
2341
2342    #[test]
2343    fn convert_deg_rad() {
2344        use crate::float::FloatCore;
2345
2346        for &(deg, rad) in &DEG_RAD_PAIRS {
2347            assert!((FloatCore::to_degrees(rad) - deg).abs() < 1e-6);
2348            assert!((FloatCore::to_radians(deg) - rad).abs() < 1e-6);
2349
2350            let (deg, rad) = (deg as f32, rad as f32);
2351            assert!((FloatCore::to_degrees(rad) - deg).abs() < 1e-5);
2352            assert!((FloatCore::to_radians(deg) - rad).abs() < 1e-5);
2353        }
2354    }
2355
2356    #[cfg(any(feature = "std", feature = "libm"))]
2357    #[test]
2358    fn convert_deg_rad_std() {
2359        for &(deg, rad) in &DEG_RAD_PAIRS {
2360            use crate::Float;
2361
2362            assert!((Float::to_degrees(rad) - deg).abs() < 1e-6);
2363            assert!((Float::to_radians(deg) - rad).abs() < 1e-6);
2364
2365            let (deg, rad) = (deg as f32, rad as f32);
2366            assert!((Float::to_degrees(rad) - deg).abs() < 1e-5);
2367            assert!((Float::to_radians(deg) - rad).abs() < 1e-5);
2368        }
2369    }
2370
2371    #[test]
2372    fn to_degrees_rounding() {
2373        use crate::float::FloatCore;
2374
2375        assert_eq!(
2376            FloatCore::to_degrees(1_f32),
2377            57.2957795130823208767981548141051703
2378        );
2379    }
2380
2381    #[test]
2382    #[cfg(any(feature = "std", feature = "libm"))]
2383    fn extra_logs() {
2384        use crate::float::{Float, FloatConst};
2385
2386        fn check<F: Float + FloatConst>(diff: F) {
2387            let _2 = F::from(2.0).unwrap();
2388            assert!((F::LOG10_2() - F::log10(_2)).abs() < diff);
2389            assert!((F::LOG10_2() - F::LN_2() / F::LN_10()).abs() < diff);
2390
2391            let _10 = F::from(10.0).unwrap();
2392            assert!((F::LOG2_10() - F::log2(_10)).abs() < diff);
2393            assert!((F::LOG2_10() - F::LN_10() / F::LN_2()).abs() < diff);
2394        }
2395
2396        check::<f32>(1e-6);
2397        check::<f64>(1e-12);
2398    }
2399
2400    #[test]
2401    #[cfg(any(feature = "std", feature = "libm"))]
2402    fn copysign() {
2403        use crate::float::Float;
2404        test_copysign_generic(2.0_f32, -2.0_f32, f32::nan());
2405        test_copysign_generic(2.0_f64, -2.0_f64, f64::nan());
2406        test_copysignf(2.0_f32, -2.0_f32, f32::nan());
2407    }
2408
2409    #[cfg(any(feature = "std", feature = "libm"))]
2410    fn test_copysignf(p: f32, n: f32, nan: f32) {
2411        use crate::float::Float;
2412        use core::ops::Neg;
2413
2414        assert!(p.is_sign_positive());
2415        assert!(n.is_sign_negative());
2416        assert!(nan.is_nan());
2417
2418        assert_eq!(p, Float::copysign(p, p));
2419        assert_eq!(p.neg(), Float::copysign(p, n));
2420
2421        assert_eq!(n, Float::copysign(n, n));
2422        assert_eq!(n.neg(), Float::copysign(n, p));
2423
2424        assert!(Float::copysign(nan, p).is_sign_positive());
2425        assert!(Float::copysign(nan, n).is_sign_negative());
2426    }
2427
2428    #[cfg(any(feature = "std", feature = "libm"))]
2429    fn test_copysign_generic<F: crate::float::Float + ::core::fmt::Debug>(p: F, n: F, nan: F) {
2430        assert!(p.is_sign_positive());
2431        assert!(n.is_sign_negative());
2432        assert!(nan.is_nan());
2433        assert!(!nan.is_subnormal());
2434
2435        assert_eq!(p, p.copysign(p));
2436        assert_eq!(p.neg(), p.copysign(n));
2437
2438        assert_eq!(n, n.copysign(n));
2439        assert_eq!(n.neg(), n.copysign(p));
2440
2441        assert!(nan.copysign(p).is_sign_positive());
2442        assert!(nan.copysign(n).is_sign_negative());
2443    }
2444
2445    #[cfg(any(feature = "std", feature = "libm"))]
2446    fn test_subnormal<F: crate::float::Float + ::core::fmt::Debug>() {
2447        let min_positive = F::min_positive_value();
2448        let lower_than_min = min_positive / F::from(2.0f32).unwrap();
2449        assert!(!min_positive.is_subnormal());
2450        assert!(lower_than_min.is_subnormal());
2451    }
2452
2453    #[test]
2454    #[cfg(any(feature = "std", feature = "libm"))]
2455    fn subnormal() {
2456        test_subnormal::<f64>();
2457        test_subnormal::<f32>();
2458    }
2459
2460    #[test]
2461    fn total_cmp() {
2462        use crate::float::TotalOrder;
2463        use core::cmp::Ordering;
2464        use core::{f32, f64};
2465
2466        fn check_eq<T: TotalOrder>(x: T, y: T) {
2467            assert_eq!(x.total_cmp(&y), Ordering::Equal);
2468        }
2469        fn check_lt<T: TotalOrder>(x: T, y: T) {
2470            assert_eq!(x.total_cmp(&y), Ordering::Less);
2471        }
2472        fn check_gt<T: TotalOrder>(x: T, y: T) {
2473            assert_eq!(x.total_cmp(&y), Ordering::Greater);
2474        }
2475
2476        check_eq(f64::NAN, f64::NAN);
2477        check_eq(f32::NAN, f32::NAN);
2478
2479        check_lt(-0.0_f64, 0.0_f64);
2480        check_lt(-0.0_f32, 0.0_f32);
2481
2482        #[cfg(not(target_arch = "x86"))]
2485        {
2486            let s_nan = f64::from_bits(0x7ff4000000000000);
2487            let q_nan = f64::from_bits(0x7ff8000000000000);
2488            check_lt(s_nan, q_nan);
2489
2490            let neg_s_nan = f64::from_bits(0xfff4000000000000);
2491            let neg_q_nan = f64::from_bits(0xfff8000000000000);
2492            check_lt(neg_q_nan, neg_s_nan);
2493
2494            let s_nan = f32::from_bits(0x7fa00000);
2495            let q_nan = f32::from_bits(0x7fc00000);
2496            check_lt(s_nan, q_nan);
2497
2498            let neg_s_nan = f32::from_bits(0xffa00000);
2499            let neg_q_nan = f32::from_bits(0xffc00000);
2500            check_lt(neg_q_nan, neg_s_nan);
2501        }
2502
2503        check_lt(-f64::NAN, f64::NEG_INFINITY);
2504        check_gt(1.0_f64, -f64::NAN);
2505        check_lt(f64::INFINITY, f64::NAN);
2506        check_gt(f64::NAN, 1.0_f64);
2507
2508        check_lt(-f32::NAN, f32::NEG_INFINITY);
2509        check_gt(1.0_f32, -f32::NAN);
2510        check_lt(f32::INFINITY, f32::NAN);
2511        check_gt(f32::NAN, 1.0_f32);
2512    }
2513}

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4