1//! Floating point operations
2
3pub(crate) mod abs;
4pub(crate) mod acos;
5pub(crate) mod asin;
6pub(crate) mod atan;
7pub(crate) mod atan2;
8pub(crate) mod ceil;
9pub(crate) mod copysign;
10pub(crate) mod cos;
11pub(crate) mod div_euclid;
12pub(crate) mod exp;
13pub(crate) mod floor;
14pub(crate) mod fract;
15pub(crate) mod hypot;
16pub(crate) mod inv;
17pub(crate) mod invsqrt;
18pub(crate) mod ln;
19pub(crate) mod log;
20pub(crate) mod log10;
21pub(crate) mod log2;
22pub(crate) mod mul_add;
23pub(crate) mod powf;
24pub(crate) mod powi;
25pub(crate) mod recip;
26pub(crate) mod rem_euclid;
27pub(crate) mod round;
28pub(crate) mod signum;
29pub(crate) mod sin;
30pub(crate) mod sin_cos;
31pub(crate) mod sqrt;
32pub(crate) mod tan;
33pub(crate) mod trunc;
34
35use core::{
36 cmp::Ordering,
37 fmt::{self, Display, LowerExp, UpperExp},
38 iter::{Product, Sum},
39 num::ParseFloatError,
40 ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign},
41 str::FromStr,
42};
43
44#[cfg(feature = "num-traits")]
45use num_traits::{Inv, Num, One, Zero};
46
47/// Sign mask.
48pub(crate) const SIGN_MASK: u32 = 0b1000_0000_0000_0000_0000_0000_0000_0000;
49
50/// Exponent mask.
51pub(crate) const EXPONENT_MASK: u32 = 0b0111_1111_1000_0000_0000_0000_0000_0000;
52
53/// Mantissa mask.
54pub(crate) const MANTISSA_MASK: u32 = 0b0000_0000_0111_1111_1111_1111_1111_1111;
55
56/// Exponent mask.
57pub(crate) const EXPONENT_BIAS: u32 = 127;
58
59/// Mantissa bits.
60///
61/// Note: `MANTISSA_DIGITS` is available in `core::f32`, but the actual bits taken up are 24 - 1.
62pub(crate) const MANTISSA_BITS: u32 = 23;
63
64/// 32-bit floating point wrapper which implements fast approximation-based
65/// operations.
66#[derive(Copy, Clone, Debug, Default, PartialEq, PartialOrd)]
67pub struct F32(pub f32);
68
69impl F32 {
70 /// The value `0.0`.
71 pub const ZERO: Self = Self(0.0);
72
73 /// The value `1.0`.
74 pub const ONE: Self = Self(1.0);
75
76 /// The radix or base of the internal representation of `f32`.
77 pub const RADIX: u32 = f32::RADIX;
78
79 /// Number of significant digits in base 2.
80 pub const MANTISSA_DIGITS: u32 = f32::MANTISSA_DIGITS;
81
82 /// Approximate number of significant digits in base 10.
83 pub const DIGITS: u32 = f32::DIGITS;
84
85 /// [Machine epsilon] value for `f32`.
86 ///
87 /// This is the difference between `1.0` and the next larger representable number.
88 ///
89 /// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon
90 pub const EPSILON: Self = Self(f32::EPSILON);
91
92 /// Smallest finite `f32` value.
93 pub const MIN: Self = Self(f32::MIN);
94
95 /// Smallest positive normal `f32` value.
96 pub const MIN_POSITIVE: Self = Self(f32::MIN_POSITIVE);
97
98 /// Largest finite `f32` value.
99 pub const MAX: Self = Self(f32::MAX);
100
101 /// One greater than the minimum possible normal power of 2 exponent.
102 pub const MIN_EXP: i32 = f32::MIN_EXP;
103
104 /// Maximum possible power of 2 exponent.
105 pub const MAX_EXP: i32 = f32::MAX_EXP;
106
107 /// Minimum possible normal power of 10 exponent.
108 pub const MIN_10_EXP: i32 = f32::MIN_10_EXP;
109
110 /// Maximum possible power of 10 exponent.
111 pub const MAX_10_EXP: i32 = f32::MAX_10_EXP;
112
113 /// Not a Number (NaN).
114 pub const NAN: Self = Self(f32::NAN);
115
116 /// Infinity (∞).
117 pub const INFINITY: Self = Self(f32::INFINITY);
118
119 /// Negative infinity (−∞).
120 pub const NEG_INFINITY: Self = Self(f32::NEG_INFINITY);
121
122 /// Returns `true` if this value is `NaN`.
123 #[inline]
124 pub fn is_nan(self) -> bool {
125 self.0.is_nan()
126 }
127
128 /// Returns `true` if this value is positive infinity or negative infinity, and
129 /// `false` otherwise.
130 #[inline]
131 pub fn is_infinite(self) -> bool {
132 self.0.is_infinite()
133 }
134
135 /// Returns `true` if this number is neither infinite nor `NaN`.
136 #[inline]
137 pub fn is_finite(self) -> bool {
138 self.0.is_finite()
139 }
140
141 /// Returns `true` if `self` has a positive sign, including `+0.0`, `NaN`s with
142 /// positive sign bit and positive infinity.
143 #[inline]
144 pub fn is_sign_positive(self) -> bool {
145 self.0.is_sign_positive()
146 }
147
148 /// Returns `true` if `self` has a negative sign, including `-0.0`, `NaN`s with
149 /// negative sign bit and negative infinity.
150 #[inline]
151 pub fn is_sign_negative(self) -> bool {
152 self.0.is_sign_negative()
153 }
154
155 /// Raw transmutation to `u32`.
156 ///
157 /// This is currently identical to `transmute::<f32, u32>(self)` on all platforms.
158 ///
159 /// See [`F32::from_bits`] for some discussion of the portability of this operation
160 /// (there are almost no issues).
161 #[inline]
162 pub fn to_bits(self) -> u32 {
163 self.0.to_bits()
164 }
165
166 /// Raw transmutation from `u32`.
167 ///
168 /// This is currently identical to `transmute::<u32, f32>(v)` on all platforms.
169 /// It turns out this is incredibly portable, for two reasons:
170 ///
171 /// - Floats and Ints have the same endianness on all supported platforms.
172 /// - IEEE-754 very precisely specifies the bit layout of floats.
173 ///
174 /// See [`f32::from_bits`] for more information.
175 #[inline]
176 pub fn from_bits(v: u32) -> Self {
177 Self(f32::from_bits(v))
178 }
179
180 /// Extract exponent bits.
181 pub(crate) fn extract_exponent_bits(self) -> u32 {
182 (self.to_bits() & EXPONENT_MASK)
183 .overflowing_shr(MANTISSA_BITS)
184 .0
185 }
186
187 /// Extract the exponent of a float's value.
188 pub(crate) fn extract_exponent_value(self) -> i32 {
189 (self.extract_exponent_bits() as i32) - EXPONENT_BIAS as i32
190 }
191
192 /// Remove sign.
193 pub(crate) fn without_sign(self) -> Self {
194 Self::from_bits(self.to_bits() & !SIGN_MASK)
195 }
196
197 /// Set the exponent to the given value.
198 pub(crate) fn set_exponent(self, exponent: i32) -> Self {
199 debug_assert!(exponent <= 127 && exponent >= -128);
200 let without_exponent: u32 = self.to_bits() & !EXPONENT_MASK;
201 let only_exponent: u32 = ((exponent + EXPONENT_BIAS as i32) as u32)
202 .overflowing_shl(MANTISSA_BITS)
203 .0;
204
205 Self::from_bits(without_exponent | only_exponent)
206 }
207
208 /// Is this floating point value equivalent to an integer?
209 pub(crate) fn is_integer(&self) -> bool {
210 let exponent = self.extract_exponent_value();
211 let self_bits = self.to_bits();
212
213 // if exponent is negative we shouldn't remove anything, this stops an opposite shift.
214 let exponent_clamped = i32::max(exponent, 0) as u32;
215
216 // find the part of the fraction that would be left over
217 let fractional_part = (self_bits).overflowing_shl(exponent_clamped).0 & MANTISSA_MASK;
218
219 // if fractional part contains anything, we know it *isn't* an integer.
220 // if zero there will be nothing in the fractional part
221 // if it is whole, there will be nothing in the fractional part
222 fractional_part == 0
223 }
224
225 /// Is this floating point value even?
226 fn is_even(&self) -> bool {
227 // any floating point value that doesn't fit in an i32 range is even,
228 // and will loose 1's digit precision at exp values of 23+
229 if self.extract_exponent_value() >= 31 {
230 true
231 } else {
232 (self.0 as i32) % 2 == 0
233 }
234 }
235}
236
237impl Add for F32 {
238 type Output = F32;
239
240 #[inline]
241 fn add(self, rhs: F32) -> F32 {
242 F32(self.0 + rhs.0)
243 }
244}
245
246impl Add<f32> for F32 {
247 type Output = F32;
248
249 #[inline]
250 fn add(self, rhs: f32) -> F32 {
251 F32(self.0 + rhs)
252 }
253}
254
255impl Add<F32> for f32 {
256 type Output = F32;
257
258 #[inline]
259 fn add(self, rhs: F32) -> F32 {
260 F32(self + rhs.0)
261 }
262}
263
264impl AddAssign for F32 {
265 #[inline]
266 fn add_assign(&mut self, rhs: F32) {
267 self.0 += rhs.0;
268 }
269}
270
271impl AddAssign<f32> for F32 {
272 #[inline]
273 fn add_assign(&mut self, rhs: f32) {
274 self.0 += rhs;
275 }
276}
277
278impl AddAssign<F32> for f32 {
279 #[inline]
280 fn add_assign(&mut self, rhs: F32) {
281 *self += rhs.0;
282 }
283}
284
285impl Display for F32 {
286 #[inline]
287 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
288 write!(fmt, "{}", self.0)
289 }
290}
291
292impl Div for F32 {
293 type Output = F32;
294
295 #[inline]
296 fn div(self, rhs: F32) -> F32 {
297 F32(self.0 / rhs.0)
298 }
299}
300
301impl Div<f32> for F32 {
302 type Output = F32;
303
304 #[inline]
305 fn div(self, rhs: f32) -> F32 {
306 F32(self.0 / rhs)
307 }
308}
309
310impl Div<F32> for f32 {
311 type Output = F32;
312
313 #[inline]
314 fn div(self, rhs: F32) -> F32 {
315 F32(self / rhs.0)
316 }
317}
318
319impl DivAssign for F32 {
320 #[inline]
321 fn div_assign(&mut self, rhs: F32) {
322 self.0 /= rhs.0;
323 }
324}
325
326impl DivAssign<f32> for F32 {
327 #[inline]
328 fn div_assign(&mut self, rhs: f32) {
329 self.0 /= rhs;
330 }
331}
332
333impl DivAssign<F32> for f32 {
334 #[inline]
335 fn div_assign(&mut self, rhs: F32) {
336 *self /= rhs.0;
337 }
338}
339
340impl From<f32> for F32 {
341 #[inline]
342 fn from(n: f32) -> F32 {
343 F32(n)
344 }
345}
346
347impl From<F32> for f32 {
348 #[inline]
349 fn from(n: F32) -> f32 {
350 n.0
351 }
352}
353
354impl From<i8> for F32 {
355 #[inline]
356 fn from(n: i8) -> F32 {
357 F32(n.into())
358 }
359}
360
361impl From<i16> for F32 {
362 #[inline]
363 fn from(n: i16) -> F32 {
364 F32(n.into())
365 }
366}
367
368impl From<u8> for F32 {
369 #[inline]
370 fn from(n: u8) -> F32 {
371 F32(n.into())
372 }
373}
374
375impl From<u16> for F32 {
376 #[inline]
377 fn from(n: u16) -> F32 {
378 F32(n.into())
379 }
380}
381
382impl FromStr for F32 {
383 type Err = ParseFloatError;
384
385 #[inline]
386 fn from_str(src: &str) -> Result<F32, ParseFloatError> {
387 f32::from_str(src).map(op:F32)
388 }
389}
390
391impl LowerExp for F32 {
392 #[inline]
393 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
394 write!(f, "{:e}", self.0)
395 }
396}
397
398impl Mul for F32 {
399 type Output = F32;
400
401 #[inline]
402 fn mul(self, rhs: F32) -> F32 {
403 F32(self.0 * rhs.0)
404 }
405}
406
407impl Mul<f32> for F32 {
408 type Output = F32;
409
410 #[inline]
411 fn mul(self, rhs: f32) -> F32 {
412 F32(self.0 * rhs)
413 }
414}
415
416impl Mul<F32> for f32 {
417 type Output = F32;
418
419 #[inline]
420 fn mul(self, rhs: F32) -> F32 {
421 F32(self * rhs.0)
422 }
423}
424
425impl MulAssign for F32 {
426 #[inline]
427 fn mul_assign(&mut self, rhs: F32) {
428 self.0 *= rhs.0;
429 }
430}
431
432impl MulAssign<f32> for F32 {
433 #[inline]
434 fn mul_assign(&mut self, rhs: f32) {
435 self.0 *= rhs;
436 }
437}
438
439impl MulAssign<F32> for f32 {
440 #[inline]
441 fn mul_assign(&mut self, rhs: F32) {
442 *self *= rhs.0;
443 }
444}
445
446impl Neg for F32 {
447 type Output = F32;
448
449 #[inline]
450 fn neg(self) -> F32 {
451 F32(-self.0)
452 }
453}
454
455impl PartialEq<f32> for F32 {
456 fn eq(&self, other: &f32) -> bool {
457 self.0.eq(other)
458 }
459}
460
461impl PartialEq<F32> for f32 {
462 fn eq(&self, other: &F32) -> bool {
463 self.eq(&other.0)
464 }
465}
466
467impl PartialOrd<f32> for F32 {
468 fn partial_cmp(&self, other: &f32) -> Option<Ordering> {
469 self.0.partial_cmp(other)
470 }
471}
472
473impl PartialOrd<F32> for f32 {
474 fn partial_cmp(&self, other: &F32) -> Option<Ordering> {
475 self.partial_cmp(&other.0)
476 }
477}
478
479impl Product for F32 {
480 #[inline]
481 fn product<I>(iter: I) -> Self
482 where
483 I: Iterator<Item = F32>,
484 {
485 F32(f32::product(iter.map(f32::from)))
486 }
487}
488
489impl Rem for F32 {
490 type Output = F32;
491
492 #[inline]
493 fn rem(self, rhs: F32) -> F32 {
494 F32(self.0 % rhs.0)
495 }
496}
497
498impl Rem<f32> for F32 {
499 type Output = F32;
500
501 #[inline]
502 fn rem(self, rhs: f32) -> F32 {
503 F32(self.0 % rhs)
504 }
505}
506
507impl Rem<F32> for f32 {
508 type Output = F32;
509
510 #[inline]
511 fn rem(self, rhs: F32) -> F32 {
512 F32(self % rhs.0)
513 }
514}
515
516impl RemAssign for F32 {
517 #[inline]
518 fn rem_assign(&mut self, rhs: F32) {
519 self.0 %= rhs.0;
520 }
521}
522
523impl RemAssign<f32> for F32 {
524 #[inline]
525 fn rem_assign(&mut self, rhs: f32) {
526 self.0 %= rhs;
527 }
528}
529
530impl Sub for F32 {
531 type Output = F32;
532
533 #[inline]
534 fn sub(self, rhs: F32) -> F32 {
535 F32(self.0 - rhs.0)
536 }
537}
538
539impl Sub<f32> for F32 {
540 type Output = F32;
541
542 #[inline]
543 fn sub(self, rhs: f32) -> F32 {
544 F32(self.0 - rhs)
545 }
546}
547
548impl Sub<F32> for f32 {
549 type Output = F32;
550
551 #[inline]
552 fn sub(self, rhs: F32) -> F32 {
553 F32(self - rhs.0)
554 }
555}
556
557impl SubAssign for F32 {
558 #[inline]
559 fn sub_assign(&mut self, rhs: F32) {
560 self.0 -= rhs.0;
561 }
562}
563
564impl SubAssign<f32> for F32 {
565 #[inline]
566 fn sub_assign(&mut self, rhs: f32) {
567 self.0 -= rhs;
568 }
569}
570
571impl SubAssign<F32> for f32 {
572 #[inline]
573 fn sub_assign(&mut self, rhs: F32) {
574 *self -= rhs.0;
575 }
576}
577
578impl Sum for F32 {
579 #[inline]
580 fn sum<I>(iter: I) -> Self
581 where
582 I: Iterator<Item = F32>,
583 {
584 F32(f32::sum(iter.map(f32::from)))
585 }
586}
587
588impl UpperExp for F32 {
589 #[inline]
590 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
591 write!(f, "{:E}", self.0)
592 }
593}
594
595#[cfg(feature = "num-traits")]
596#[cfg_attr(docsrs, doc(cfg(feature = "num-traits")))]
597impl Zero for F32 {
598 fn zero() -> Self {
599 Self::ZERO
600 }
601
602 fn is_zero(&self) -> bool {
603 Self::ZERO == *self
604 }
605}
606
607#[cfg(feature = "num-traits")]
608#[cfg_attr(docsrs, doc(cfg(feature = "num-traits")))]
609impl One for F32 {
610 fn one() -> Self {
611 Self::ONE
612 }
613
614 fn is_one(&self) -> bool {
615 Self::ONE == *self
616 }
617}
618
619#[cfg(feature = "num-traits")]
620#[cfg_attr(docsrs, doc(cfg(feature = "num-traits")))]
621impl Num for F32 {
622 type FromStrRadixErr = num_traits::ParseFloatError;
623
624 fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
625 f32::from_str_radix(str, radix).map(Self)
626 }
627}
628
629#[cfg(feature = "num-traits")]
630#[cfg_attr(docsrs, doc(cfg(feature = "num-traits")))]
631impl Inv for F32 {
632 type Output = Self;
633
634 fn inv(self) -> Self {
635 self.inv()
636 }
637}
638
639#[cfg(test)]
640mod tests {
641 #[allow(unused_imports)] // remove when we have more tests
642 use super::F32;
643
644 #[cfg(feature = "num-traits")]
645 #[test]
646 fn inv_trait() {
647 assert_eq!(num_traits::Inv::inv(F32(2.0)), F32(0.5));
648 }
649}
650