fastnum2/decimal/dec/math/
sqrt.rs1use crate::decimal::{
2 dec::{
3 convert::to_f64,
4 intrinsics::Intrinsics,
5 math::{add::add, div::div, mul::mul},
6 parse::from_f64,
7 },
8 utils::types,
9 Decimal,
10};
11
12type D<const N: usize> = Decimal<N>;
13
14#[inline]
15pub(crate) const fn sqrt<const N: usize>(d: D<N>) -> D<N> {
16 if d.is_nan() {
17 return d.op_invalid();
18 }
19
20 if d.is_infinite() {
21 return d;
22 }
23
24 if d.is_zero() || d.is_one() {
25 return d;
26 }
27
28 if d.is_negative() {
29 return d.signaling_nan();
30 }
31
32 if d.eq(&D::TWO) {
33 return D::SQRT_2;
34 }
35
36 sqrt_heron(d)
37}
38
39#[inline]
40const fn sqrt_heron<const N: usize>(d: D<N>) -> D<N> {
41 let approx_f64 = to_f64(d);
42 let guess = types::f64::sqrt(approx_f64);
43
44 let mut result = from_f64(guess).compound(&d);
46
47 let mut result_next;
48 let mut i = 0;
49
50 while result.is_ok() && i < Intrinsics::<N>::SERIES_MAX_ITERATIONS {
51 result_next = mul(D::HALF, add(result, div(d, result)));
52
53 if result.eq(&result_next) {
54 break;
55 }
56
57 result = result_next;
58 i += 1;
59 }
60
61 result
62}