finding pi with machin.

Hi, I am a beginner in c++ with basic knowledge in coding and started with python. My college hasn't started yet and i've just been doing projects on my own. I've written a few programs to find pi, this one being the most advanced. I used Machin's formula, pi/4 = 4(arctan(1/5)) - (arctan(1/239)).

The problem is that however many iterations i do, i get the same result, and i can't seem to understand why, and i unfortunately don't have a teacher.
I am using visual studios 2015 community on a windows 7. I would also greatly welcome any help on form and style. Thank you :)


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

#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <math.h>
using namespace std;

double arctan_series(int x, double y) // x is the # of iterations while y is the number
{
	double pi = y;
	double temp_Pi;
	for (int i = 1, j = 3; i < x; i++, j += 2) 
	{
		temp_Pi = pow(y, j) / j; //the actual value of the iteration
		if (i % 2 != 0)		// for every odd iteration that subtracts
		{
			pi -= temp_Pi;
		}
		else	// for every even iteration that adds
		{
			pi += temp_Pi;
		}
	}
	pi = pi * 4;
	return pi;
}

double calculations(int x) // x is the # of iterations
{
	double value_1, value_2, answer;
	value_1 = arctan_series(x, 0.2);
	value_2 = arctan_series(x, 1.0 / 239.0);
	answer = (4 * value_1) - (value_2);
	return answer;
}

int main() 
{
	double pi;
	int iteration_num;
	cout << "Enter the number of iterations: ";
	cin >> iteration_num;
	pi = calculations(iteration_num);
	cout << "Pi has the value of: " << setprecision(100) << fixed << pi << endl;
	return 0;

}

Hi, it worked for me, as you had it.

I made some changes and comments, mainly the loop and std::

Google about using namespace std; and why it is bad :+)


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
//#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <cmath>
//using namespace std;


// x is the # of iterations while y is the number
double arctan_series(const int x, const double y) 
{
	double pi = y;
	double temp_Pi;
	for (int i = 1, j = 3; i < x; i++, j += 2) 
	{
		temp_Pi = std::pow(y, j) / j; //the actual value of the iteration
		if (i % 2 != 0)		// for every odd iteration that subtracts
		{
			pi -= temp_Pi;
		}
		else	// for every even iteration that adds
		{
			pi += temp_Pi;
		}
	}
	//pi = pi * 4;
pi *= 4.0;
	return pi;
}

double calculations(const int x) // x is the # of iterations  We are not changing x
{
	double value_1 = 1.0;  // always initialise to something
double value_2 = 1.0;   // always initialise to something
double answer = 1.0;    // always initialise to something

	value_1 = arctan_series(x, 0.2);
	value_2 = arctan_series(x, 1.0 / 239.0);
	answer = (4 * value_1) - (value_2);
	return answer;
}

int main() 
{
	double pi = 1.0;  // always initialise to something
	int iteration_num;
	std::cout << "Enter the number of iterations: ";
		std::cin >> iteration_num;

for (int term = 2; term < iteration_num; ++term) {
	       pi = calculations(term);
        std::cout << std::setprecision(16) <<  std::fixed;  // 16sf is as much as double can do
	       std::cout << "Pi has the value of: term " <<  term  << " " << pi << "\n";
}

	return 0;

}
Last edited on
Enter the number of iterations: 10
Pi has the value of: term 2 3.1405970293260603
Pi has the value of: term 3 3.1416210293250346
Pi has the value of: term 4 3.1415917721821773
Pi has the value of: term 5 3.1415926824043994
Pi has the value of: term 6 3.1415926526153086
Pi has the value of: term 7 3.1415926536235550
Pi has the value of: term 8 3.1415926535886025
Pi has the value of: term 9 3.1415926535898362
Thanks! This is really helpful.
First off, why do i have to keep them the function value as constants? It's not like those numbers are tampered with? Is it something to do with memory? It feels like i don't really know when to use const.

I'm not sure but i heard that uninitialized variables will cause glitches, as it makes the program non-deterministic. Is that true? or is there another reason.

One last question, how can i get more decimal places? I want to try and get at least a 100, not sure how long it will take but i really want to get to lots of decimal places haha.
First off, why do i have to keep them the function value as constants?

You don't. The 'advantage' of having const parameters is not having to worry about them being changed in the function body, which makes it easier to reason about the code in longer functions. I don't know why someone would take the time to say they should be const.


I'm not sure but i heard that uninitialized variables will cause glitches, as it makes the program non-deterministic. Is that true?

No, it's not true. Using variables which have had no value assigned to them can be problematic, but not immediately initializing variables is not problematic unless you have a propensity for losing track of whether they've been assigned a value.

You should, however, define variables as close as possible to first use:

1
2
3
4
5
6
7
double calculations(int x) // x is the # of iterations
{
	double value_1 = arctan_series(x, 0.2);
	double value_2 = arctan_series(x, 1.0 / 239.0);
	double answer = (4 * value_1) - (value_2);
	return answer;
}


In which case you may find initialization comes more naturally.

One last question, how can i get more decimal places? I want to try and get at least a 100, not sure how long it will take but i really want to get to lots of decimal places haha.

You'd have to use a third-party library to work that out. Unfortunately you can't do it with native types.

If you're set on doing so, you might begin here:
http://www.boost.org/doc/libs/1_53_0/libs/multiprecision/doc/html/boost_multiprecision/intro.html

If you end up doing any serious programming in C++, you're going to encounter Boost anyway.
Hi,

I guess that initialising variables at declaration is a type of defensive measure, as is putting braces around a single statement belonging to an if as an example.

It's not strictly required, but might save you one day, or someone else. Uninitialised variables can be a real problem.

cire's example is great, something useful is being assigned at declaration, rather than some dummy value, and that is really good. If you can delay declaration until then, then do it. But a dummy value is better than garbage, especially if it can be assigned some invalid value. For example, the char is supposed to be a, b or c, but it is still z becasuse we never assigned anything to it.

I view const correctness in the same light, as is good variable and function names, good use of white space, indenting, function pre and post conditions, correct and appropriate types.

With const, if one doen't use it, and then is distracted, under pressure, tired or otherwise discombobulated then one might write code that changes that variable, causing a possibly hard to spot error. If one does use const, then the compiler will tell you, possibly within 500 milliseconds if you have background compilation on. This is much better than it being much later and being in the depths of the debugger, or worse it's someone else debugging your code.

Anyway , Good Luck :+)

I view const correctness in the same light, as is good variable and function names

I'm all for const correctness, but top level const on parameters doesn't have anything to do with it, since it doesn't affect function overload resolution.

http://stackoverflow.com/questions/117293/use-of-const-for-function-parameters
covers the topic pretty well.

cire wrote:
I'm all for const correctness, but top level const on parameters doesn't have anything to do with it, since it doesn't affect function overload resolution.


Ok, that is fine, but what about avoiding inadvertently assigning a value to a parameter variable? The compiler will let one know with an error - that's worth doing surely?
Sometimes I will purposefully "adjust" the values of parameters at the start of a function. For a function similar to strlen I'd probably just increment the poiner-parameter rather than defining a new pointer. They're just local variables, after all. Sometimes I don't want them to be constant. Typically though, it's very obvious at the beginning of the function if a parameter is being used thusly.
@cire

I agree with what you are saying.

@flaemtail

There maybe a slight misunderstanding: I am not saying that parameters should always be marked const, just that often they could be, and if one knows they don't want the value to change then mark them const.

Regards :+)
Topic archived. No new replies allowed.