Urban75 Home About Offline BrixtonBuzz Contact

Why is this C code not printing out the variance?

electric.avenue

lots of work to be done
I have to have two functions, one for the mean, one for the variance. The one for the mean works, but not the variance one. Just thought maybe some kind person could shed some light. Here's the code:

/*Program to demonstrate functions.*/

#include <stdio.h>

/*function to calculate average of numbers in array*/

float average(float array[], int size)
{
int i;
float sum;
sum=0;


for(i=0;i<size;++i)
{
sum=sum+array;

}

return sum/size;
}

float variance(float array[], int size)
{
int i;
float sum,mean,square,sumsquare;
sum=0;

for(i=0;i<size;++i)
{
sum=sum+array;

}

mean=sum/size;

for(i=0;i<size;++i)
{
square=(array-mean)*(array-mean);
sumsquare=sumsquare+square;


}



return sumsquare;
}

/*Main function starts here.*/

int main()
{
int i,number;
float data[10],mean,var;
number=10;

for(i=0;i<number;++i)
{
printf("Enter data %d ",i);
scanf("%f",&data);

}

/*Process*/
mean=average(data,number);
var=variance(data,number);
printf("Average is %f\n",mean);
printf("Variance is %f\n",var);

return 0;
}


When I run it, it prints out a correct value for the average, but for the variance I just get "Variance is nan".

It would be great if somebody could point me in the right direction. :confused:
 
First debugging thing i'd do is put in debugging code to see where it's failing. Chuck a printf in to see what it's getting for the mean and the array values.

Second thing is to ask why you're duplicating code, can you reuse your average function for the variance? I hate C with a passion but you should be able to call the average function from within the variance one.

(Am i the only one who doesn't really like using preincrement by the by? Gets too confusing to read imo).
 
That works fine for me (compiled with gcc under solaris).

I whacked in some debug output:

float variance(float array[], int size)
{
int i;
float sum,mean,square,sumsquare;
sum=0;

for(i=0;i<size;++i)
{
sum=sum+array;
printf("Sum is %f\n",sum);
}

mean=sum/size;

for(i=0;i<size;++i)
{
square=(array-mean)*(array-mean);
printf("Sumsquare is %f\n",sumsquare);
sumsquare=sumsquare+square;


}
return sumsquare;
}

and got:

a.out
Enter data 0 2
Enter data 1 4
Enter data 2 2
Enter data 3 4
Enter data 4 6
Enter data 5 4
Enter data 6 2
Enter data 7 4
Enter data 8 6
Enter data 9 2
Sum is 2.000000
Sum is 6.000000
Sum is 8.000000
Sum is 12.000000
Sum is 18.000000
Sum is 22.000000
Sum is 24.000000
Sum is 28.000000
Sum is 34.000000
Sum is 36.000000
Sumsquare is 0.000000
Sumsquare is 2.560000
Sumsquare is 2.720000
Sumsquare is 5.280000
Sumsquare is 5.440000
Sumsquare is 11.200000
Sumsquare is 11.360000
Sumsquare is 13.919999
Sumsquare is 14.079999
Sumsquare is 19.840000
Average is 3.600000
Variance is 22.400000
 
(Am i the only one who doesn't really like using preincrement by the by? Gets too confusing to read imo).
It looks plain wrong.

And the code layout is a bit dodgy, but I assume that's vbulletin doing its thing on non CODE tagged text.

For the code itself, what platform and compiler you using ? Also local var sumsquared in variance is uninitialised, which is a Major boo boo and probably causing it to return NAN :( Also personally I wouldn't use local and global vars with the same name, like your mean var.
 
Ok, Bob - thanks for the advice - I didn't know a function could call a function, and I agree the duplication seems a bit untidy.

So, Fruitloop, it works for you but not for me. I'll look into what you've written.

What do you mean by uninitialised, Radar? The compiler is lcc-win32. Platform - I'm on a university pc, if that's what you mean by platform.
 
For everyone else who's eyes are watering...

Code:
/*Program to demonstrate functions.*/

#include <stdio.h>

/*function to calculate average of numbers in array*/

float average(float array[], int size)
{
	int i;
	float sum;
	sum=0;


	for(i=0;i<size;++i)
		{
			sum=sum+array[i];

		}

		return sum/size;
}

float variance(float array[], int size)
{
	int i;
	float sum,mean,square,sumsquare;
	sum=0;

	for(i=0;i<size;++i)
		{
			sum=sum+array[i];

		}

		mean=sum/size;

		for(i=0;i<size;++i)
		{
			square=(array[i]-mean)*(array[i]-mean);
			sumsquare=sumsquare+square;


		}



		return sumsquare;
}

/*Main function starts here.*/

int main()
{
	int i,number;
	float data[10],mean,var;
	number=10;

	for(i=0;i<number;++i)
		{
			printf("Enter data %d ",i);
			scanf("%f",&data[i]);

		}

		/*Process*/
		mean=average(data,number);
		var=variance(data,number);
		printf("Average is %f\n",mean);
		printf("Variance is %f\n",var);

		return 0;
}
 
Ok, Bob - thanks for the advice - I didn't know a function could call a function, and I agree the duplication seems a bit untidy.

So, Fruitloop, it works for you but not for me. I'll look into what you've written.

What do you mean by uninitialised, Radar? The compiler is lcc-win32. Platform - I'm on a university pc, if that's what you mean by platform.
you're using it before it's been assigned a value. Follow it through in your head and you'll see on the first time through the following for loop that you're using sumsquare before it has been assigned something. Fix that by initialising it to zero where you set sum to zero in variance() and you should lose your NAN ;)

Code:
for(i=0;i<size;i++)
  {
  square=(array[i]-mean)*(array[i]-mean);
  sumsquare=sumsquare+square;   <<<<<<<<<<<< Here
  }
Haven't heard of that lcc before. It would probably be a good idea to look up how to enable all the compiler warning it offers.

You learning C off your own bat or via school/college ?? If you intend sticking with c for a while you'll want a copy of K&R
Accept no substitutes :D
 
Grrrr - I keep getting logged out cos on this uni pooter I can't put remember me.

Anyway - Radar - I see the light. I am just off to fix it. Of course, now I remember what initialised is. :D

And Jaed, how did you do that clever thing? :eek:
 
The following seems to work: :D

/*Program to demonstrate functions.*/

#include <stdio.h>

/*function to calculate average of numbers in array*/

float average(float array[], int size)
{
int i;
float sum;
sum=0;


for(i=0;i<size;++i)
{
sum=sum+array;

}

return sum/size;
}

/*function to calculate variance of numbers in an array*/

float variance(float array[], int size)
{
int i;
float sum,mean,square,sumsquare;
sum=0.0;
sumsquare=0.0;

mean=average(array,size);

for(i=0;i<size;++i)
{
square=(array-mean)*(array-mean);
sumsquare=sumsquare+square;


}



return sumsquare/size;
}

/*Main function starts here.*/

int main()
{
int i,number;
float data[10],mean,var;
number=10;

for(i=0;i<number;++i)
{
printf("Enter data %d ",i);
scanf("%f",&data);

}

/*Process*/
mean=average(data,number);
var=variance(data,number);
printf("Average is %f\n",mean);
printf("Variance is %f\n",var);

return 0;
}
 
The variance is the mean squared difference of the scores from the mean, if I'm correct.
I should hope so, cause that's what you coded ;) Yeah, that's it.

Now you need to figure why your C&Ped code looks so crap, even with code tags. You're losing (or not using) indentation, and proper indentation is essential for spotting errors and to make code maintainable. Not indenting correctly is a habit you don't want to get into if you intend working as a coder.
 
I should hope so, cause that's what you coded ;) Yeah, that's it

Now you need to figure why your C&Ped code looks so crap, even with code tags. You're losing (or not using) decent indentation, and proper indentation is essential for spotting errors and to make code maintainable. Not indenting correctly is a habit you don't want to get into if you intend working as a coder.

It's two spaces, by the way.

Anyone what says different is a communist.
 
Thanks, Radar, mate - I'll try to get me indentation under control.

Thanks, everyone who helped! :D

Now I'm working on a prog to solve quadratic equations. :eek:
 
I don't recommend the use of the prefix ++ for general use increment. Use in for is one of the few places that prefix does not effect the result.

i++; is the same as i = i + 1;
++i; is kinda like int prefixadd1(int &x) { x++; return x-1;}
 
I don't recommend the use of the prefix ++ for general use increment. Use in for is one of the few places that prefix does not effect the result.

i++; is the same as i = i + 1;
++i; is kinda like int prefixadd1(int &x) { x++; return x-1;}
Can you expand on why it's not ideal? As i'm reading that you're saying that it's effectively calling a function rather than just an increment operation?

(Or am i just being thick :D ?)
 
I suppose its mainly down to prefix use being quite rare and you have to think about its effect. One is more subtle than the other.

If you call a function int i=5; f(++i) it will pass the added value to the function, f(i++) will pass in i and then add one to i when it returns.

If it were in more general use, post fix wouldn't be such a problem, but its quite rare to see it used. I had to check the C++ standard for 'for' expression evaluation on the for loop to see if the prefix had any effect. Its executed *completely* before the condition, but after the statement, so pre or post makes no difference. For me its keeping the code as simple as possible, C++ is a monster standard that is difficult enough at the best of times. I knew someone who thought nothing about using every single feature of the language and it made his code nearly impenetrable.
 
I don't recommend the use of the prefix ++ for general use increment. Use in for is one of the few places that prefix does not effect the result.

i++; is the same as i = i + 1;
++i; is kinda like int prefixadd1(int &x) { x++; return x-1;}


that was my 1st thought ... if OP is using the c default of zero based arrays, and is prefixing ++, surely i=1 on the 1st iteration? doesn't matter ofc, if it's a 1-based array.

try adding printf("i=%i", i); to the debug if so to check

i always preferred


iSomeCounter=0;

do
{
// do something
iSomeCounter++;
}
while (iSomeCounter <= iSomeLimit);

to for/next as it seemed clearer for just this reason.

eta: sunray is right, increment is made after loop execution; i'll stfu

K&R (page 13)
The for statement has the form

for ( expression1 ; expression2 ; expression3 )
statement;

This statement is equivalent to

expression1;
while ( expression2)
{
statement;
expression3;
}

Thus the first expression specifies initialization for the loop; the second specifies a test, made before each iteration,
such that the loop is exited when the expression becomes 0; the third expression typically specifies an incrementation
which is performed after each iteration.
 
I prefer for loops as they seem to be more consistent across the languages i use. While loops tend to vary a lot more in syntax and layout imo. The pre increment bit above still confuses me deeply.
 
Before compilers optimised the crap out of everything, pre-increments were more efficient, because otherwise the variable had to increment itself and then still return the old value.

It's not convention any more though IME, and it's slightly confusing.
 
You learning C off your own bat or via school/college ?? If you intend sticking with c for a while you'll want a copy of K&R
Accept no substitutes :D

Surprise - I've just taken a look at a pile of books a mate gave me - and here it is - it's signed 1988 though. Could still be mostly relevant, but I think I'll get an up-to-date version.

Thanks for the recommendation.
 
Back
Top Bottom