malachite_float/basic/constants.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::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 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::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 /// There is no maximum finite [`Float`], but there is one for any given precision. This
262 /// function returns that [`Float`].
263 ///
264 /// $$
265 /// f(p) = (1-(1/2)^p)2^{2^{30}-1},
266 /// $$
267 /// where $p$ is the `prec`. The output has precision `prec`.
268 ///
269 /// # Worst-case complexity
270 /// $T(n) = O(n)$
271 ///
272 /// $M(n) = O(n)$
273 ///
274 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
275 ///
276 /// # Panics
277 /// Panics if `prec` is zero.
278 ///
279 /// # Examples
280 /// ```
281 /// use malachite_float::Float;
282 ///
283 /// assert_eq!(Float::max_finite_value_with_prec(1).to_string(), "too_big");
284 /// assert_eq!(Float::max_finite_value_with_prec(10).to_string(), "too_big");
285 /// assert_eq!(
286 /// Float::max_finite_value_with_prec(100).to_string(),
287 /// "too_big"
288 /// );
289 ///
290 /// assert_eq!(Float::max_finite_value_with_prec(1).get_prec(), Some(1));
291 /// assert_eq!(Float::max_finite_value_with_prec(10).get_prec(), Some(10));
292 /// assert_eq!(Float::max_finite_value_with_prec(100).get_prec(), Some(100));
293 /// ```
294 pub fn max_finite_value_with_prec(prec: u64) -> Self {
295 assert_ne!(prec, 0);
296 Self(Finite {
297 sign: true,
298 exponent: Self::MAX_EXPONENT,
299 precision: prec,
300 significand: Natural::low_mask(prec) << prec.neg_mod_power_of_2(Limb::LOG_WIDTH),
301 })
302 }
303
304 /// Returns the number 1, with the given precision.
305 ///
306 /// $$
307 /// f(p) = 1,
308 /// $$
309 ///
310 /// and the output has precision $p$.
311 ///
312 /// # Worst-case complexity
313 /// $T(n) = O(n)$
314 ///
315 /// $M(n) = O(n)$
316 ///
317 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
318 ///
319 /// # Panics
320 /// Panics if `prec` is zero.
321 ///
322 /// # Examples
323 /// ```
324 /// use malachite_float::Float;
325 ///
326 /// assert_eq!(Float::one_prec(1), 1);
327 /// assert_eq!(Float::one_prec(10), 1);
328 /// assert_eq!(Float::one_prec(100), 1);
329 ///
330 /// assert_eq!(Float::one_prec(1).get_prec(), Some(1));
331 /// assert_eq!(Float::one_prec(10).get_prec(), Some(10));
332 /// assert_eq!(Float::one_prec(100).get_prec(), Some(100));
333 /// ```
334 pub fn one_prec(prec: u64) -> Self {
335 assert_ne!(prec, 0);
336 Self(Finite {
337 sign: true,
338 exponent: 1,
339 precision: prec,
340 significand: Natural::power_of_2(
341 prec.round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
342 .0
343 - 1,
344 ),
345 })
346 }
347
348 /// Returns the number 2, with the given precision.
349 ///
350 /// $$
351 /// f(p) = 2,
352 /// $$
353 ///
354 /// and the output has precision $p$.
355 ///
356 /// # Worst-case complexity
357 /// $T(n) = O(n)$
358 ///
359 /// $M(n) = O(n)$
360 ///
361 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
362 ///
363 /// # Panics
364 /// Panics if `prec` is zero.
365 ///
366 /// # Examples
367 /// ```
368 /// use malachite_float::Float;
369 ///
370 /// assert_eq!(Float::two_prec(1), 2);
371 /// assert_eq!(Float::two_prec(10), 2);
372 /// assert_eq!(Float::two_prec(100), 2);
373 ///
374 /// assert_eq!(Float::two_prec(1).get_prec(), Some(1));
375 /// assert_eq!(Float::two_prec(10).get_prec(), Some(10));
376 /// assert_eq!(Float::two_prec(100).get_prec(), Some(100));
377 /// ```
378 pub fn two_prec(prec: u64) -> Self {
379 assert_ne!(prec, 0);
380 Self(Finite {
381 sign: true,
382 exponent: 2,
383 precision: prec,
384 significand: Natural::power_of_2(
385 prec.round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
386 .0
387 - 1,
388 ),
389 })
390 }
391
392 /// Returns the number $-1$, with the given precision.
393 ///
394 /// $$
395 /// f(p) = -1,
396 /// $$
397 ///
398 /// and the output has precision $p$.
399 ///
400 /// # Worst-case complexity
401 /// $T(n) = O(n)$
402 ///
403 /// $M(n) = O(n)$
404 ///
405 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
406 ///
407 /// # Panics
408 /// Panics if `prec` is zero.
409 ///
410 /// # Examples
411 /// ```
412 /// use malachite_float::Float;
413 ///
414 /// assert_eq!(Float::negative_one_prec(1), -1);
415 /// assert_eq!(Float::negative_one_prec(10), -1);
416 /// assert_eq!(Float::negative_one_prec(100), -1);
417 ///
418 /// assert_eq!(Float::negative_one_prec(1).get_prec(), Some(1));
419 /// assert_eq!(Float::negative_one_prec(10).get_prec(), Some(10));
420 /// assert_eq!(Float::negative_one_prec(100).get_prec(), Some(100));
421 /// ```
422 pub fn negative_one_prec(prec: u64) -> Self {
423 assert_ne!(prec, 0);
424 Self(Finite {
425 sign: false,
426 exponent: 1,
427 precision: prec,
428 significand: Natural::power_of_2(
429 prec.round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
430 .0
431 - 1,
432 ),
433 })
434 }
435
436 /// Returns the number 0.5, with the given precision.
437 ///
438 /// $$
439 /// f(p) = 0.5,
440 /// $$
441 ///
442 /// and the output has precision $p$.
443 ///
444 /// # Worst-case complexity
445 /// $T(n) = O(n)$
446 ///
447 /// $M(n) = O(n)$
448 ///
449 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
450 ///
451 /// # Panics
452 /// Panics if `prec` is zero.
453 ///
454 /// # Examples
455 /// ```
456 /// use malachite_float::Float;
457 ///
458 /// assert_eq!(Float::one_half_prec(1), 0.5);
459 /// assert_eq!(Float::one_half_prec(10), 0.5);
460 /// assert_eq!(Float::one_half_prec(100), 0.5);
461 ///
462 /// assert_eq!(Float::one_half_prec(1).get_prec(), Some(1));
463 /// assert_eq!(Float::one_half_prec(10).get_prec(), Some(10));
464 /// assert_eq!(Float::one_half_prec(100).get_prec(), Some(100));
465 /// ```
466 pub fn one_half_prec(prec: u64) -> Self {
467 assert_ne!(prec, 0);
468 Self(Finite {
469 sign: true,
470 exponent: 0,
471 precision: prec,
472 significand: Natural::power_of_2(
473 prec.round_to_multiple_of_power_of_2(Limb::LOG_WIDTH, Ceiling)
474 .0
475 - 1,
476 ),
477 })
478 }
479}