1use crate::defs::BigFloatNum;
4use crate::defs::Error;
5
6impl BigFloatNum {
7 pub fn cbrt(&self) -> Result<Self, Error> {
9 let arg = Self::to_big_float_inc(self);
10 let ret = arg.cbrt()?;
11 Self::from_big_float_inc(ret)
12 }
13}
14
15#[cfg(test)]
16mod tests {
17
18 use super::*;
19 use crate::defs::{
20 DECIMAL_MIN_EXPONENT, DECIMAL_POSITIONS, DECIMAL_SIGN_NEG, DECIMAL_SIGN_POS,
21 };
22
23 #[test]
24 fn test_cbrt() {
25 let mut d1;
26
27 let one = BigFloatNum::one();
28 let mut epsilon = BigFloatNum::one();
29 epsilon.e = -epsilon.n as i8 + 2 - (DECIMAL_POSITIONS as i8);
30
31 d1 = BigFloatNum::new();
43 assert!(d1.cbrt().unwrap().n == 0);
44
45 d1 = BigFloatNum::one();
47 let d2 = d1;
48 let ret = d1.cbrt().unwrap();
49 assert!(ret.sub(&d2).unwrap().abs().cmp(&epsilon) <= 0);
50
51 d1.sign = DECIMAL_SIGN_NEG;
52 let d2 = d1;
53 let ret = d1.cbrt().unwrap();
54 assert!(ret.sub(&d2).unwrap().abs().cmp(&epsilon) <= 0);
55
56 d1 = BigFloatNum::one();
58 d1.m[0] = 456;
59 d1.m[8] = 123;
60 d1.e -= 1;
61 let d2 = d1;
62 let ret = d1.cbrt().unwrap();
63 let ret = ret.mul(&ret).unwrap().mul(&ret).unwrap();
64 assert!(ret.div(&d2).unwrap().sub(&one).unwrap().abs().cmp(&epsilon) <= 0);
65
66 d1.sign = DECIMAL_SIGN_NEG;
67 let d2 = d1;
68 let ret = d1.cbrt().unwrap();
69 let ret = ret.mul(&ret).unwrap().mul(&ret).unwrap();
70 assert!(ret.div(&d2).unwrap().sub(&one).unwrap().abs().cmp(&epsilon) <= 0);
71
72 d1.e += 2;
74 d1.sign = DECIMAL_SIGN_POS;
75 let d2 = d1;
76 let ret = d1.cbrt().unwrap();
77 let ret = ret.mul(&ret).unwrap().mul(&ret).unwrap();
78 assert!(ret.div(&d2).unwrap().sub(&one).unwrap().abs().cmp(&epsilon) <= 0);
79
80 d1.sign = DECIMAL_SIGN_NEG;
81 let d2 = d1;
82 let ret = d1.cbrt().unwrap();
83 let ret = ret.mul(&ret).unwrap().mul(&ret).unwrap();
84 assert!(ret.div(&d2).unwrap().sub(&one).unwrap().abs().cmp(&epsilon) <= 0);
85
86 d1 = BigFloatNum::new();
88 d1.m[0] = 456;
89 d1.m[1] = 123;
90 d1.n = 7;
91 d1.e = DECIMAL_MIN_EXPONENT;
92 let d2 = d1;
93 let ret = d1.cbrt().unwrap();
94 let ret = ret.mul(&ret).unwrap().mul(&ret).unwrap();
95 assert!(ret.sub(&d2).unwrap().abs().get_mantissa_len() < 2);
96
97 let mut ret;
99 let mut d1 = BigFloatNum::new();
100 d1.m[0] = 4560;
101 d1.m[1] = 123;
102 d1.m[2] = 6789;
103 d1.m[3] = 2345;
104 d1.m[4] = 651;
105 d1.m[5] = 41;
106 d1.m[6] = 671;
107 d1.m[7] = 100;
108 d1.m[8] = 0;
109 d1.m[9] = 0;
110 d1.n = 32;
111 d1.e = -38;
112 epsilon.e = -epsilon.n as i8 + 3 - (DECIMAL_POSITIONS as i8);
113 for i in 1..8000 {
114 d1.m[8] = 10 + i;
115 d1.m[9] = i;
116 d1.n = if i < 10 {
117 1
118 } else if i < 100 {
119 2
120 } else if i < 1000 {
121 3
122 } else {
123 4
124 } + 36;
125 ret = d1.cbrt().unwrap();
126 ret = ret.mul(&ret).unwrap().mul(&ret).unwrap();
127 assert!(ret.div(&d1).unwrap().sub(&one).unwrap().abs().cmp(&epsilon) <= 0);
128 }
129 }
130}