astro_float_num/ops/consts/
mod.rs

1mod e;
2mod ln10;
3mod ln2;
4mod pi;
5
6use crate::common::buf::WordBuf;
7use crate::common::util::round_p;
8use crate::mantissa::Mantissa;
9use crate::num::BigFloatNumber;
10use crate::ops::consts::e::ECache;
11use crate::ops::consts::ln10::Ln10Cache;
12use crate::ops::consts::ln2::Ln2Cache;
13use crate::ops::consts::pi::PiCache;
14use crate::BigFloat;
15use crate::Error;
16use crate::RoundingMode;
17
18#[cfg(not(feature = "std"))]
19use alloc::vec::Vec;
20
21/// Constants cache contains arbitrary-precision mathematical constants.
22#[derive(Debug)]
23pub struct Consts {
24    pi: PiCache,
25    e: ECache,
26    ln2: Ln2Cache,
27    ln10: Ln10Cache,
28    tenpowers: Vec<(WordBuf, WordBuf, usize)>,
29}
30
31/// In an ideal situation, the `Consts` structure is initialized with `Consts::new` only once,
32/// and then used where needed.
33impl Consts {
34    /// Initializes the constants cache.
35    ///
36    /// ## Errors
37    ///
38    ///  - MemoryAllocation: failed to allocate memory for mantissa.
39    pub fn new() -> Result<Self, Error> {
40        Ok(Consts {
41            pi: PiCache::new()?,
42            e: ECache::new()?,
43            ln2: Ln2Cache::new()?,
44            ln10: Ln10Cache::new()?,
45            tenpowers: Vec::new(),
46        })
47    }
48
49    /// Returns the value of the pi number with precision `p` using rounding mode `rm`.
50    /// Precision is rounded upwards to the word size.
51    ///
52    /// ## Errors
53    ///
54    ///  - MemoryAllocation: failed to allocate memory for mantissa.
55    ///  - InvalidArgument: the precision is incorrect.
56    pub(crate) fn pi_num(&mut self, p: usize, rm: RoundingMode) -> Result<BigFloatNumber, Error> {
57        let p = round_p(p);
58        self.pi.for_prec(p, rm)
59    }
60
61    /// Returns the value of the Euler number with precision `p` using rounding mode `rm`.
62    /// Precision is rounded upwards to the word size.
63    ///
64    /// ## Errors
65    ///
66    ///  - MemoryAllocation: failed to allocate memory for mantissa.
67    ///  - InvalidArgument: the precision is incorrect.
68    pub(crate) fn e_num(&mut self, p: usize, rm: RoundingMode) -> Result<BigFloatNumber, Error> {
69        let p = round_p(p);
70        self.e.for_prec(p, rm)
71    }
72
73    /// Returns the value of the natural logarithm of 2 with precision `p` using rounding mode `rm`.
74    /// Precision is rounded upwards to the word size.
75    ///
76    /// ## Errors
77    ///
78    ///  - MemoryAllocation: failed to allocate memory for mantissa.
79    ///  - InvalidArgument: the precision is incorrect.
80    pub(crate) fn ln_2_num(&mut self, p: usize, rm: RoundingMode) -> Result<BigFloatNumber, Error> {
81        let p = round_p(p);
82        self.ln2.for_prec(p, rm)
83    }
84
85    /// Returns the value of the natural logarithm of 10 with precision `p` using rounding mode `rm`.
86    /// Precision is rounded upwards to the word size.
87    ///
88    /// ## Errors
89    ///
90    ///  - MemoryAllocation: failed to allocate memory for mantissa.
91    ///  - InvalidArgument: the precision is incorrect.
92    pub(crate) fn ln_10_num(
93        &mut self,
94        p: usize,
95        rm: RoundingMode,
96    ) -> Result<BigFloatNumber, Error> {
97        let p = round_p(p);
98        self.ln10.for_prec(p, rm)
99    }
100
101    /// Returns the value of the pi number with precision `p` using rounding mode `rm`.
102    /// Precision is rounded upwards to the word size.
103    pub fn pi(&mut self, p: usize, rm: RoundingMode) -> BigFloat {
104        match self.pi_num(p, rm) {
105            Ok(v) => v.into(),
106            Err(e) => BigFloat::nan(Some(e)),
107        }
108    }
109
110    /// Returns the value of the Euler number with precision `p` using rounding mode `rm`.
111    /// Precision is rounded upwards to the word size.
112    pub fn e(&mut self, p: usize, rm: RoundingMode) -> BigFloat {
113        match self.e_num(p, rm) {
114            Ok(v) => v.into(),
115            Err(e) => BigFloat::nan(Some(e)),
116        }
117    }
118
119    /// Returns the value of the natural logarithm of 2 with precision `p` using rounding mode `rm`.
120    /// Precision is rounded upwards to the word size.
121    pub fn ln_2(&mut self, p: usize, rm: RoundingMode) -> BigFloat {
122        match self.ln_2_num(p, rm) {
123            Ok(v) => v.into(),
124            Err(e) => BigFloat::nan(Some(e)),
125        }
126    }
127
128    /// Returns the value of the natural logarithm of 10 with precision `p` using rounding mode `rm`.
129    /// Precision is rounded upwards to the word size.
130    pub fn ln_10(&mut self, p: usize, rm: RoundingMode) -> BigFloat {
131        match self.ln_10_num(p, rm) {
132            Ok(v) => v.into(),
133            Err(e) => BigFloat::nan(Some(e)),
134        }
135    }
136
137    /// Return powers of 10: 100, 10000, 100000000, ...
138    pub(crate) fn tenpowers(&mut self, p: usize) -> Result<&[(WordBuf, WordBuf, usize)], Error> {
139        if p >= self.tenpowers.len() {
140            Mantissa::compute_tenpowers(&mut self.tenpowers, p)?;
141        }
142
143        Ok(&self.tenpowers)
144    }
145}