1 #[cfg(feature = "libm")] 2 mod libm_math { 3 #[inline(always)] abs(f: f64) -> f644 pub(crate) fn abs(f: f64) -> f64 { 5 libm::fabs(f) 6 } 7 8 #[inline(always)] acos_approx(f: f64) -> f649 pub(crate) fn acos_approx(f: f64) -> f64 { 10 libm::acos(f.clamp(-1.0, 1.0)) 11 } 12 13 #[inline(always)] asin(f: f64) -> f6414 pub(crate) fn asin(f: f64) -> f64 { 15 libm::asin(f) 16 } 17 18 #[inline(always)] atan2(f: f64, other: f64) -> f6419 pub(crate) fn atan2(f: f64, other: f64) -> f64 { 20 libm::atan2(f, other) 21 } 22 23 #[inline(always)] sin(f: f64) -> f6424 pub(crate) fn sin(f: f64) -> f64 { 25 libm::sin(f) 26 } 27 28 #[inline(always)] sin_cos(f: f64) -> (f64, f64)29 pub(crate) fn sin_cos(f: f64) -> (f64, f64) { 30 libm::sincos(f) 31 } 32 33 #[inline(always)] tan(f: f64) -> f6434 pub(crate) fn tan(f: f64) -> f64 { 35 libm::tan(f) 36 } 37 38 #[inline(always)] sqrt(f: f64) -> f6439 pub(crate) fn sqrt(f: f64) -> f64 { 40 libm::sqrt(f) 41 } 42 43 #[inline(always)] copysign(f: f64, sign: f64) -> f6444 pub(crate) fn copysign(f: f64, sign: f64) -> f64 { 45 libm::copysign(f, sign) 46 } 47 48 #[inline(always)] signum(f: f64) -> f6449 pub(crate) fn signum(f: f64) -> f64 { 50 if f.is_nan() { 51 f64::NAN 52 } else { 53 copysign(1.0, f) 54 } 55 } 56 57 #[inline(always)] round(f: f64) -> f6458 pub(crate) fn round(f: f64) -> f64 { 59 libm::round(f) 60 } 61 62 #[inline(always)] trunc(f: f64) -> f6463 pub(crate) fn trunc(f: f64) -> f64 { 64 libm::trunc(f) 65 } 66 67 #[inline(always)] ceil(f: f64) -> f6468 pub(crate) fn ceil(f: f64) -> f64 { 69 libm::ceil(f) 70 } 71 72 #[inline(always)] floor(f: f64) -> f6473 pub(crate) fn floor(f: f64) -> f64 { 74 libm::floor(f) 75 } 76 77 #[inline(always)] exp(f: f64) -> f6478 pub(crate) fn exp(f: f64) -> f64 { 79 libm::exp(f) 80 } 81 82 #[inline(always)] powf(f: f64, n: f64) -> f6483 pub(crate) fn powf(f: f64, n: f64) -> f64 { 84 libm::pow(f, n) 85 } 86 87 #[inline(always)] mul_add(a: f64, b: f64, c: f64) -> f6488 pub(crate) fn mul_add(a: f64, b: f64, c: f64) -> f64 { 89 libm::fma(a, b, c) 90 } 91 92 #[inline] div_euclid(a: f64, b: f64) -> f6493 pub fn div_euclid(a: f64, b: f64) -> f64 { 94 // Based on https://doc.rust-lang.org/src/std/f64.rs.html#293 95 let q = libm::trunc(a / b); 96 if a % b < 0.0 { 97 return if b > 0.0 { q - 1.0 } else { q + 1.0 }; 98 } 99 q 100 } 101 102 #[inline] rem_euclid(a: f64, b: f64) -> f64103 pub fn rem_euclid(a: f64, b: f64) -> f64 { 104 let r = a % b; 105 if r < 0.0 { 106 r + abs(b) 107 } else { 108 r 109 } 110 } 111 } 112 113 #[cfg(not(feature = "libm"))] 114 mod std_math { 115 #[inline(always)] abs(f: f64) -> f64116 pub(crate) fn abs(f: f64) -> f64 { 117 f64::abs(f) 118 } 119 120 #[inline(always)] acos_approx(f: f64) -> f64121 pub(crate) fn acos_approx(f: f64) -> f64 { 122 f64::acos(f64::clamp(f, -1.0, 1.0)) 123 } 124 125 #[inline(always)] asin(f: f64) -> f64126 pub(crate) fn asin(f: f64) -> f64 { 127 f64::asin(f) 128 } 129 130 #[inline(always)] atan2(f: f64, other: f64) -> f64131 pub(crate) fn atan2(f: f64, other: f64) -> f64 { 132 f64::atan2(f, other) 133 } 134 135 #[inline(always)] sin(f: f64) -> f64136 pub(crate) fn sin(f: f64) -> f64 { 137 f64::sin(f) 138 } 139 140 #[inline(always)] sin_cos(f: f64) -> (f64, f64)141 pub(crate) fn sin_cos(f: f64) -> (f64, f64) { 142 f64::sin_cos(f) 143 } 144 145 #[inline(always)] tan(f: f64) -> f64146 pub(crate) fn tan(f: f64) -> f64 { 147 f64::tan(f) 148 } 149 150 #[inline(always)] sqrt(f: f64) -> f64151 pub(crate) fn sqrt(f: f64) -> f64 { 152 f64::sqrt(f) 153 } 154 155 #[inline(always)] copysign(f: f64, sign: f64) -> f64156 pub(crate) fn copysign(f: f64, sign: f64) -> f64 { 157 f64::copysign(f, sign) 158 } 159 160 #[inline(always)] signum(f: f64) -> f64161 pub(crate) fn signum(f: f64) -> f64 { 162 f64::signum(f) 163 } 164 165 #[inline(always)] round(f: f64) -> f64166 pub(crate) fn round(f: f64) -> f64 { 167 f64::round(f) 168 } 169 170 #[inline(always)] trunc(f: f64) -> f64171 pub(crate) fn trunc(f: f64) -> f64 { 172 f64::trunc(f) 173 } 174 175 #[inline(always)] ceil(f: f64) -> f64176 pub(crate) fn ceil(f: f64) -> f64 { 177 f64::ceil(f) 178 } 179 180 #[inline(always)] floor(f: f64) -> f64181 pub(crate) fn floor(f: f64) -> f64 { 182 f64::floor(f) 183 } 184 185 #[inline(always)] exp(f: f64) -> f64186 pub(crate) fn exp(f: f64) -> f64 { 187 f64::exp(f) 188 } 189 190 #[inline(always)] powf(f: f64, n: f64) -> f64191 pub(crate) fn powf(f: f64, n: f64) -> f64 { 192 f64::powf(f, n) 193 } 194 195 #[inline(always)] mul_add(a: f64, b: f64, c: f64) -> f64196 pub(crate) fn mul_add(a: f64, b: f64, c: f64) -> f64 { 197 f64::mul_add(a, b, c) 198 } 199 200 #[inline] div_euclid(a: f64, b: f64) -> f64201 pub fn div_euclid(a: f64, b: f64) -> f64 { 202 f64::div_euclid(a, b) 203 } 204 205 #[inline] rem_euclid(a: f64, b: f64) -> f64206 pub fn rem_euclid(a: f64, b: f64) -> f64 { 207 f64::rem_euclid(a, b) 208 } 209 } 210 211 #[cfg(feature = "libm")] 212 pub(crate) use libm_math::*; 213 214 #[cfg(not(feature = "libm"))] 215 pub(crate) use std_math::*; 216