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
use crate::Consts;
use crate::common::consts::ONE;
use crate::common::util::count_leading_zeroes_skip_first;
use crate::num::BigFloatNumber;
use crate::defs::RoundingMode;
use crate::defs::Error;
impl BigFloatNumber {
pub fn acosh(&self, rm: RoundingMode, cc: &mut Consts) -> Result<Self, Error> {
let cmpone = self.cmp(&ONE);
if cmpone == 0 {
return Self::new(self.get_mantissa_max_bit_len());
} else if cmpone < 0 {
return Err(Error::InvalidArgument);
}
let mut additional_prec = 0;
if self.get_exponent() == 1 {
additional_prec = count_leading_zeroes_skip_first(self.m.get_digits());
}
let mut x = self.clone()?;
x.set_precision(x.get_mantissa_max_bit_len() + 3 + additional_prec, RoundingMode::None)?;
let xx = x.mul(&x, RoundingMode::None)?;
let d1 = xx.sub(&ONE, RoundingMode::None)?;
let d2 = d1.sqrt(RoundingMode::None)?;
let d3 = d2.add(&x, RoundingMode::None)?;
let mut ret = d3.ln(RoundingMode::None, cc)?;
ret.set_precision(self.get_mantissa_max_bit_len(), rm)?;
Ok(ret)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_acosh() {
let mut cc = Consts::new().unwrap();
let rm = RoundingMode::ToEven;
let n1 = BigFloatNumber::from_word(2,320).unwrap();
let _n2 = n1.acosh(rm, &mut cc).unwrap();
let n1 = BigFloatNumber::parse("1.0000000000000000000000000000000000000000000B56A0EBA6F7D47E21A7B2A7806A698BABAF2F05BC61E2F8FB50FE0B98F55B181AC9C8_e+0", crate::Radix::Hex, 448, RoundingMode::None).unwrap();
let n2 = n1.acosh(rm, &mut cc).unwrap();
let n3 = BigFloatNumber::parse("4.C31368910963B1A1BCFC0EDBD393FB7A5E876F9751D93A20E7E48EC0D16090ADA5F46DF2184D32A19C500088EA09CBD4F23DF713113D8A58_e-16", crate::Radix::Hex, 448, RoundingMode::None).unwrap();
assert!(n2.cmp(&n3) == 0);
let n1 = BigFloatNumber::parse("1.921FB54442D18469898CC51701B839A200000000000000004D3C337F7C8D419EBBFC39B4BEC14AF6_e+1000", crate::Radix::Hex, 320, RoundingMode::None).unwrap();
let n2 = n1.acosh(rm, &mut cc).unwrap();
let n3 = BigFloatNumber::parse("2.C5DAB0AF9025886C3364C7B6D6741EB19D4FB009D3F92CA21B77498D9F0666363C665F2F324EAEC8_e+3", crate::Radix::Hex, 320, RoundingMode::None).unwrap();
assert!(n2.cmp(&n3) == 0);
}
#[ignore]
#[test]
#[cfg(feature="std")]
fn acosh_perf() {
let mut cc = Consts::new().unwrap();
let mut n = vec![];
for _ in 0..10000 {
n.push(BigFloatNumber::random_normal(160, 0, 5).unwrap());
}
for _ in 0..5 {
let start_time = std::time::Instant::now();
for ni in n.iter() {
let _f = ni.acosh(RoundingMode::ToEven, &mut cc).unwrap();
}
let time = start_time.elapsed();
println!("{}", time.as_millis());
}
}
}