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)] atan2(f: f64, other: f64) -> f6414 pub(crate) fn atan2(f: f64, other: f64) -> f64 { 15 libm::atan2(f, other) 16 } 17 18 #[inline(always)] sin(f: f64) -> f6419 pub(crate) fn sin(f: f64) -> f64 { 20 libm::sin(f) 21 } 22 23 #[inline(always)] sin_cos(f: f64) -> (f64, f64)24 pub(crate) fn sin_cos(f: f64) -> (f64, f64) { 25 libm::sincos(f) 26 } 27 28 #[inline(always)] tan(f: f64) -> f6429 pub(crate) fn tan(f: f64) -> f64 { 30 libm::tan(f) 31 } 32 33 #[inline(always)] sqrt(f: f64) -> f6434 pub(crate) fn sqrt(f: f64) -> f64 { 35 libm::sqrt(f) 36 } 37 38 #[inline(always)] copysign(f: f64, sign: f64) -> f6439 pub(crate) fn copysign(f: f64, sign: f64) -> f64 { 40 libm::copysign(f, sign) 41 } 42 43 #[inline(always)] signum(f: f64) -> f6444 pub(crate) fn signum(f: f64) -> f64 { 45 if f.is_nan() { 46 f64::NAN 47 } else { 48 copysign(1.0, f) 49 } 50 } 51 52 #[inline(always)] round(f: f64) -> f6453 pub(crate) fn round(f: f64) -> f64 { 54 libm::round(f) 55 } 56 57 #[inline(always)] trunc(f: f64) -> f6458 pub(crate) fn trunc(f: f64) -> f64 { 59 libm::trunc(f) 60 } 61 62 #[inline(always)] ceil(f: f64) -> f6463 pub(crate) fn ceil(f: f64) -> f64 { 64 libm::ceil(f) 65 } 66 67 #[inline(always)] floor(f: f64) -> f6468 pub(crate) fn floor(f: f64) -> f64 { 69 libm::floor(f) 70 } 71 72 #[inline(always)] exp(f: f64) -> f6473 pub(crate) fn exp(f: f64) -> f64 { 74 libm::exp(f) 75 } 76 77 #[inline(always)] powf(f: f64, n: f64) -> f6478 pub(crate) fn powf(f: f64, n: f64) -> f64 { 79 libm::pow(f, n) 80 } 81 82 #[inline(always)] mul_add(a: f64, b: f64, c: f64) -> f6483 pub(crate) fn mul_add(a: f64, b: f64, c: f64) -> f64 { 84 libm::fma(a, b, c) 85 } 86 87 #[inline] div_euclid(a: f64, b: f64) -> f6488 pub fn div_euclid(a: f64, b: f64) -> f64 { 89 // Based on https://doc.rust-lang.org/src/std/f64.rs.html#293 90 let q = libm::trunc(a / b); 91 if a % b < 0.0 { 92 return if b > 0.0 { q - 1.0 } else { q + 1.0 }; 93 } 94 q 95 } 96 97 #[inline] rem_euclid(a: f64, b: f64) -> f6498 pub fn rem_euclid(a: f64, b: f64) -> f64 { 99 let r = a % b; 100 if r < 0.0 { 101 r + abs(b) 102 } else { 103 r 104 } 105 } 106 } 107 108 #[cfg(all(not(feature = "libm"), feature = "std"))] 109 mod std_math { 110 #[inline(always)] abs(f: f64) -> f64111 pub(crate) fn abs(f: f64) -> f64 { 112 f64::abs(f) 113 } 114 115 #[inline(always)] acos_approx(f: f64) -> f64116 pub(crate) fn acos_approx(f: f64) -> f64 { 117 f64::acos(f64::clamp(f, -1.0, 1.0)) 118 } 119 120 #[inline(always)] atan2(f: f64, other: f64) -> f64121 pub(crate) fn atan2(f: f64, other: f64) -> f64 { 122 f64::atan2(f, other) 123 } 124 125 #[inline(always)] sin(f: f64) -> f64126 pub(crate) fn sin(f: f64) -> f64 { 127 f64::sin(f) 128 } 129 130 #[inline(always)] sin_cos(f: f64) -> (f64, f64)131 pub(crate) fn sin_cos(f: f64) -> (f64, f64) { 132 f64::sin_cos(f) 133 } 134 135 #[inline(always)] tan(f: f64) -> f64136 pub(crate) fn tan(f: f64) -> f64 { 137 f64::tan(f) 138 } 139 140 #[inline(always)] sqrt(f: f64) -> f64141 pub(crate) fn sqrt(f: f64) -> f64 { 142 f64::sqrt(f) 143 } 144 145 #[inline(always)] copysign(f: f64, sign: f64) -> f64146 pub(crate) fn copysign(f: f64, sign: f64) -> f64 { 147 f64::copysign(f, sign) 148 } 149 150 #[inline(always)] signum(f: f64) -> f64151 pub(crate) fn signum(f: f64) -> f64 { 152 f64::signum(f) 153 } 154 155 #[inline(always)] round(f: f64) -> f64156 pub(crate) fn round(f: f64) -> f64 { 157 f64::round(f) 158 } 159 160 #[inline(always)] trunc(f: f64) -> f64161 pub(crate) fn trunc(f: f64) -> f64 { 162 f64::trunc(f) 163 } 164 165 #[inline(always)] ceil(f: f64) -> f64166 pub(crate) fn ceil(f: f64) -> f64 { 167 f64::ceil(f) 168 } 169 170 #[inline(always)] floor(f: f64) -> f64171 pub(crate) fn floor(f: f64) -> f64 { 172 f64::floor(f) 173 } 174 175 #[inline(always)] exp(f: f64) -> f64176 pub(crate) fn exp(f: f64) -> f64 { 177 f64::exp(f) 178 } 179 180 #[inline(always)] powf(f: f64, n: f64) -> f64181 pub(crate) fn powf(f: f64, n: f64) -> f64 { 182 f64::powf(f, n) 183 } 184 185 #[inline(always)] mul_add(a: f64, b: f64, c: f64) -> f64186 pub(crate) fn mul_add(a: f64, b: f64, c: f64) -> f64 { 187 f64::mul_add(a, b, c) 188 } 189 190 #[inline] div_euclid(a: f64, b: f64) -> f64191 pub fn div_euclid(a: f64, b: f64) -> f64 { 192 f64::div_euclid(a, b) 193 } 194 195 #[inline] rem_euclid(a: f64, b: f64) -> f64196 pub fn rem_euclid(a: f64, b: f64) -> f64 { 197 f64::rem_euclid(a, b) 198 } 199 } 200 201 // Used to reduce the number of compilation errors, in the event that no other 202 // math backend is specified. 203 #[cfg(all(not(feature = "libm"), not(feature = "std")))] 204 mod no_backend_math { abs(_: f64) -> f64205 pub(crate) fn abs(_: f64) -> f64 { 206 unimplemented!() 207 } 208 acos_approx(_: f64) -> f64209 pub(crate) fn acos_approx(_: f64) -> f64 { 210 unimplemented!() 211 } 212 atan2(_: f64, _: f64) -> f64213 pub(crate) fn atan2(_: f64, _: f64) -> f64 { 214 unimplemented!() 215 } 216 sin(_: f64) -> f64217 pub(crate) fn sin(_: f64) -> f64 { 218 unimplemented!() 219 } 220 sin_cos(_: f64) -> (f64, f64)221 pub(crate) fn sin_cos(_: f64) -> (f64, f64) { 222 unimplemented!() 223 } 224 tan(_: f64) -> f64225 pub(crate) fn tan(_: f64) -> f64 { 226 unimplemented!() 227 } 228 sqrt(_: f64) -> f64229 pub(crate) fn sqrt(_: f64) -> f64 { 230 unimplemented!() 231 } 232 copysign(_: f64, _: f64) -> f64233 pub(crate) fn copysign(_: f64, _: f64) -> f64 { 234 unimplemented!() 235 } 236 signum(_: f64) -> f64237 pub(crate) fn signum(_: f64) -> f64 { 238 unimplemented!() 239 } 240 round(_: f64) -> f64241 pub(crate) fn round(_: f64) -> f64 { 242 unimplemented!() 243 } 244 trunc(_: f64) -> f64245 pub(crate) fn trunc(_: f64) -> f64 { 246 unimplemented!() 247 } 248 ceil(_: f64) -> f64249 pub(crate) fn ceil(_: f64) -> f64 { 250 unimplemented!() 251 } 252 floor(_: f64) -> f64253 pub(crate) fn floor(_: f64) -> f64 { 254 unimplemented!() 255 } 256 exp(_: f64) -> f64257 pub(crate) fn exp(_: f64) -> f64 { 258 unimplemented!() 259 } 260 powf(_: f64, _: f64) -> f64261 pub(crate) fn powf(_: f64, _: f64) -> f64 { 262 unimplemented!() 263 } 264 mul_add(_: f64, _: f64, _: f64) -> f64265 pub(crate) fn mul_add(_: f64, _: f64, _: f64) -> f64 { 266 unimplemented!() 267 } 268 div_euclid(_: f64, _: f64) -> f64269 pub fn div_euclid(_: f64, _: f64) -> f64 { 270 unimplemented!() 271 } 272 rem_euclid(_: f64, _: f64) -> f64273 pub fn rem_euclid(_: f64, _: f64) -> f64 { 274 unimplemented!() 275 } 276 } 277 278 #[cfg(feature = "libm")] 279 pub(crate) use libm_math::*; 280 281 #[cfg(all(not(feature = "libm"), feature = "std"))] 282 pub(crate) use std_math::*; 283 284 #[cfg(all(not(feature = "libm"), not(feature = "std")))] 285 pub(crate) use no_backend_math::*; 286