Skip to content

Commit 45e2c9e

Browse files
committed
Improve accuracy of pi and roots
1 parent aa42376 commit 45e2c9e

File tree

3 files changed

+42
-10
lines changed

3 files changed

+42
-10
lines changed

core/src/num/bigrat.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -967,7 +967,7 @@ impl BigRat {
967967
int: &I,
968968
) -> FResult<Self> {
969969
let mut high_bound = low_bound.clone().add(1.into(), int)?;
970-
for _ in 0..30 {
970+
for _ in 0..50 {
971971
let guess = low_bound
972972
.clone()
973973
.add(high_bound.clone(), int)?

core/src/num/real.rs

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,41 @@ impl Real {
9696
match self.pattern {
9797
Pattern::Simple(s) => Ok(s),
9898
Pattern::Pi(n) => {
99-
let num = BigRat::from(3_141_592_653_589_793_238);
100-
let den = BigRat::from(1_000_000_000_000_000_000);
101-
let pi = num.div(&den, int)?;
99+
let required_accuracy_dp = 20;
100+
let mut pi = BigRat::from(0);
101+
for k in 0..=(required_accuracy_dp / 14) {
102+
let mut term = BigRat::from(1);
103+
if k % 2 == 1 {
104+
term = -term;
105+
}
106+
let k = BigRat::from(k);
107+
term = term.mul(&BigRat::from(6).mul(&k, int)?.factorial(int)?, int)?;
108+
term = term.mul(
109+
&BigRat::from(545_140_134)
110+
.mul(&k, int)?
111+
.add(BigRat::from(13_591_409), int)?,
112+
int,
113+
)?;
114+
term = term.div(&BigRat::from(3).mul(&k, int)?.factorial(int)?, int)?;
115+
term = term.div(
116+
&k.clone().factorial(int)?.pow(BigRat::from(3), int)?.value,
117+
int,
118+
)?;
119+
term = term.div(
120+
&BigRat::from(640_320)
121+
.pow(
122+
BigRat::from(3)
123+
.mul(&k, int)?
124+
.add(BigRat::from(3).div(&BigRat::from(2), int)?, int)?,
125+
int,
126+
)?
127+
.value,
128+
int,
129+
)?;
130+
pi = pi.add(term, int)?;
131+
}
132+
pi = pi.mul(&BigRat::from(12), int)?;
133+
pi = pi.pow(-BigRat::from(1), int)?.value;
102134
Ok(n.mul(&pi, int)?)
103135
}
104136
}

core/tests/integration_tests.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ fn large_simple_subtraction_2() {
573573

574574
#[test]
575575
fn sqrt_half() {
576-
test_eval("sqrt (1/2)", "approx. 0.7071067814");
576+
test_eval("sqrt (1/2)", "approx. 0.7071067811");
577577
}
578578

579579
#[test]
@@ -588,7 +588,7 @@ fn sqrt_1() {
588588

589589
#[test]
590590
fn sqrt_2() {
591-
test_eval("sqrt 2", "approx. 1.4142135619");
591+
test_eval("sqrt 2", "approx. 1.4142135623");
592592
}
593593

594594
#[test]
@@ -1202,7 +1202,7 @@ fn powers_15() {
12021202

12031203
#[test]
12041204
fn powers_16() {
1205-
test_eval("4^(1/4)", "approx. 1.4142135619");
1205+
test_eval("4^(1/4)", "approx. 1.4142135623");
12061206
}
12071207

12081208
#[test]
@@ -1214,7 +1214,7 @@ fn powers_17() {
12141214
fn powers_18() {
12151215
test_eval(
12161216
"5.2*10^15*300^(3/2)",
1217-
"approx. 27019992598076723515.9873962402",
1217+
"approx. 27019992598074485776.9266786817",
12181218
);
12191219
}
12201220

@@ -2501,7 +2501,7 @@ fn abs_2_i() {
25012501

25022502
#[test]
25032503
fn abs_1_plus_i() {
2504-
test_eval("abs (1 + i)", "approx. 1.4142135619");
2504+
test_eval("abs (1 + i)", "approx. 1.4142135623");
25052505
}
25062506

25072507
#[test]
@@ -5398,7 +5398,7 @@ fn day_of_week_type_name() {
53985398

53995399
#[test]
54005400
fn phi() {
5401-
test_eval("phi", "approx. 1.6180339886");
5401+
test_eval("phi", "approx. 1.6180339887");
54025402
}
54035403

54045404
#[test]

0 commit comments

Comments
 (0)