malachite_float/basic/constants.rs
1// Copyright © 2026 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::Float;
10use crate::InnerFloat::{Finite, Infinity, NaN, Zero};
11use malachite_base::comparison::traits::{Max, Min};
12use malachite_base::named::Named;
13use malachite_base::num::arithmetic::traits::{
14 IsPowerOf2, NegModPowerOf2, PowerOf2, RoundToMultipleOfPowerOf2,
15};
16use malachite_base::num::basic::integers::PrimitiveInt;
17use malachite_base::num::basic::traits::{
18 Infinity as InfinityTrait, NaN as NaNTrait, NegativeInfinity, NegativeOne, NegativeZero, One,
19 OneHalf, Two, Zero as ZeroTrait,
20};
21use malachite_base::num::logic::traits::{BitScan, LowMask};
22use malachite_base::rounding_modes::RoundingMode::*;
23use malachite_nz::natural::Natural;
24use malachite_nz::platform::Limb;
25
26#[doc(hidden)]
27#[macro_export]
28macro_rules! float_zero {
29 () => {
30 Float(Zero { sign: true })
31 };
32}
33
34#[doc(hidden)]
35#[macro_export]
36macro_rules! float_one {
37 () => {
38 Float(Finite {
39 sign: true,
40 exponent: 1,
41 precision: 1,
42 significand: Natural::HIGH_BIT,
43 })
44 };
45}
46
47#[doc(hidden)]
48#[macro_export]
49macro_rules! float_two {
50 () => {
51 Float(Finite {
52 sign: true,
53 exponent: 2,
54 precision: 1,
55 significand: Natural::HIGH_BIT,
56 })
57 };
58}
59
60#[doc(hidden)]
61#[macro_export]
62macro_rules! float_negative_one {
63 () => {
64 Float(Finite {
65 sign: false,
66 exponent: 1,
67 precision: 1,
68 significand: Natural::HIGH_BIT,
69 })
70 };
71}
72
73#[doc(hidden)]
74#[macro_export]
75macro_rules! float_one_half {
76 () => {
77 Float(Finite {
78 sign: true,
79 exponent: 0,
80 precision: 1,
81 significand: Natural::HIGH_BIT,
82 })
83 };
84}
85
86#[doc(hidden)]
87#[macro_export]
88macro_rules! float_negative_zero {
89 () => {
90 Float(Zero { sign: false })
91 };
92}
93
94#[doc(hidden)]
95#[macro_export]
96macro_rules! float_infinity {
97 () => {
98 Float(Infinity { sign: true })
99 };
100}
101
102#[doc(hidden)]
103#[macro_export]
104macro_rules! float_negative_infinity {
105 () => {
106 Float(Infinity { sign: false })
107 };
108}
109
110#[doc(hidden)]
111#[macro_export]
112macro_rules! float_nan {
113 () => {
114 Float(NaN)
115 };
116}
117
118#[doc(hidden)]
119#[macro_export]
120macro_rules! float_finite {
121 () => {
122 Float(Finite { .. })
123 };
124}
125
126#[doc(hidden)]
127#[macro_export]
128macro_rules! float_either_infinity {
129 () => {
130 Float(Infinity { .. })
131 };
132}
133
134#[doc(hidden)]
135#[macro_export]
136macro_rules! float_either_zero {
137 () => {
138 Float(Zero { .. })
139 };
140}
141
142/// The constant 0.0 (positive zero), with precision 1.
143impl ZeroTrait for Float {
144 const ZERO: Self = float_zero!();
145}
146
147/// The constant 1.0, with precision 1.
148impl One for Float {
149 const ONE: Self = float_one!();
150}
151
152/// The constant 2.0, with precision 1.
153impl Two for Float {
154 const TWO: Self = float_two!();
155}
156
157/// The constant -1.0, with precision 1.
158impl NegativeOne for Float {
159 const NEGATIVE_ONE: Self = float_negative_one!();
160}
161
162/// The constant 0.5, with precision 1.
163impl OneHalf for Float {
164 const ONE_HALF: Self = float_one_half!();
165}
166
167/// The constant -0.0, with precision 1.
168impl NegativeZero for Float {
169 const NEGATIVE_ZERO: Self = float_negative_zero!();
170}
171
172/// The constant $\infty$.
173impl InfinityTrait for Float {
174 const INFINITY: Self = float_infinity!();
175}
176
177/// The constant $-\infty$.
178impl NegativeInfinity for Float {
179 const NEGATIVE_INFINITY: Self = float_negative_infinity!();
180}
181
182/// The constant NaN.
183impl NaNTrait for Float {
184 const NAN: Self = float_nan!();
185}
186
187impl Default for Float {
188 /// The default value of a [`Float`], NaN.
189 fn default() -> Self {
190 Self::NAN
191 }
192}
193
194/// The lowest value representable by this type, $-\infty$.
195impl Min for Float {
196 const MIN: Self = Self::NEGATIVE_INFINITY;
197}
198
199/// The highest value representable by this type, $\infty$.
200impl Max for Float {
201 const MAX: Self = Self::INFINITY;
202}
203
204// Implements `Named` for `Float`.
205impl_named!(Float);
206
207impl Float {
208 /// The minimum representable positive value, or $2^{-2^{30}}$, with precision 1.
209 pub const MIN_POSITIVE: Self = Self(Finite {
210 sign: true,
211 exponent: Self::MIN_EXPONENT,
212 precision: 1,
213 significand: Natural::HIGH_BIT,
214 });
215
216 /// Returns the minimum representable positive value, or $2^{-2^{30}}$, with the given
217 /// precision.
218 ///
219 /// $$
220 /// f(p) = 2^{-2^{30}},
221 /// $$
222 ///
223 /// and the output has precision `prec`.
224 ///
225 /// # Worst-case complexity
226 /// $T(n) = O(n)$
227 ///
228 /// $M(n) = O(n)$
229 ///
230 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
231 ///
232 /// # Panics
233 /// Panics if `prec` is zero.
234 ///
235 /// # Examples
236 /// ```
237 /// use malachite_float::Float;
238 ///
239 /// assert_eq!(Float::min_positive_value_prec(1).to_string(), "too_small");
240 /// assert_eq!(Float::min_positive_value_prec(10).to_string(), "too_small");
241 /// assert_eq!(Float::min_positive_value_prec(100).to_string(), "too_small");
242 ///
243 /// assert_eq!(Float::min_positive_value_prec(1).get_prec(), Some(1));
244 /// assert_eq!(Float::min_positive_value_prec(10).get_prec(), Some(10));
245 /// assert_eq!(Float::min_positive_value_prec(100).get_prec(), Some(100));
246 /// ```
247 pub fn min_positive_value_prec(prec: u64) -> Self {
248 assert_ne!(prec, 0);
249 Self(Finite {
250 sign: true,
251 exponent: Self::MIN_EXPONENT,
252 precision: prec,
253 significand: Natural::power_of_2(
254 prec.round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
255 .0
256 - 1,
257 ),
258 })
259 }
260
261 /// Returns whether the absolute value of a `Float` is equal to the minimum representable
262 /// positive value, or $2^{-2^{30}}$.
263 ///
264 /// $$
265 /// f(x) = (|x|=2^{-2^{30}}).
266 /// $$
267 ///
268 /// # Worst-case complexity
269 /// $T(n) = O(n)$
270 ///
271 /// $M(n) = O(1)$
272 ///
273 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
274 ///
275 /// # Examples
276 /// ```
277 /// use malachite_float::Float;
278 ///
279 /// assert!(Float::min_positive_value_prec(100).abs_is_min_positive_value());
280 /// assert!((-Float::min_positive_value_prec(100)).abs_is_min_positive_value());
281 /// assert!(!(Float::min_positive_value_prec(100) << 1u32).abs_is_min_positive_value());
282 /// ```
283 pub fn abs_is_min_positive_value(&self) -> bool {
284 self.get_exponent() == Some(Self::MIN_EXPONENT)
285 && self.significand_ref().unwrap().is_power_of_2()
286 }
287
288 /// There is no maximum finite [`Float`], but there is one for any given precision. This
289 /// function returns that [`Float`].
290 ///
291 /// $$
292 /// f(p) = (1-(1/2)^p)2^{2^{30}-1},
293 /// $$
294 /// where $p$ is `prec`. The output has precision `prec`.
295 ///
296 /// # Worst-case complexity
297 /// $T(n) = O(n)$
298 ///
299 /// $M(n) = O(n)$
300 ///
301 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
302 ///
303 /// # Panics
304 /// Panics if `prec` is zero.
305 ///
306 /// # Examples
307 /// ```
308 /// use malachite_float::Float;
309 ///
310 /// assert_eq!(Float::max_finite_value_with_prec(1).to_string(), "too_big");
311 /// assert_eq!(Float::max_finite_value_with_prec(10).to_string(), "too_big");
312 /// assert_eq!(
313 /// Float::max_finite_value_with_prec(100).to_string(),
314 /// "too_big"
315 /// );
316 ///
317 /// assert_eq!(Float::max_finite_value_with_prec(1).get_prec(), Some(1));
318 /// assert_eq!(Float::max_finite_value_with_prec(10).get_prec(), Some(10));
319 /// assert_eq!(Float::max_finite_value_with_prec(100).get_prec(), Some(100));
320 /// ```
321 pub fn max_finite_value_with_prec(prec: u64) -> Self {
322 assert_ne!(prec, 0);
323 Self(Finite {
324 sign: true,
325 exponent: Self::MAX_EXPONENT,
326 precision: prec,
327 significand: Natural::low_mask(prec) << prec.neg_mod_power_of_2(Limb::LOG_WIDTH),
328 })
329 }
330
331 /// Returns whether the absolute value of a `Float` is equal to the maximum representable finite
332 /// value with that precision.
333 ///
334 /// $$
335 /// f(x) = (|x|=(1-(1/2)^p)2^{2^{30}-1}),
336 /// $$
337 /// where $p$ is the precision of the $x$.
338 ///
339 /// # Worst-case complexity
340 /// $T(n) = O(n)$
341 ///
342 /// $M(n) = O(1)$
343 ///
344 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
345 ///
346 /// # Examples
347 /// ```
348 /// use malachite_float::Float;
349 ///
350 /// assert!(Float::max_finite_value_with_prec(100).abs_is_max_finite_value_with_prec());
351 /// assert!((-Float::max_finite_value_with_prec(100)).abs_is_max_finite_value_with_prec());
352 /// assert!(
353 /// !(Float::max_finite_value_with_prec(100) >> 1u32).abs_is_max_finite_value_with_prec()
354 /// );
355 /// ```
356 pub fn abs_is_max_finite_value_with_prec(&self) -> bool {
357 if self.get_exponent() != Some(Self::MAX_EXPONENT) {
358 return false;
359 }
360 let prec = self.get_prec().unwrap();
361 let lowest_1_index = prec.neg_mod_power_of_2(Limb::LOG_WIDTH);
362 self.significand_ref()
363 .unwrap()
364 .index_of_next_false_bit(lowest_1_index)
365 .unwrap()
366 == prec
367 .round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
368 .0
369 }
370
371 /// Returns the number 1, with the given precision.
372 ///
373 /// $$
374 /// f(p) = 1,
375 /// $$
376 ///
377 /// and the output has precision $p$.
378 ///
379 /// # Worst-case complexity
380 /// $T(n) = O(n)$
381 ///
382 /// $M(n) = O(n)$
383 ///
384 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
385 ///
386 /// # Panics
387 /// Panics if `prec` is zero.
388 ///
389 /// # Examples
390 /// ```
391 /// use malachite_float::Float;
392 ///
393 /// assert_eq!(Float::one_prec(1), 1);
394 /// assert_eq!(Float::one_prec(10), 1);
395 /// assert_eq!(Float::one_prec(100), 1);
396 ///
397 /// assert_eq!(Float::one_prec(1).get_prec(), Some(1));
398 /// assert_eq!(Float::one_prec(10).get_prec(), Some(10));
399 /// assert_eq!(Float::one_prec(100).get_prec(), Some(100));
400 /// ```
401 pub fn one_prec(prec: u64) -> Self {
402 assert_ne!(prec, 0);
403 Self(Finite {
404 sign: true,
405 exponent: 1,
406 precision: prec,
407 significand: Natural::power_of_2(
408 prec.round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
409 .0
410 - 1,
411 ),
412 })
413 }
414
415 /// Returns the number 2, with the given precision.
416 ///
417 /// $$
418 /// f(p) = 2,
419 /// $$
420 ///
421 /// and the output has precision $p$.
422 ///
423 /// # Worst-case complexity
424 /// $T(n) = O(n)$
425 ///
426 /// $M(n) = O(n)$
427 ///
428 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
429 ///
430 /// # Panics
431 /// Panics if `prec` is zero.
432 ///
433 /// # Examples
434 /// ```
435 /// use malachite_float::Float;
436 ///
437 /// assert_eq!(Float::two_prec(1), 2);
438 /// assert_eq!(Float::two_prec(10), 2);
439 /// assert_eq!(Float::two_prec(100), 2);
440 ///
441 /// assert_eq!(Float::two_prec(1).get_prec(), Some(1));
442 /// assert_eq!(Float::two_prec(10).get_prec(), Some(10));
443 /// assert_eq!(Float::two_prec(100).get_prec(), Some(100));
444 /// ```
445 pub fn two_prec(prec: u64) -> Self {
446 assert_ne!(prec, 0);
447 Self(Finite {
448 sign: true,
449 exponent: 2,
450 precision: prec,
451 significand: Natural::power_of_2(
452 prec.round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
453 .0
454 - 1,
455 ),
456 })
457 }
458
459 /// Returns the number $-1$, with the given precision.
460 ///
461 /// $$
462 /// f(p) = -1,
463 /// $$
464 ///
465 /// and the output has precision $p$.
466 ///
467 /// # Worst-case complexity
468 /// $T(n) = O(n)$
469 ///
470 /// $M(n) = O(n)$
471 ///
472 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
473 ///
474 /// # Panics
475 /// Panics if `prec` is zero.
476 ///
477 /// # Examples
478 /// ```
479 /// use malachite_float::Float;
480 ///
481 /// assert_eq!(Float::negative_one_prec(1), -1);
482 /// assert_eq!(Float::negative_one_prec(10), -1);
483 /// assert_eq!(Float::negative_one_prec(100), -1);
484 ///
485 /// assert_eq!(Float::negative_one_prec(1).get_prec(), Some(1));
486 /// assert_eq!(Float::negative_one_prec(10).get_prec(), Some(10));
487 /// assert_eq!(Float::negative_one_prec(100).get_prec(), Some(100));
488 /// ```
489 pub fn negative_one_prec(prec: u64) -> Self {
490 assert_ne!(prec, 0);
491 Self(Finite {
492 sign: false,
493 exponent: 1,
494 precision: prec,
495 significand: Natural::power_of_2(
496 prec.round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
497 .0
498 - 1,
499 ),
500 })
501 }
502
503 /// Returns the number 0.5, with the given precision.
504 ///
505 /// $$
506 /// f(p) = 0.5,
507 /// $$
508 ///
509 /// and the output has precision $p$.
510 ///
511 /// # Worst-case complexity
512 /// $T(n) = O(n)$
513 ///
514 /// $M(n) = O(n)$
515 ///
516 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
517 ///
518 /// # Panics
519 /// Panics if `prec` is zero.
520 ///
521 /// # Examples
522 /// ```
523 /// use malachite_float::Float;
524 ///
525 /// assert_eq!(Float::one_half_prec(1), 0.5);
526 /// assert_eq!(Float::one_half_prec(10), 0.5);
527 /// assert_eq!(Float::one_half_prec(100), 0.5);
528 ///
529 /// assert_eq!(Float::one_half_prec(1).get_prec(), Some(1));
530 /// assert_eq!(Float::one_half_prec(10).get_prec(), Some(10));
531 /// assert_eq!(Float::one_half_prec(100).get_prec(), Some(100));
532 /// ```
533 pub fn one_half_prec(prec: u64) -> Self {
534 assert_ne!(prec, 0);
535 Self(Finite {
536 sign: true,
537 exponent: 0,
538 precision: prec,
539 significand: Natural::power_of_2(
540 prec.round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
541 .0
542 - 1,
543 ),
544 })
545 }
546}