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