malachite_float/constants/prime_constant.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 core::cmp::Ordering;
11use malachite_base::num::factorization::primes::prime_indicator_sequence_less_than_or_equal_to;
12use malachite_base::rounding_modes::RoundingMode::{self, *};
13
14impl Float {
15 /// Returns an approximation to the prime constant, with the given precision and rounded using
16 /// the given [`RoundingMode`]. An [`Ordering`] is also returned, indicating whether the rounded
17 /// value is less than or greater than the exact value of the constant. (Since the constant is
18 /// irrational, the rounded value is never equal to the exact value.)
19 ///
20 /// The prime constant is the real number whose $n$th bit is prime if and only if $n$ is prime.
21 /// That is,
22 /// $$
23 /// P = \sum_{p\ text{prime}\}2^{-p}.
24 /// $$
25 ///
26 /// The constant is irrational.
27 ///
28 /// The output has precision `prec`.
29 ///
30 /// # Worst-case complexity
31 /// $T(n) = O(n)$
32 ///
33 /// $M(n) = O(n)$
34 ///
35 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
36 ///
37 /// # Panics
38 /// Panics if `prec` is zero or if `rm` is `Exact`.
39 ///
40 /// # Examples
41 /// ```
42 /// use malachite_base::rounding_modes::RoundingMode::*;
43 /// use malachite_float::Float;
44 /// use std::cmp::Ordering::*;
45 ///
46 /// let (pc, o) = Float::prime_constant_prec_round(100, Floor);
47 /// assert_eq!(pc.to_string(), "0.4146825098511116602481096221542");
48 /// assert_eq!(o, Less);
49 ///
50 /// let (pc, o) = Float::prime_constant_prec_round(100, Ceiling);
51 /// assert_eq!(pc.to_string(), "0.4146825098511116602481096221546");
52 /// assert_eq!(o, Greater);
53 /// ```
54 pub fn prime_constant_prec_round(prec: u64, rm: RoundingMode) -> (Self, Ordering) {
55 // Strictly speaking, this call violates the preconditions for
56 // `non_dyadic_from_bits_prec_round`, because the iterator passed in is finite. But since we
57 // know exactly how many bits `non_dyadic_from_bits_prec_round` will read, we can get away
58 // with this.
59 Self::non_dyadic_from_bits_prec_round(
60 prime_indicator_sequence_less_than_or_equal_to(if rm == Nearest {
61 prec + 2
62 } else {
63 prec + 1
64 }),
65 prec,
66 rm,
67 )
68 }
69
70 /// Returns an approximation to the prime constant, with the given precision and rounded to the
71 /// nearest [`Float`] of that precision. An [`Ordering`] is also returned, indicating whether
72 /// the rounded value is less than or greater than the exact value of the constant. (Since the
73 /// constant is irrational, the rounded value is never equal to the exact value.)
74 ///
75 /// The prime constant is the real number whose $n$th bit is prime if and only if $n$ is prime.
76 /// That is,
77 /// $$
78 /// P = \sum_{p\ text{prime}\}2^{-p}.
79 /// $$
80 ///
81 /// The constant is irrational.
82 ///
83 /// The output has precision `prec`.
84 ///
85 /// # Worst-case complexity
86 /// $T(n) = O(n)$
87 ///
88 /// $M(n) = O(n)$
89 ///
90 /// where $T$ is time, $M$ is additional memory, and $n$ is `prec`.
91 ///
92 /// # Panics
93 /// Panics if `prec` is zero.
94 ///
95 /// # Examples
96 /// ```
97 /// use malachite_float::Float;
98 /// use std::cmp::Ordering::*;
99 ///
100 /// let (pc, o) = Float::prime_constant_prec(1);
101 /// assert_eq!(pc.to_string(), "0.5");
102 /// assert_eq!(o, Greater);
103 ///
104 /// let (pc, o) = Float::prime_constant_prec(10);
105 /// assert_eq!(pc.to_string(), "0.4146");
106 /// assert_eq!(o, Less);
107 ///
108 /// let (pc, o) = Float::prime_constant_prec(100);
109 /// assert_eq!(pc.to_string(), "0.4146825098511116602481096221542");
110 /// assert_eq!(o, Less);
111 /// ```
112 #[inline]
113 pub fn prime_constant_prec(prec: u64) -> (Self, Ordering) {
114 Self::prime_constant_prec_round(prec, Nearest)
115 }
116}