Standard Deviation problem!!!

I was assigned a problem that allows the user to enter a quantity of integers using an array. It prints out the values, the average, and the standard deviation of the values entered.

I am having some problems with the standard deviation part. If you could help me figure it out that would be great. Here is my code so far...


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
// This program prompts the user to enter a quantity of values
// then prints the values the user entered, the average of the values,
// and the standard deviation of the values.

#include <iostream>
#include <cmath>

using namespace std;

const int VALSIZE = 100;

void checkVals(int numVals);
void displayVals(int vals[], int numVals);
void getVals(int vals[], int numVals, int &sum);
int average(int sum, int numVals);
int stanDev(int sum, int numVals);

int main()
{
	int numVals, sum=0;
	
	cout << "Please enter the number of values you would like(1-100): ";
	cin >> numVals;
	checkVals(numVals);
	
	int vals[VALSIZE];
	getVals(vals, numVals, sum);
	cout << endl;
	displayVals(vals, numVals);
	cout << endl;

	cout << "The average of your values is: ";
	cout << average(sum, numVals) << ".\n";

	cout << "The standard deviation of your values is: ";
	cout << stanDev(sum, numVals) << ".\n";

}

void getVals(int vals[], int numVals, int &sum)
{
	int index;
	for(index=0; index<numVals; index++) {
		cout << "Please enter value #" << index+1 << ": ";
		cin >> vals[index];
		sum+=vals[index];
	}
}

void displayVals(int vals[], int numVals)
{
	int index;
	for(index=0; index<numVals; index++) {
		cout << "Here is value #" << index+1 << ": ";
		cout << vals[index] << ".\n";
	}
}

void checkVals(int numVals)
{
	while ((numVals<0) || (numVals>100)) {
		cout << "That is an invalid value entered.\n";
		cout << "Please reenter your value.\n";
		cin >> numVals;
	}
}

int average(int sum, int numVals)
{
	return sum/numVals;
}

int stanDev(int sum, int numVals)
{
	return sqrt(((pow(sum,2.0)) - ((1.0/numVals) * (pow(sum,2.0)))) / (numVals-1.0));

}
There are some errors in your code:

1) I suppose average must be double, not int. The integer-values division sum/numVals is an integer as well and can significantly differ from the true value

2) When you write
cin >> numVals;
in your checkVals() function, this operator doesn't do what is expected. The numVals variable is local for the function. To change the outer numVals pass it by reference:

void checkVals(int& numVals)

3) I can't understand what is the formula you use in stanDev(). I would write as follows

1
2
3
4
5
6
7
8
double stanDev(int vals[], int numVals)
{
  double sigma_squared = 0.0;
  double ave = average(vals, numVals);
  for(int i=0; i<numVals; ++i)
       sigma_squared += (vals[i] - ave)*(vals[i] - ave);
  return sqrt(sigma_squared/(numVals-1));
}
Thanks for the help! But after i fixed the errors the next error that I have is that it cannot convert the vals paramater in the average function call from int [] to int.


average(vals, numVals);

This is the one in the stanDev function.
oh, of course i supposed the function average() to be a "normal" average function:

1
2
3
4
5
6
7
double average(int vals[], int numVals)
{
   int sum = 0;
   for(int i=0; i<numVals; ++i)
       sum += vals[i];
   return (double)sum/numVals;
}
I'm new to this forum. So, hopefully this helps.

My solution is similar to melkiy's. Melkiy's standard deviation function is correct. Although, it does assume sample standard deviation instead of population standard deviation. Depending on which one you require, you will use an unbiased estimator (denominator = sample size - 1) of the pop. var or not. My version assumes population variance; hence no estimator:

1
2
3
4
5
6
7
8
9
10
double stanDev(double vals[], double mean, double numVals)
{
	double sum=0,value=0;
	for (int i=0; i<numVals; i++)
	{
		value = (vals[i]-mean)*(vals[i]-mean);
		sum+=value;
	}
	return sqrt(sum/numVals);
}


Also, you will lose significant figures, when calculating variance. And hence, you will not end up with the correct standard deviation. So, instead of casting, you may want to set all values to double. Any values, especially statistical ones, should be doubles or at the very least floats. Integer values will generally lead to undesirable results.

If I am wrong about any C++ info here, please correct me, as I haven't programmed in C++ in a long time and I've joined this forum as a way to review and improve.

Thanks all!

- Ray


Ok here is my my new code that i have constructed. Unfortunately I think I am getting the wrong standard deviation answer. Any help with it would be great!

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
// This program prompts the user to enter a quantity of values
// then prints the values the user entered, the average of the values,
// and the standard deviation of the values.

#include <iostream>
#include <cmath>

using namespace std;

const int VALSIZE = 100;

void checkVals(int &numVals);
void displayVals(int vals[], int numVals, int sum);
void getVals(int vals[], int numVals);
double average(int vals[], int numVals, int &sum);
double stanDev(int vals[], int numVals, int sum);

int main()
{
	int numVals; 
	int sum = 0;
	int vals[VALSIZE];

	cout << "Please enter the number of values you would like(1-100): ";
	cin >> numVals;
	checkVals(numVals);

	getVals(vals, numVals);
	cout << endl;
	displayVals(vals, numVals, sum);
	cout << endl;

	

}

void getVals(int vals[], int numVals)
{
	int index;
	for(index=0; index<numVals; index++) {
		cout << "Please enter value #" << index+1 << ": ";
		cin >> vals[index];
	}
}

void displayVals(int vals[], int numVals, int sum)
{
	int index;
	for(index=0; index<numVals; index++) {
		cout << "Here is value #" << index+1 << ": ";
		cout << vals[index] << ".\n";
	}

	cout << endl;
	cout << "The average of your values is: ";
	cout << average(vals, numVals, sum) << ".\n";

	cout << endl;
	cout << "The standard deviation of your values is: ";
	cout << stanDev(vals, numVals, sum) << ".\n";

}

void checkVals(int &numVals)
{
	while ((numVals < 0 ) || (numVals > 100 )) {
		cout << "That is an invalid value entered!!!\n";
		cout << "A valid value is between 0 and 100 inclusive!!!\n";
		cout << "Please reenter the number of values that you would like!\n";
		cin >> numVals;
	}
}


double average(int vals[], int numVals, int &sum)
{	
	int i;
	for(i=0; i<numVals; i++) {
		sum+= vals[i];
	}
	return (double)sum/numVals;
}

double stanDev(int vals[], int numVals, int sum)
{
	double sigmaSquared = 0.0;
	int i;
	double ave = average(vals, numVals, sum);
	for(i=0; i<numVals; i++) {
		sigmaSquared += pow((vals[i] - ave),2.0);
	}
	return sqrt(sigmaSquared/(numVals-1));
}
Last edited on
I ran your previous code with the adjustments I suggested. It ran fine and produced accurate results to 3 significant figures. Pls see my previous entry.

A minor point...I don't know your background but if it's in engineering, finance, science, or anything with a stats background, you may consider changing your variable names to things like 'variance' instead of 'sigmaSquared'...just more descriptive, clearer, and shorter, imho.
I understand the adjustments you would like me to make, however in the problem i was given the professor wants the user to enter integer values and not floats or doubles. Also when I looked on the internet for standard deviation calculators and put the same numbers in the calculator as I did with my program it gave me two different numbers. However, like you said in your previous post this was due to my program calculating population deviation. How would I get my program to calculate regular standard deviation and not variance or population deviation?
That's unusual that your prof wants int values to be entered for this type of calculation. Hmm...I'm going to work on casting it so we don't lose sig figs. In the mean time, does the problem state to how many sig.figs your mean(average) and sd should calculate to?

At first glance, I've noticed you rely on the math.h library functions a lot (i.e. average, pow,etc) Are you required to do that? These are easy algorithms to incorporate and it's good exercise, so you should not rely too much on them. Also, it helps condition your mind to build your own...it's the difference between a mediocre programmer and an design architect...a big difference in salary.

There's no such thing as "regular" standard deviation. There's either sample or population. From your formula, I can see your stanDev function returns a sample stand dev. Variance is your "sigmaSquared" and it's local to your stanDev...so no worries. Providing you are using the math.h functions correctly, it should return what you call a "regular" standard deviation. If this is true, then casting is the only problem at this point.

FYI, I rewrote your code casting from int to double...and compared it to my previous results and my trusty HP financial calculator and it's off. So casting is making a BIG difference.

Ok. I used the code you first provided and calls to these adjusted functions. Notice the casting. They take place within the called functions. Also, notice the return types of both...doubles. The critical int[] (values entered by the user) is kept per your prof's requirements and casted right before we perform any arithmetic where significant figures are required. I ran the program against numbers from an old stats book I have and the solution is clean without losing any significant figures. You should easily incorporate this into your code.

I used population variance to calculate standard deviation. So, if you want sample variance, you need to change the denominator to numVals-1.

This worked off a lot of rust. If you ever get stuck again, post and then note me (I don't read every post...still waiting for someone to help me with a problem with IOstreams), I'll be happy to help if I have the time.

Thank you and good luck with school!

- Ray

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
double average(int sum, int numVals)
{
	double dsum = (double)sum;
	double dnumVals = (double)numVals;
	return dsum/dnumVals;
}


double stanDev(int vals[], double mean, int numVals)
{
	double sum=0,dVals=0,value=0, variance=0;
	for (int i=0; i<numVals; i++)
	{
		dVals = (double)vals[i];
		value = (dVals-mean)*(dVals-mean);
		sum+=value;
		variance = sum/(numVals);
	}
	return sqrt(variance);
}

Last edited on
Thanks for all your help Ray!! If I have any other problems will be happy to try and contact you about them.
Topic archived. No new replies allowed.