Finding the Mean and Average of a Set of Temperatures

In Stroustrup's intro C++ book, Proggramming: Principles and Practice Using C++ 2nd Edition, there's an example code for a program that finds the mean and median of a list of temperatures read into a vector via user input. The median formula works for an odd-numbered list of temperatures just fine, but Stroustrup intentionally made it goof up on even-numbered lists for the sake of an exercise at the end of the chapter where the reader has to fix it by writing the correct formula for finding the median of an even-numbered list.

I managed to do it, but I've apparently done the calculation for median of an even-numbered list in a way that it gets my compiler to give me a warning about a possible loss of data (because there's a conversion from a double to an unsigned int - but I don't understand why that's happening).

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
// temperature_vector.cpp : Defines the entry point for the console application.
//

#include "std_lib_facilities.h"

vector<double> read_temperatures();
double average_temperature(const vector<double>& temps);
double median_temperature(vector<double>& temps);
void print_mean_median(const double mean, const double median);

int main()
{
	vector<double> temps = read_temperatures();
	double mean = average_temperature(temps);
	double median = median_temperature(temps);
	print_mean_median(mean, median);
	keep_window_open();
	cin.ignore(32767, '\n');
	cin.ignore(32767, '\n');
}

vector<double> read_temperatures()
{
	vector<double> temps;
	for (double temp; cin >> temp;)
	{
		temps.push_back(temp);
	}
	return temps;
}

double average_temperature(const vector<double>& temps)
{
	double sum = 0;
	for (const double &x : temps)
	{
		sum += x;
	}
	return sum / temps.size();
}

double median_temperature(vector<double>& temps)
{
	double median = 0;
	sort(temps);
	if (temps.size() % 2 != 0)
	{
		median = temps[temps.size() / 2];
	}
	else
	{
		double middle = temps.size() / 2;
		median = (temps[middle + 1] + temps[middle - 2]) / 2.0;
	}
	return median;
}

void print_mean_median(const double mean, const double median)
{
	cout << "Average temperature: " << mean << "\n";
	cout << "Median temperature: " << median << "\n";
}


The output itself seems to be correct, but I want to fix the code on Line 30 so that it doesn't produce that warning.

The warning itself reads as follows:
1>c:\users\osman\programming\visual studio 2015\projects\programming_principles_and_practice_using_c++\temperature_vector\temperature_vector\temperature_vector.cpp(53): warning C4244: 'argument': conversion from 'double' to 'unsigned int', possible loss of data


So yeah, what am I doing wrong that it's giving me that warning? Please help. Also, if there's any problem in the calculation for the median, please let me know.

After editing the code to separate it into different functions and then running it again, I had it crash after taking input for the temperatures. I also need help debugging that problem if it isn't too much trouble.
The 'middle' is a double. An index of array or vector element is an integral.

You should notice from line 48 that temps.size() / 2 must be integral (no warning there), so storing it into a double gains you nothing (well, you do get the warning), but can lose accuracy (for floating point math is not intuitive).


Your indexing on line 53 is a bit suspicious. Let me draw you some elements from the vector:
[m-3] [m-2] [m-1] [m+0] [m+1] [m+2] [m+3]
        ^                 ^

Are you sure that you are taking the average of correct two elements?
Last edited on
I'm not sure about that calculation in the first place (the one for the median in the case that temperature vector has an even number of items). That's the main reason I asked the question, though I'd also like to know about the correct placement of std::cin.ignore() such that the input buffer would be correctly flushed out and the program would wait for the user to enter a character before exiting.

How about if I were to do it like this instead?
median = (temps[middle + 1] + temps[middle - 1]) / 2.0 (note the 2 changed to a 1 on the subtraction).

Edit: Actually, never mind. It's working now. median = (temps[middle + 2] + temps[middle - 2]) / 2.0;
Last edited on
Working? Lets see, I have two temperatures. The temps.size() is thus 2.

middle = 2 / 2 = 1
If we follow your formula, you will compute the average of elements 1+2 (==3) and 1-2 (==-1).
However, the vector has only elements 0 and 1; no -1, no 3.

If the vector has 4 elements, indices {0, 1, 2, 3}, then middle=4/2=2, and the two centermost elements have indices 1 and 2.
If the vector has 6 elements, indices {0, 1, 2, 3, 4, 5}, then middle=6/2=3, and the two centermost elements have indices 2 and 3.

Always middle-1 and middle.

How about the odd sizes?
size = 1; middle = 1/2 = 0; { 0 }
size = 3; middle = 3/2 = 1; { 0, 1, 2 }
size = 5; middle = 5/2 = 2; { 0, 1, 2, 3, 4 }

Neat.


I run programs from terminal. The terminal is open before, during, and after the program. I have no need for nor knowledge about any "keep open" idiom. There is, however, a thread on the subject:
http://www.cplusplus.com/forum/beginner/1988/
Topic archived. No new replies allowed.