malachite_float/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!(
240 /// Float::min_positive_value_prec(1).to_string(),
241 /// "2.4e-323228497"
242 /// );
243 /// assert_eq!(
244 /// Float::min_positive_value_prec(10).to_string(),
245 /// "2.3826e-323228497"
246 /// );
247 /// assert_eq!(
248 /// Float::min_positive_value_prec(100).to_string(),
249 /// "2.3825649048879510732161697817327e-323228497"
250 /// );
251 ///
252 /// assert_eq!(Float::min_positive_value_prec(1).get_prec(), Some(1));
253 /// assert_eq!(Float::min_positive_value_prec(10).get_prec(), Some(10));
254 /// assert_eq!(Float::min_positive_value_prec(100).get_prec(), Some(100));
255 /// ```
256 pub fn min_positive_value_prec(prec: u64) -> Self {
257 assert_ne!(prec, 0);
258 Self(Finite {
259 sign: true,
260 exponent: Self::MIN_EXPONENT,
261 precision: prec,
262 significand: Natural::power_of_2(
263 prec.round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
264 .0
265 - 1,
266 ),
267 })
268 }
269
270 /// Returns whether the absolute value of a `Float` is equal to the minimum representable
271 /// positive value, or $2^{-2^{30}}$.
272 ///
273 /// $$
274 /// f(x) = (|x|=2^{-2^{30}}).
275 /// $$
276 ///
277 /// # Worst-case complexity
278 /// $T(n) = O(n)$
279 ///
280 /// $M(n) = O(1)$
281 ///
282 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
283 ///
284 /// # Examples
285 /// ```
286 /// use malachite_float::Float;
287 ///
288 /// assert!(Float::min_positive_value_prec(100).abs_is_min_positive_value());
289 /// assert!((-Float::min_positive_value_prec(100)).abs_is_min_positive_value());
290 /// assert!(!(Float::min_positive_value_prec(100) << 1u32).abs_is_min_positive_value());
291 /// ```
292 pub fn abs_is_min_positive_value(&self) -> bool {
293 self.get_exponent() == Some(Self::MIN_EXPONENT)
294 && self.significand_ref().unwrap().is_power_of_2()
295 }
296
297 /// There is no maximum finite [`Float`], but there is one for any given precision. This
298 /// function returns that [`Float`].
299 ///
300 /// $$
301 /// f(p) = (1-(1/2)^p)2^{2^{30}-1},
302 /// $$
303 /// where $p$ is `prec`. The output has precision `prec`.
304 ///
305 /// # Worst-case complexity
306 /// $T(n) = O(n)$
307 ///
308 /// $M(n) = O(n)$
309 ///
310 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
311 ///
312 /// # Panics
313 /// Panics if `prec` is zero.
314 ///
315 /// # Examples
316 /// ```
317 /// use malachite_float::Float;
318 ///
319 /// assert_eq!(
320 /// Float::max_finite_value_with_prec(1).to_string(),
321 /// "1.0e323228496"
322 /// );
323 /// assert_eq!(
324 /// Float::max_finite_value_with_prec(10).to_string(),
325 /// "2.0965e323228496"
326 /// );
327 /// assert_eq!(
328 /// Float::max_finite_value_with_prec(100).to_string(),
329 /// "2.0985787164673876924043581168822e323228496"
330 /// );
331 ///
332 /// assert_eq!(Float::max_finite_value_with_prec(1).get_prec(), Some(1));
333 /// assert_eq!(Float::max_finite_value_with_prec(10).get_prec(), Some(10));
334 /// assert_eq!(Float::max_finite_value_with_prec(100).get_prec(), Some(100));
335 /// ```
336 pub fn max_finite_value_with_prec(prec: u64) -> Self {
337 assert_ne!(prec, 0);
338 Self(Finite {
339 sign: true,
340 exponent: Self::MAX_EXPONENT,
341 precision: prec,
342 significand: Natural::low_mask(prec) << prec.neg_mod_power_of_2(Limb::LOG_WIDTH),
343 })
344 }
345
346 /// Returns whether the absolute value of a `Float` is equal to the maximum representable finite
347 /// value with that precision.
348 ///
349 /// $$
350 /// f(x) = (|x|=(1-(1/2)^p)2^{2^{30}-1}),
351 /// $$
352 /// where $p$ is the precision of the $x$.
353 ///
354 /// # Worst-case complexity
355 /// $T(n) = O(n)$
356 ///
357 /// $M(n) = O(1)$
358 ///
359 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
360 ///
361 /// # Examples
362 /// ```
363 /// use malachite_float::Float;
364 ///
365 /// assert!(Float::max_finite_value_with_prec(100).abs_is_max_finite_value_with_prec());
366 /// assert!((-Float::max_finite_value_with_prec(100)).abs_is_max_finite_value_with_prec());
367 /// assert!(
368 /// !(Float::max_finite_value_with_prec(100) >> 1u32).abs_is_max_finite_value_with_prec()
369 /// );
370 /// ```
371 pub fn abs_is_max_finite_value_with_prec(&self) -> bool {
372 if self.get_exponent() != Some(Self::MAX_EXPONENT) {
373 return false;
374 }
375 let prec = self.get_prec().unwrap();
376 let lowest_1_index = prec.neg_mod_power_of_2(Limb::LOG_WIDTH);
377 self.significand_ref()
378 .unwrap()
379 .index_of_next_false_bit(lowest_1_index)
380 .unwrap()
381 == prec
382 .round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
383 .0
384 }
385
386 /// Returns the number 1, with the given precision.
387 ///
388 /// $$
389 /// f(p) = 1,
390 /// $$
391 ///
392 /// and the output has precision $p$.
393 ///
394 /// # Worst-case complexity
395 /// $T(n) = O(n)$
396 ///
397 /// $M(n) = O(n)$
398 ///
399 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
400 ///
401 /// # Panics
402 /// Panics if `prec` is zero.
403 ///
404 /// # Examples
405 /// ```
406 /// use malachite_float::Float;
407 ///
408 /// assert_eq!(Float::one_prec(1), 1);
409 /// assert_eq!(Float::one_prec(10), 1);
410 /// assert_eq!(Float::one_prec(100), 1);
411 ///
412 /// assert_eq!(Float::one_prec(1).get_prec(), Some(1));
413 /// assert_eq!(Float::one_prec(10).get_prec(), Some(10));
414 /// assert_eq!(Float::one_prec(100).get_prec(), Some(100));
415 /// ```
416 pub fn one_prec(prec: u64) -> Self {
417 assert_ne!(prec, 0);
418 Self(Finite {
419 sign: true,
420 exponent: 1,
421 precision: prec,
422 significand: Natural::power_of_2(
423 prec.round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
424 .0
425 - 1,
426 ),
427 })
428 }
429
430 /// Returns the number 2, with the given precision.
431 ///
432 /// $$
433 /// f(p) = 2,
434 /// $$
435 ///
436 /// and the output has precision $p$.
437 ///
438 /// # Worst-case complexity
439 /// $T(n) = O(n)$
440 ///
441 /// $M(n) = O(n)$
442 ///
443 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
444 ///
445 /// # Panics
446 /// Panics if `prec` is zero.
447 ///
448 /// # Examples
449 /// ```
450 /// use malachite_float::Float;
451 ///
452 /// assert_eq!(Float::two_prec(1), 2);
453 /// assert_eq!(Float::two_prec(10), 2);
454 /// assert_eq!(Float::two_prec(100), 2);
455 ///
456 /// assert_eq!(Float::two_prec(1).get_prec(), Some(1));
457 /// assert_eq!(Float::two_prec(10).get_prec(), Some(10));
458 /// assert_eq!(Float::two_prec(100).get_prec(), Some(100));
459 /// ```
460 pub fn two_prec(prec: u64) -> Self {
461 assert_ne!(prec, 0);
462 Self(Finite {
463 sign: true,
464 exponent: 2,
465 precision: prec,
466 significand: Natural::power_of_2(
467 prec.round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
468 .0
469 - 1,
470 ),
471 })
472 }
473
474 /// Returns the number $-1$, with the given precision.
475 ///
476 /// $$
477 /// f(p) = -1,
478 /// $$
479 ///
480 /// and the output has precision $p$.
481 ///
482 /// # Worst-case complexity
483 /// $T(n) = O(n)$
484 ///
485 /// $M(n) = O(n)$
486 ///
487 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
488 ///
489 /// # Panics
490 /// Panics if `prec` is zero.
491 ///
492 /// # Examples
493 /// ```
494 /// use malachite_float::Float;
495 ///
496 /// assert_eq!(Float::negative_one_prec(1), -1);
497 /// assert_eq!(Float::negative_one_prec(10), -1);
498 /// assert_eq!(Float::negative_one_prec(100), -1);
499 ///
500 /// assert_eq!(Float::negative_one_prec(1).get_prec(), Some(1));
501 /// assert_eq!(Float::negative_one_prec(10).get_prec(), Some(10));
502 /// assert_eq!(Float::negative_one_prec(100).get_prec(), Some(100));
503 /// ```
504 pub fn negative_one_prec(prec: u64) -> Self {
505 assert_ne!(prec, 0);
506 Self(Finite {
507 sign: false,
508 exponent: 1,
509 precision: prec,
510 significand: Natural::power_of_2(
511 prec.round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
512 .0
513 - 1,
514 ),
515 })
516 }
517
518 /// Returns the number 0.5, with the given precision.
519 ///
520 /// $$
521 /// f(p) = 0.5,
522 /// $$
523 ///
524 /// and the output has precision $p$.
525 ///
526 /// # Worst-case complexity
527 /// $T(n) = O(n)$
528 ///
529 /// $M(n) = O(n)$
530 ///
531 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
532 ///
533 /// # Panics
534 /// Panics if `prec` is zero.
535 ///
536 /// # Examples
537 /// ```
538 /// use malachite_float::Float;
539 ///
540 /// assert_eq!(Float::one_half_prec(1), 0.5);
541 /// assert_eq!(Float::one_half_prec(10), 0.5);
542 /// assert_eq!(Float::one_half_prec(100), 0.5);
543 ///
544 /// assert_eq!(Float::one_half_prec(1).get_prec(), Some(1));
545 /// assert_eq!(Float::one_half_prec(10).get_prec(), Some(10));
546 /// assert_eq!(Float::one_half_prec(100).get_prec(), Some(100));
547 /// ```
548 pub fn one_half_prec(prec: u64) -> Self {
549 assert_ne!(prec, 0);
550 Self(Finite {
551 sign: true,
552 exponent: 0,
553 precision: prec,
554 significand: Natural::power_of_2(
555 prec.round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
556 .0
557 - 1,
558 ),
559 })
560 }
561}