1 | //! Floating point operations |
2 | |
3 | pub(crate) mod abs; |
4 | pub(crate) mod acos; |
5 | pub(crate) mod asin; |
6 | pub(crate) mod atan; |
7 | pub(crate) mod atan2; |
8 | pub(crate) mod ceil; |
9 | pub(crate) mod copysign; |
10 | pub(crate) mod cos; |
11 | pub(crate) mod div_euclid; |
12 | pub(crate) mod exp; |
13 | pub(crate) mod floor; |
14 | pub(crate) mod fract; |
15 | pub(crate) mod hypot; |
16 | pub(crate) mod inv; |
17 | pub(crate) mod invsqrt; |
18 | pub(crate) mod ln; |
19 | pub(crate) mod log; |
20 | pub(crate) mod log10; |
21 | pub(crate) mod log2; |
22 | pub(crate) mod mul_add; |
23 | pub(crate) mod powf; |
24 | pub(crate) mod powi; |
25 | pub(crate) mod recip; |
26 | pub(crate) mod rem_euclid; |
27 | pub(crate) mod round; |
28 | pub(crate) mod signum; |
29 | pub(crate) mod sin; |
30 | pub(crate) mod sin_cos; |
31 | pub(crate) mod sqrt; |
32 | pub(crate) mod tan; |
33 | pub(crate) mod trunc; |
34 | |
35 | use 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" )] |
45 | use num_traits::{Inv, Num, One, Zero}; |
46 | |
47 | /// Sign mask. |
48 | pub(crate) const SIGN_MASK: u32 = 0b1000_0000_0000_0000_0000_0000_0000_0000; |
49 | |
50 | /// Exponent mask. |
51 | pub(crate) const EXPONENT_MASK: u32 = 0b0111_1111_1000_0000_0000_0000_0000_0000; |
52 | |
53 | /// Mantissa mask. |
54 | pub(crate) const MANTISSA_MASK: u32 = 0b0000_0000_0111_1111_1111_1111_1111_1111; |
55 | |
56 | /// Exponent mask. |
57 | pub(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. |
62 | pub(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)] |
67 | pub struct F32(pub f32); |
68 | |
69 | impl 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 | |
237 | impl 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 | |
246 | impl 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 | |
255 | impl 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 | |
264 | impl AddAssign for F32 { |
265 | #[inline ] |
266 | fn add_assign(&mut self, rhs: F32) { |
267 | self.0 += rhs.0; |
268 | } |
269 | } |
270 | |
271 | impl AddAssign<f32> for F32 { |
272 | #[inline ] |
273 | fn add_assign(&mut self, rhs: f32) { |
274 | self.0 += rhs; |
275 | } |
276 | } |
277 | |
278 | impl AddAssign<F32> for f32 { |
279 | #[inline ] |
280 | fn add_assign(&mut self, rhs: F32) { |
281 | *self += rhs.0; |
282 | } |
283 | } |
284 | |
285 | impl Display for F32 { |
286 | #[inline ] |
287 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
288 | write!(fmt, " {}" , self.0) |
289 | } |
290 | } |
291 | |
292 | impl 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 | |
301 | impl 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 | |
310 | impl 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 | |
319 | impl DivAssign for F32 { |
320 | #[inline ] |
321 | fn div_assign(&mut self, rhs: F32) { |
322 | self.0 /= rhs.0; |
323 | } |
324 | } |
325 | |
326 | impl DivAssign<f32> for F32 { |
327 | #[inline ] |
328 | fn div_assign(&mut self, rhs: f32) { |
329 | self.0 /= rhs; |
330 | } |
331 | } |
332 | |
333 | impl DivAssign<F32> for f32 { |
334 | #[inline ] |
335 | fn div_assign(&mut self, rhs: F32) { |
336 | *self /= rhs.0; |
337 | } |
338 | } |
339 | |
340 | impl From<f32> for F32 { |
341 | #[inline ] |
342 | fn from(n: f32) -> F32 { |
343 | F32(n) |
344 | } |
345 | } |
346 | |
347 | impl From<F32> for f32 { |
348 | #[inline ] |
349 | fn from(n: F32) -> f32 { |
350 | n.0 |
351 | } |
352 | } |
353 | |
354 | impl From<i8> for F32 { |
355 | #[inline ] |
356 | fn from(n: i8) -> F32 { |
357 | F32(n.into()) |
358 | } |
359 | } |
360 | |
361 | impl From<i16> for F32 { |
362 | #[inline ] |
363 | fn from(n: i16) -> F32 { |
364 | F32(n.into()) |
365 | } |
366 | } |
367 | |
368 | impl From<u8> for F32 { |
369 | #[inline ] |
370 | fn from(n: u8) -> F32 { |
371 | F32(n.into()) |
372 | } |
373 | } |
374 | |
375 | impl From<u16> for F32 { |
376 | #[inline ] |
377 | fn from(n: u16) -> F32 { |
378 | F32(n.into()) |
379 | } |
380 | } |
381 | |
382 | impl 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 | |
391 | impl LowerExp for F32 { |
392 | #[inline ] |
393 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
394 | write!(f, " {:e}" , self.0) |
395 | } |
396 | } |
397 | |
398 | impl 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 | |
407 | impl 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 | |
416 | impl 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 | |
425 | impl MulAssign for F32 { |
426 | #[inline ] |
427 | fn mul_assign(&mut self, rhs: F32) { |
428 | self.0 *= rhs.0; |
429 | } |
430 | } |
431 | |
432 | impl MulAssign<f32> for F32 { |
433 | #[inline ] |
434 | fn mul_assign(&mut self, rhs: f32) { |
435 | self.0 *= rhs; |
436 | } |
437 | } |
438 | |
439 | impl MulAssign<F32> for f32 { |
440 | #[inline ] |
441 | fn mul_assign(&mut self, rhs: F32) { |
442 | *self *= rhs.0; |
443 | } |
444 | } |
445 | |
446 | impl Neg for F32 { |
447 | type Output = F32; |
448 | |
449 | #[inline ] |
450 | fn neg(self) -> F32 { |
451 | F32(-self.0) |
452 | } |
453 | } |
454 | |
455 | impl PartialEq<f32> for F32 { |
456 | fn eq(&self, other: &f32) -> bool { |
457 | self.0.eq(other) |
458 | } |
459 | } |
460 | |
461 | impl PartialEq<F32> for f32 { |
462 | fn eq(&self, other: &F32) -> bool { |
463 | self.eq(&other.0) |
464 | } |
465 | } |
466 | |
467 | impl PartialOrd<f32> for F32 { |
468 | fn partial_cmp(&self, other: &f32) -> Option<Ordering> { |
469 | self.0.partial_cmp(other) |
470 | } |
471 | } |
472 | |
473 | impl PartialOrd<F32> for f32 { |
474 | fn partial_cmp(&self, other: &F32) -> Option<Ordering> { |
475 | self.partial_cmp(&other.0) |
476 | } |
477 | } |
478 | |
479 | impl 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 | |
489 | impl 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 | |
498 | impl 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 | |
507 | impl 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 | |
516 | impl RemAssign for F32 { |
517 | #[inline ] |
518 | fn rem_assign(&mut self, rhs: F32) { |
519 | self.0 %= rhs.0; |
520 | } |
521 | } |
522 | |
523 | impl RemAssign<f32> for F32 { |
524 | #[inline ] |
525 | fn rem_assign(&mut self, rhs: f32) { |
526 | self.0 %= rhs; |
527 | } |
528 | } |
529 | |
530 | impl 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 | |
539 | impl 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 | |
548 | impl 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 | |
557 | impl SubAssign for F32 { |
558 | #[inline ] |
559 | fn sub_assign(&mut self, rhs: F32) { |
560 | self.0 -= rhs.0; |
561 | } |
562 | } |
563 | |
564 | impl SubAssign<f32> for F32 { |
565 | #[inline ] |
566 | fn sub_assign(&mut self, rhs: f32) { |
567 | self.0 -= rhs; |
568 | } |
569 | } |
570 | |
571 | impl SubAssign<F32> for f32 { |
572 | #[inline ] |
573 | fn sub_assign(&mut self, rhs: F32) { |
574 | *self -= rhs.0; |
575 | } |
576 | } |
577 | |
578 | impl 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 | |
588 | impl 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" )))] |
597 | impl 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" )))] |
609 | impl 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" )))] |
621 | impl 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" )))] |
631 | impl Inv for F32 { |
632 | type Output = Self; |
633 | |
634 | fn inv(self) -> Self { |
635 | self.inv() |
636 | } |
637 | } |
638 | |
639 | #[cfg (test)] |
640 | mod 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 | |