help with a function

I have to write a function to count the number of students who scored Y marks in GPA. The result should be stored in the array sum_gpa[]. The student can score from 1 (highest), 0.6, 0.3 and 0 (lowest).

My intend is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void getTotalGPA(int numOfStudents, float gpa[], int sum_gpa[]) {

/*int numOfStudents: Integer number containing the total number of students
float gpa[]: Array of type float containing the GPA marks of all students
int sum_gpa[]: Integer array to be computed */

     int j;
     for (j = 0; j < numOfStudents; j++){
	if (gpa[j] == 0){
	      sum_gpa[0]++;
	}
	if (gpa[j] == 0.3){
	      sum_gpa[1]++;
        }
        if (gpa[j] == 0.6){
		sum_gpa[2]++;
	}
	if (gpa[j] == 1){
		sum_gpa[3]++;
	}
     }
}
  


It works good for case 0 and 1, but not for the other cases. Could someone please help me? Many thanks.
Clearly, you need to check if gpa[j] is inside a range not if it's equal to its ends.
Do you mean?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void getTotalGPA(int numOfStudents, float gpa[], int sum_gpa[]) {

/*int numOfStudents: Integer number containing the total number of students
float gpa[]: Array of type float containing the GPA marks of all students
int sum_gpa[]: Integer array to be computed */

     int j;
     for (j = 0; j < numOfStudents; j++){
	if (gpa[j]>= 0 & gpa[j] <0.3){
	      sum_gpa[0]++;
	}
	.................
	}
     }
}


The array read from a file is like gpa[j]={0, 1, 1, 0, 0.3, .........}. That was the reason that I check if gpa[j] is equal some of the possible scores.

You're a victim of precision error.

There are two things you need to consider.
First, when you write: 0.3 this literal is assumed to a double. Not float.
If you want float literals you should use: 0.3f

Second, you're almost certain to get false if you compare double and a float using == .
This is because of differences in precision. To see it in action compare the outputs of the following:
1
2
printf("%.20f\n", 0.3f); //0.30000001192092896000
printf("%.20lf\n", 0.3); //0.29999999999999999000 

1 and 0 are different in this regard because they are "well behaved" and so are all numbers which can be written in binary form with finite number of digits. e.g. 0.5f == 0.5 will yield true. For almost every other number though (there are a lot more pathological than well behaved numbers) you ought to get false after doing such a comparison

In general, you must never use == between float or double types (let alone mix them together!)
Instead, if you wanted to compare if two floating point values are "equal" you should use something like the following:
1
2
#define M_PREC 0.0001
#define fcmp(x, y) (fabs(x - y) < M_PREC) 

That is, you should only consider them "equal" up to M_PREC.
You might think this is cumbersome, but that's how it's done.
Last edited on
Now I understand because it does not work.


Instead, if you wanted to compare if two floating point values are "equal" you should use something like the following:

#define M_PREC 0.0001
#define fcmp(x, y) (fabs(x - y) < M_PREC)

That is, you should only consider them "equal" up to M_PREC.


I have not yet studied that. I tried to check gpa inside a range and that works. The function is now:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

void getTotalGPA(int numOfStudents, float gpa[], int sum_gpa[]) {

	for (int i=0; i<numOfStudents; i++){
        if (gpa[i]==1) {
			sum_gpa[3]++;
		}
        if (gpa[i] > 0.55 && gpa[i] < 0.65) {
			sum_gpa[2]++;
		}
        if (gpa[i] > 0.25 && gpa[i] < 0.35) {
			sum_gpa[1]++;
		}
        if (gpa[i]==0) {
			sum_gpa[0]++;
		}
	}
}


Thank you again for your help.
Topic archived. No new replies allowed.