malachite_base/num/basic/floats.rs
1// Copyright © 2025 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::comparison::traits::{Max, Min};
10use crate::named::Named;
11use crate::num::arithmetic::traits::{
12 Abs, AbsAssign, AddMul, AddMulAssign, Ceiling, CeilingAssign, CeilingLogBase2,
13 CeilingLogBasePowerOf2, CheckedLogBase2, CheckedLogBasePowerOf2, Floor, FloorAssign,
14 FloorLogBase2, FloorLogBasePowerOf2, IsPowerOf2, Ln, NegAssign, NextPowerOf2,
15 NextPowerOf2Assign, Pow, PowAssign, PowerOf2, Reciprocal, ReciprocalAssign, Sign, Sqrt,
16 SqrtAssign, Square, SquareAssign, SubMul, SubMulAssign,
17};
18use crate::num::basic::traits::{
19 Infinity, NaN, NegativeInfinity, NegativeOne, NegativeZero, One, OneHalf, PrimeConstant,
20 ThueMorseConstant, Two, Zero,
21};
22use crate::num::comparison::traits::PartialOrdAbs;
23use crate::num::conversion::traits::{
24 ConvertibleFrom, ExactInto, IntegerMantissaAndExponent, IsInteger, RawMantissaAndExponent,
25 RoundingFrom, RoundingInto, SciMantissaAndExponent, WrappingFrom,
26};
27use crate::num::float::FmtRyuString;
28use crate::num::logic::traits::{BitAccess, LowMask, SignificantBits, TrailingZeros};
29use core::cmp::Ordering::*;
30use core::fmt::{Debug, Display, LowerExp, UpperExp};
31use core::iter::{Product, Sum};
32use core::num::FpCategory;
33use core::ops::{
34 Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign,
35};
36use core::panic::RefUnwindSafe;
37use core::str::FromStr;
38
39/// This trait defines functions on primitive float types: [`f32`] and [`f64`].
40///
41/// Many of the functions here concern exponents and mantissas. We define three ways to express a
42/// float, each with its own exponent and mantissa. In the following, let $x$ be an arbitrary
43/// positive, finite, non-zero, non-NaN float. Let $M$ and $E$ be the mantissa width and exponent
44/// width of the floating point type; for [`f32`]s, this is 23 and 8, and for [`f64`]s it's 52 and
45/// 11.
46///
47/// In the following we assume that $x$ is positive, but you can easily extend these definitions to
48/// negative floats by first taking their absolute value.
49///
50/// # raw form
51/// The raw exponent and raw mantissa are the actual bit patterns used to represent the components
52/// of $x$. The raw exponent $e_r$ is an integer in $[0, 2^E-2]$ and the raw mantissa $m_r$ is an
53/// integer in $[0, 2^M-1]$. Since we are dealing with a nonzero $x$, we forbid $e_r$ and $m_r$ from
54/// both being zero. We have
55/// $$
56/// x = \\begin{cases}
57/// 2^{2-2^{E-1}-M}m_r & \text{if} \quad e_r = 0, \\\\
58/// 2^{e_r-2^{E-1}+1}(2^{-M}m_r+1) & \textrm{otherwise},
59/// \\end{cases}
60/// $$
61/// $$
62/// e_r = \\begin{cases}
63/// 0 & \text{if} \quad x < 2^{2-2^{E-1}}, \\\\
64/// \lfloor \log_2 x \rfloor + 2^{E-1} - 1 & \textrm{otherwise},
65/// \\end{cases}
66/// $$
67/// $$
68/// m_r = \\begin{cases}
69/// 2^{M+2^{E-1}-2}x & \text{if} \quad x < 2^{2-2^{E-1}}, \\\\
70/// 2^M \left ( \frac{x}{2^{\lfloor \log_2 x \rfloor}}-1\right ) & \textrm{otherwise}.
71/// \\end{cases}
72/// $$
73///
74/// # scientific form
75/// We can write $x = 2^{e_s}m_s$, where $e_s$ is an integer and $m_s$ is a rational number with $1
76/// \leq m_s < 2$. If $x$ is a valid float, the scientific mantissa $m_s$ is always exactly
77/// representable as a float of the same type. We have
78/// $$
79/// x = 2^{e_s}m_s,
80/// $$
81/// $$
82/// e_s = \lfloor \log_2 x \rfloor,
83/// $$
84/// $$
85/// m_s = \frac{x}{2^{\lfloor \log_2 x \rfloor}}.
86/// $$
87///
88/// # integer form
89/// We can also write $x = 2^{e_i}m_i$, where $e_i$ is an integer and $m_i$ is an odd integer. We
90/// have
91/// $$
92/// x = 2^{e_i}m_i,
93/// $$
94/// $e_i$ is the unique integer such that $x/2^{e_i}$is an odd integer, and
95/// $$
96/// m_i = \frac{x}{2^{e_i}}.
97/// $$
98pub trait PrimitiveFloat:
99 'static
100 + Abs<Output = Self>
101 + AbsAssign
102 + Add<Output = Self>
103 + AddAssign<Self>
104 + AddMul<Output = Self>
105 + AddMulAssign<Self, Self>
106 + Ceiling<Output = Self>
107 + CeilingAssign
108 + CeilingLogBase2<Output = i64>
109 + CeilingLogBasePowerOf2<u64, Output = i64>
110 + CheckedLogBase2<Output = i64>
111 + CheckedLogBasePowerOf2<u64, Output = i64>
112 + ConvertibleFrom<u8>
113 + ConvertibleFrom<u16>
114 + ConvertibleFrom<u32>
115 + ConvertibleFrom<u64>
116 + ConvertibleFrom<u128>
117 + ConvertibleFrom<usize>
118 + ConvertibleFrom<i8>
119 + ConvertibleFrom<i16>
120 + ConvertibleFrom<i32>
121 + ConvertibleFrom<i64>
122 + ConvertibleFrom<i128>
123 + ConvertibleFrom<isize>
124 + Copy
125 + Debug
126 + Default
127 + Display
128 + Div<Output = Self>
129 + DivAssign
130 + Floor<Output = Self>
131 + FloorAssign
132 + FloorLogBase2<Output = i64>
133 + FloorLogBasePowerOf2<u64, Output = i64>
134 + FmtRyuString
135 + From<f32>
136 + FromStr
137 + Infinity
138 + IntegerMantissaAndExponent<u64, i64>
139 + Into<f64>
140 + IsInteger
141 + IsPowerOf2
142 + Ln
143 + LowerExp
144 + Min
145 + Max
146 + Mul<Output = Self>
147 + MulAssign<Self>
148 + Named
149 + NaN
150 + NegativeInfinity
151 + NegativeZero
152 + Neg<Output = Self>
153 + NegAssign
154 + NegativeOne
155 + NextPowerOf2<Output = Self>
156 + NextPowerOf2Assign
157 + One
158 + PartialEq<Self>
159 + PartialOrd<Self>
160 + PartialOrdAbs<Self>
161 + Pow<i64, Output = Self>
162 + Pow<Self, Output = Self>
163 + PowAssign<i64>
164 + PowAssign<Self>
165 + PowerOf2<i64>
166 + PrimeConstant
167 + Product
168 + RawMantissaAndExponent<u64, u64>
169 + Reciprocal<Output = Self>
170 + ReciprocalAssign
171 + RefUnwindSafe
172 + Rem<Output = Self>
173 + RemAssign<Self>
174 + RoundingFrom<u8>
175 + RoundingFrom<u16>
176 + RoundingFrom<u32>
177 + RoundingFrom<u64>
178 + RoundingFrom<u128>
179 + RoundingFrom<usize>
180 + RoundingFrom<i8>
181 + RoundingFrom<i16>
182 + RoundingFrom<i32>
183 + RoundingFrom<i64>
184 + RoundingFrom<i128>
185 + RoundingFrom<isize>
186 + RoundingInto<u8>
187 + RoundingInto<u16>
188 + RoundingInto<u32>
189 + RoundingInto<u64>
190 + RoundingInto<u128>
191 + RoundingInto<usize>
192 + RoundingInto<i8>
193 + RoundingInto<i16>
194 + RoundingInto<i32>
195 + RoundingInto<i64>
196 + RoundingInto<i128>
197 + RoundingInto<isize>
198 + SciMantissaAndExponent<Self, i64>
199 + Sign
200 + Sized
201 + Sqrt<Output = Self>
202 + SqrtAssign
203 + Square<Output = Self>
204 + SquareAssign
205 + Sub<Output = Self>
206 + SubAssign<Self>
207 + SubMul<Output = Self>
208 + SubMulAssign<Self, Self>
209 + Sum<Self>
210 + ThueMorseConstant
211 + Two
212 + UpperExp
213 + Zero
214{
215 /// The number of bits taken up by the type.
216 ///
217 /// This is $M+E+1$. The three terms in the sum correspond to the width of the mantissa, the
218 /// width of the exponent, and the sign bit.
219 /// - For [`f32`]s, this is 32.
220 /// - For [`f64`]s, this is 64.
221 const WIDTH: u64;
222 /// The number of bits taken up by the exponent.
223 /// - For [`f32`]s, this is 8.
224 /// - For [`f64`]s, this is 11.
225 const EXPONENT_WIDTH: u64 = Self::WIDTH - Self::MANTISSA_WIDTH - 1;
226 /// The number of bits taken up by the mantissa.
227 /// - For [`f32`]s, this is 23.
228 /// - For [`f64`]s, this is 52.
229 const MANTISSA_WIDTH: u64;
230 /// The smallest possible exponent of a float in the normal range. Any floats with smaller
231 /// exponents are subnormal and thus have reduced precision. This is $2-2^{E-1}$.
232 /// - For [`f32`]s, this is -126.
233 /// - For [`f64`]s, this is -1022.
234 const MIN_NORMAL_EXPONENT: i64 = -(1 << (Self::EXPONENT_WIDTH - 1)) + 2;
235 /// The smallest possible exponent of a float. This is $2-2^{E-1}-M$.
236 /// - For [`f32`]s, this is -149.
237 /// - For [`f64`]s, this is -1074.
238 const MIN_EXPONENT: i64 = Self::MIN_NORMAL_EXPONENT - (Self::MANTISSA_WIDTH as i64);
239 /// The largest possible exponent of a float. This is $2^{E-1}-1$.
240 /// - For [`f32`]s, this is 127.
241 /// - For [`f64`]s, this is 1023.
242 const MAX_EXPONENT: i64 = (1 << (Self::EXPONENT_WIDTH - 1)) - 1;
243 /// The smallest positive float. This is $2^{2-2^{E-1}-M}$.
244 /// - For [`f32`]s, this is $2^{-149}$, or `1.0e-45`.
245 /// - For [`f64`]s, this is $2^{-1074}$, or `5.0e-324`.
246 const MIN_POSITIVE_SUBNORMAL: Self;
247 /// The largest float in the subnormal range. This is $2^{2-2^{E-1}-M}(2^M-1)$.
248 /// - For [`f32`]s, this is $2^{-149}(2^{23}-1)$, or `1.1754942e-38`.
249 /// - For [`f64`]s, this is $2^{-1074}(2^{52}-1)$, or `2.225073858507201e-308`.
250 const MAX_SUBNORMAL: Self;
251 /// The smallest positive normal float. This is $2^{2-2^{E-1}}$.
252 /// - For [`f32`]s, this is $2^{-126}$, or `1.1754944e-38`.
253 /// - For [`f64`]s, this is $2^{-1022}$, or `2.2250738585072014e-308`.
254 const MIN_POSITIVE_NORMAL: Self;
255 /// The largest finite float. This is $2^{2^{E-1}-1}(2-2^{-M})$.
256 /// - For [`f32`]s, this is $2^{127}(2-2^{-23})$, or `3.4028235e38`.
257 /// - For [`f64`]s, this is $2^{1023}(2-2^{-52})$, or `1.7976931348623157e308`.
258 const MAX_FINITE: Self;
259 /// The smallest positive integer that cannot be represented as a float. This is $2^{M+1}+1$.
260 /// - For [`f32`]s, this is $2^{24}+1$, or 16777217.
261 /// - For [`f64`]s, this is $2^{53}+1$, or 9007199254740993.
262 const SMALLEST_UNREPRESENTABLE_UINT: u64;
263 /// If you list all floats in increasing order, excluding NaN and giving negative and positive
264 /// zero separate adjacent spots, this will be index of the last element, positive infinity. It
265 /// is $2^{M+1}(2^E-1)+1$.
266 /// - For [`f32`]s, this is $2^{32}-2^{24}+1$, or 4278190081.
267 /// - For [`f64`]s, this is $2^{64}-2^{53}+1$, or 18437736874454810625.
268 const LARGEST_ORDERED_REPRESENTATION: u64;
269
270 fn is_nan(self) -> bool;
271
272 fn is_infinite(self) -> bool;
273
274 fn is_finite(self) -> bool;
275
276 fn is_normal(self) -> bool;
277
278 fn is_sign_positive(self) -> bool;
279
280 fn is_sign_negative(self) -> bool;
281
282 fn classify(self) -> FpCategory;
283
284 fn to_bits(self) -> u64;
285
286 fn from_bits(v: u64) -> Self;
287
288 /// Tests whether `self` is negative zero.
289 ///
290 /// # Worst-case complexity
291 /// Constant time and additional memory.
292 ///
293 /// # Examples
294 /// ```
295 /// use malachite_base::num::basic::floats::PrimitiveFloat;
296 ///
297 /// assert!((-0.0).is_negative_zero());
298 /// assert!(!0.0.is_negative_zero());
299 /// assert!(!1.0.is_negative_zero());
300 /// assert!(!f32::NAN.is_negative_zero());
301 /// assert!(!f32::INFINITY.is_negative_zero());
302 /// ```
303 #[inline]
304 fn is_negative_zero(self) -> bool {
305 self.sign() == Less && self == Self::ZERO
306 }
307
308 /// If `self` is negative zero, returns positive zero; otherwise, returns `self`.
309 ///
310 /// # Worst-case complexity
311 /// Constant time and additional memory.
312 ///
313 /// # Examples
314 /// ```
315 /// use malachite_base::num::basic::floats::PrimitiveFloat;
316 /// use malachite_base::num::float::NiceFloat;
317 ///
318 /// assert_eq!(NiceFloat((-0.0).abs_negative_zero()), NiceFloat(0.0));
319 /// assert_eq!(NiceFloat(0.0.abs_negative_zero()), NiceFloat(0.0));
320 /// assert_eq!(NiceFloat(1.0.abs_negative_zero()), NiceFloat(1.0));
321 /// assert_eq!(NiceFloat((-1.0).abs_negative_zero()), NiceFloat(-1.0));
322 /// assert_eq!(NiceFloat(f32::NAN.abs_negative_zero()), NiceFloat(f32::NAN));
323 /// ```
324 #[inline]
325 fn abs_negative_zero(self) -> Self {
326 if self == Self::ZERO {
327 Self::ZERO
328 } else {
329 self
330 }
331 }
332
333 /// If `self` is negative zero, replaces it with positive zero; otherwise, leaves `self`
334 /// unchanged.
335 ///
336 /// # Worst-case complexity
337 /// Constant time and additional memory.
338 ///
339 /// # Examples
340 /// ```
341 /// use malachite_base::num::basic::floats::PrimitiveFloat;
342 /// use malachite_base::num::float::NiceFloat;
343 ///
344 /// let mut f = -0.0;
345 /// f.abs_negative_zero_assign();
346 /// assert_eq!(NiceFloat(f), NiceFloat(0.0));
347 ///
348 /// let mut f = 0.0;
349 /// f.abs_negative_zero_assign();
350 /// assert_eq!(NiceFloat(f), NiceFloat(0.0));
351 ///
352 /// let mut f = 1.0;
353 /// f.abs_negative_zero_assign();
354 /// assert_eq!(NiceFloat(f), NiceFloat(1.0));
355 ///
356 /// let mut f = -1.0;
357 /// f.abs_negative_zero_assign();
358 /// assert_eq!(NiceFloat(f), NiceFloat(-1.0));
359 ///
360 /// let mut f = f32::NAN;
361 /// f.abs_negative_zero_assign();
362 /// assert_eq!(NiceFloat(f), NiceFloat(f32::NAN));
363 /// ```
364 #[inline]
365 fn abs_negative_zero_assign(&mut self) {
366 if *self == Self::ZERO {
367 *self = Self::ZERO;
368 }
369 }
370
371 /// Returns the smallest float larger than `self`.
372 ///
373 /// Passing `-0.0` returns `0.0`; passing `NaN` or positive infinity panics.
374 ///
375 /// # Worst-case complexity
376 /// Constant time and additional memory.
377 ///
378 /// # Panics
379 /// Panics if `self` is `NaN` or positive infinity.
380 ///
381 /// # Examples
382 /// ```
383 /// use malachite_base::num::basic::floats::PrimitiveFloat;
384 /// use malachite_base::num::float::NiceFloat;
385 ///
386 /// assert_eq!(NiceFloat((-0.0f32).next_higher()), NiceFloat(0.0));
387 /// assert_eq!(NiceFloat(0.0f32.next_higher()), NiceFloat(1.0e-45));
388 /// assert_eq!(NiceFloat(1.0f32.next_higher()), NiceFloat(1.0000001));
389 /// assert_eq!(NiceFloat((-1.0f32).next_higher()), NiceFloat(-0.99999994));
390 /// ```
391 fn next_higher(self) -> Self {
392 assert!(!self.is_nan());
393 if self.sign() == Greater {
394 assert_ne!(self, Self::INFINITY);
395 Self::from_bits(self.to_bits() + 1)
396 } else if self == Self::ZERO {
397 // negative zero -> positive zero
398 Self::ZERO
399 } else {
400 Self::from_bits(self.to_bits() - 1)
401 }
402 }
403
404 /// Returns the largest float smaller than `self`.
405 ///
406 /// Passing `0.0` returns `-0.0`; passing `NaN` or negative infinity panics.
407 ///
408 /// # Worst-case complexity
409 /// Constant time and additional memory.
410 ///
411 /// # Panics
412 /// Panics if `self` is `NaN` or negative infinity.
413 ///
414 /// # Examples
415 /// ```
416 /// use malachite_base::num::basic::floats::PrimitiveFloat;
417 /// use malachite_base::num::float::NiceFloat;
418 ///
419 /// assert_eq!(NiceFloat(0.0f32.next_lower()), NiceFloat(-0.0));
420 /// assert_eq!(NiceFloat((-0.0f32).next_lower()), NiceFloat(-1.0e-45));
421 /// assert_eq!(NiceFloat(1.0f32.next_lower()), NiceFloat(0.99999994));
422 /// assert_eq!(NiceFloat((-1.0f32).next_lower()), NiceFloat(-1.0000001));
423 /// ```
424 fn next_lower(self) -> Self {
425 assert!(!self.is_nan());
426 if self.sign() == Less {
427 assert_ne!(self, Self::NEGATIVE_INFINITY);
428 Self::from_bits(self.to_bits() + 1)
429 } else if self == Self::ZERO {
430 // positive zero -> negative zero
431 Self::NEGATIVE_ZERO
432 } else {
433 Self::from_bits(self.to_bits() - 1)
434 }
435 }
436
437 /// Maps `self` to an integer. The map preserves ordering, and adjacent floats are mapped to
438 /// adjacent integers.
439 ///
440 /// Negative infinity is mapped to 0, and positive infinity is mapped to the largest value,
441 /// [`LARGEST_ORDERED_REPRESENTATION`](PrimitiveFloat::LARGEST_ORDERED_REPRESENTATION). Negative
442 /// and positive zero are mapped to distinct adjacent values. Passing in `NaN` panics.
443 ///
444 /// The inverse operation is
445 /// [`from_ordered_representation`](PrimitiveFloat::from_ordered_representation).
446 ///
447 /// # Worst-case complexity
448 /// Constant time and additional memory.
449 ///
450 /// # Panics
451 /// Panics if `self` is `NaN`.
452 ///
453 /// # Examples
454 /// ```
455 /// use malachite_base::num::basic::floats::PrimitiveFloat;
456 /// use malachite_base::num::basic::traits::NegativeInfinity;
457 ///
458 /// assert_eq!(f32::NEGATIVE_INFINITY.to_ordered_representation(), 0);
459 /// assert_eq!((-0.0f32).to_ordered_representation(), 2139095040);
460 /// assert_eq!(0.0f32.to_ordered_representation(), 2139095041);
461 /// assert_eq!(1.0f32.to_ordered_representation(), 3204448257);
462 /// assert_eq!(f32::INFINITY.to_ordered_representation(), 4278190081);
463 /// ```
464 fn to_ordered_representation(self) -> u64 {
465 assert!(!self.is_nan());
466 let bits = self.to_bits();
467 if self.sign() == Greater {
468 (u64::low_mask(Self::EXPONENT_WIDTH) << Self::MANTISSA_WIDTH) + bits + 1
469 } else {
470 (u64::low_mask(Self::EXPONENT_WIDTH + 1) << Self::MANTISSA_WIDTH) - bits
471 }
472 }
473
474 /// Maps a non-negative integer, less than or equal to
475 /// [`LARGEST_ORDERED_REPRESENTATION`](PrimitiveFloat::LARGEST_ORDERED_REPRESENTATION), to a
476 /// float. The map preserves ordering, and adjacent integers are mapped to adjacent floats.
477 ///
478 /// Zero is mapped to negative infinity, and
479 /// [`LARGEST_ORDERED_REPRESENTATION`](PrimitiveFloat::LARGEST_ORDERED_REPRESENTATION) is mapped
480 /// to positive infinity. Negative and positive zero are produced by two distinct adjacent
481 /// integers. `NaN` is never produced.
482 ///
483 /// The inverse operation is
484 /// [`to_ordered_representation`](PrimitiveFloat::to_ordered_representation).
485 ///
486 /// # Worst-case complexity
487 /// Constant time and additional memory.
488 ///
489 /// # Panics
490 /// Panics if `self` is greater than
491 /// [`LARGEST_ORDERED_REPRESENTATION`](PrimitiveFloat::LARGEST_ORDERED_REPRESENTATION).
492 ///
493 /// # Examples
494 /// ```
495 /// use malachite_base::num::basic::floats::PrimitiveFloat;
496 /// use malachite_base::num::basic::traits::NegativeInfinity;
497 ///
498 /// assert_eq!(f32::from_ordered_representation(0), f32::NEGATIVE_INFINITY);
499 /// assert_eq!(f32::from_ordered_representation(2139095040), -0.0f32);
500 /// assert_eq!(f32::from_ordered_representation(2139095041), 0.0f32);
501 /// assert_eq!(f32::from_ordered_representation(3204448257), 1.0f32);
502 /// assert_eq!(f32::from_ordered_representation(4278190081), f32::INFINITY);
503 /// ```
504 fn from_ordered_representation(n: u64) -> Self {
505 let zero_exp = u64::low_mask(Self::EXPONENT_WIDTH) << Self::MANTISSA_WIDTH;
506 let f = if n <= zero_exp {
507 Self::from_bits((u64::low_mask(Self::EXPONENT_WIDTH + 1) << Self::MANTISSA_WIDTH) - n)
508 } else {
509 let f = Self::from_bits(n - zero_exp - 1);
510 assert_eq!(f.sign(), Greater);
511 f
512 };
513 assert!(!f.is_nan());
514 f
515 }
516
517 /// Returns the precision of a nonzero finite floating-point number.
518 ///
519 /// The precision is the number of significant bits of the integer mantissa. For example, the
520 /// floats with precision 1 are the powers of 2, those with precision 2 are 3 times a power of
521 /// 2, those with precision 3 are 5 or 7 times a power of 2, and so on.
522 ///
523 /// # Worst-case complexity
524 /// Constant time and additional memory.
525 ///
526 /// # Panics
527 /// Panics if `self` is zero, infinite, or `NaN`.
528 ///
529 /// # Examples
530 /// ```
531 /// use malachite_base::num::basic::floats::PrimitiveFloat;
532 ///
533 /// assert_eq!(1.0.precision(), 1);
534 /// assert_eq!(2.0.precision(), 1);
535 /// assert_eq!(3.0.precision(), 2);
536 /// assert_eq!(1.5.precision(), 2);
537 /// assert_eq!(1.234f32.precision(), 23);
538 /// ```
539 fn precision(self) -> u64 {
540 assert!(self.is_finite());
541 assert!(self != Self::ZERO);
542 let (mut mantissa, exponent) = self.raw_mantissa_and_exponent();
543 if exponent == 0 {
544 mantissa.significant_bits() - TrailingZeros::trailing_zeros(mantissa)
545 } else {
546 mantissa.set_bit(Self::MANTISSA_WIDTH);
547 Self::MANTISSA_WIDTH + 1 - TrailingZeros::trailing_zeros(mantissa)
548 }
549 }
550
551 /// Given a scientific exponent, returns the largest possible precision for a float with that
552 /// exponent.
553 ///
554 /// See the documentation of the [`precision`](PrimitiveFloat::precision) function for a
555 /// definition of precision.
556 ///
557 /// For exponents greater than or equal to
558 /// [`MIN_NORMAL_EXPONENT`](PrimitiveFloat::MIN_NORMAL_EXPONENT), the maximum precision is one
559 /// more than the mantissa width. For smaller exponents (corresponding to the subnormal range),
560 /// the precision is lower.
561 ///
562 /// # Worst-case complexity
563 /// Constant time and additional memory.
564 ///
565 /// # Panics
566 /// Panics if `exponent` is less than [`MIN_EXPONENT`](PrimitiveFloat::MIN_EXPONENT) or greater
567 /// than [`MAX_EXPONENT`](PrimitiveFloat::MAX_EXPONENT).
568 ///
569 /// # Examples
570 /// ```
571 /// use malachite_base::num::basic::floats::PrimitiveFloat;
572 ///
573 /// assert_eq!(f32::max_precision_for_sci_exponent(0), 24);
574 /// assert_eq!(f32::max_precision_for_sci_exponent(127), 24);
575 /// assert_eq!(f32::max_precision_for_sci_exponent(-149), 1);
576 /// assert_eq!(f32::max_precision_for_sci_exponent(-148), 2);
577 /// assert_eq!(f32::max_precision_for_sci_exponent(-147), 3);
578 /// ```
579 fn max_precision_for_sci_exponent(exponent: i64) -> u64 {
580 assert!(exponent >= Self::MIN_EXPONENT);
581 assert!(exponent <= Self::MAX_EXPONENT);
582 if exponent >= Self::MIN_NORMAL_EXPONENT {
583 Self::MANTISSA_WIDTH + 1
584 } else {
585 u64::wrapping_from(exponent - Self::MIN_EXPONENT) + 1
586 }
587 }
588}
589
590/// Defines basic trait implementations for floating-point types.
591macro_rules! impl_basic_traits_primitive_float {
592 (
593 $t: ident,
594 $width: expr,
595 $min_positive_subnormal: expr,
596 $max_subnormal: expr,
597 $min_positive_normal: expr,
598 $thue_morse_constant: expr,
599 $prime_constant: expr
600 ) => {
601 impl PrimitiveFloat for $t {
602 const WIDTH: u64 = $width;
603 const MANTISSA_WIDTH: u64 = ($t::MANTISSA_DIGITS as u64) - 1;
604
605 const MAX_FINITE: Self = $t::MAX;
606 const MIN_POSITIVE_SUBNORMAL: Self = $min_positive_subnormal;
607 const MAX_SUBNORMAL: Self = $max_subnormal;
608 const MIN_POSITIVE_NORMAL: Self = $min_positive_normal;
609 const SMALLEST_UNREPRESENTABLE_UINT: u64 = (1 << (Self::MANTISSA_WIDTH + 1)) + 1;
610 // We can't shift by $width when $width is 64, so we shift by $width - 1 and then by 1
611 const LARGEST_ORDERED_REPRESENTATION: u64 = (1u64 << ($width - 1) << 1)
612 .wrapping_sub(((1 << Self::MANTISSA_WIDTH) - 1) << 1)
613 - 1;
614
615 #[inline]
616 fn is_nan(self) -> bool {
617 $t::is_nan(self)
618 }
619
620 #[inline]
621 fn is_infinite(self) -> bool {
622 $t::is_infinite(self)
623 }
624
625 #[inline]
626 fn is_finite(self) -> bool {
627 $t::is_finite(self)
628 }
629
630 #[inline]
631 fn is_normal(self) -> bool {
632 $t::is_normal(self)
633 }
634
635 #[inline]
636 fn is_sign_positive(self) -> bool {
637 $t::is_sign_positive(self)
638 }
639
640 #[inline]
641 fn is_sign_negative(self) -> bool {
642 $t::is_sign_negative(self)
643 }
644
645 #[inline]
646 fn classify(self) -> FpCategory {
647 $t::classify(self)
648 }
649
650 #[inline]
651 fn to_bits(self) -> u64 {
652 u64::wrapping_from($t::to_bits(self))
653 }
654
655 #[inline]
656 fn from_bits(v: u64) -> $t {
657 $t::from_bits(v.exact_into())
658 }
659 }
660
661 impl_named!($t);
662
663 /// The constant 0.
664 impl Zero for $t {
665 const ZERO: $t = 0.0;
666 }
667
668 /// The constant 1.
669 impl One for $t {
670 const ONE: $t = 1.0;
671 }
672
673 /// The constant 2.
674 impl Two for $t {
675 const TWO: $t = 2.0;
676 }
677
678 /// The constant 1/2.
679 impl OneHalf for $t {
680 const ONE_HALF: $t = 0.5;
681 }
682
683 /// The constant -1.0 for primitive floating-point types.
684 impl NegativeOne for $t {
685 const NEGATIVE_ONE: $t = -1.0;
686 }
687
688 /// The constant -0.0 for primitive floating-point types.
689 impl NegativeZero for $t {
690 const NEGATIVE_ZERO: $t = -0.0;
691 }
692
693 /// The constant Infinity for primitive floating-point types.
694 impl Infinity for $t {
695 const INFINITY: $t = $t::INFINITY;
696 }
697
698 /// The constant -Infinity for primitive floating-point types.
699 impl NegativeInfinity for $t {
700 const NEGATIVE_INFINITY: $t = $t::NEG_INFINITY;
701 }
702
703 /// The constant NaN for primitive floating-point types.
704 impl NaN for $t {
705 const NAN: $t = $t::NAN;
706 }
707
708 /// The lowest value representable by this type, negative infinity.
709 impl Min for $t {
710 const MIN: $t = $t::NEGATIVE_INFINITY;
711 }
712
713 /// The highest value representable by this type, positive infinity.
714 impl Max for $t {
715 const MAX: $t = $t::INFINITY;
716 }
717
718 /// The Thue-Morse constant.
719 impl ThueMorseConstant for $t {
720 const THUE_MORSE_CONSTANT: $t = $thue_morse_constant;
721 }
722
723 /// The prime constant.
724 impl PrimeConstant for $t {
725 const PRIME_CONSTANT: $t = $prime_constant;
726 }
727 };
728}
729impl_basic_traits_primitive_float!(
730 f32,
731 32,
732 1.0e-45,
733 1.1754942e-38,
734 1.1754944e-38,
735 0.41245404,
736 0.4146825
737);
738impl_basic_traits_primitive_float!(
739 f64,
740 64,
741 5.0e-324,
742 2.225073858507201e-308,
743 2.2250738585072014e-308,
744 0.4124540336401076,
745 0.41468250985111166
746);