Arithmetic Mean Function C++

Hy ! I did a poor job today at exams with this function.
Haw you will make a function from this simple code.

1
2
3
4
5
6
7
8
9
10
11
12
13
 #include<iostream>
using namespace std;
int main(){
int a,b,c;
cout<<"a=";cin>>a;
cout<<"b=";cin>>b;
cout<<"c=";cin>>c;
double Average=(a+b+c)/3.0;
cout<<"Arithmetic mean= "<<Average;
return 0;

}


So we want a function for an Arithmetic Mean (average).
For your actual example, with exactly 3 inputs,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<iostream>
using namespace std;

double average( int a, int b, int c )
{
   return ( a + b + c ) / 3.0;
}

int main()
{
   int a, b, c;
   cout << "a = ";   cin >> a;
   cout << "b = ";   cin >> b;
   cout << "c = ";   cin >> c;
   cout << "Arithmetic mean = " << average( a, b, c );
}



It's intriguing to think how you might do it for an arbitrary number of inputs (without putting them in an array first).

Array or initializer list (nuisance, because you need to use { } notation):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <numeric>
#include <initializer_list>
using namespace std;

double average( initializer_list<double> L )
{
   return accumulate( L.begin(), L.end(), 0.0 ) / (double)L.size();
}

int main()
{
   cout << average( { 10 } ) << '\n';
   cout << average( { 8.5, 16.5 } ) << '\n';
   cout << average( { 10.5, 21.1, 4 } ) << '\n';
   cout << average( { 1, 2, 3, 4, 5 } ) << '\n';
}



From the command line:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <cstdlib>
using namespace std;

int main( int argc, char *argv[] )
{
   double sum = 0.0;
   if ( argc == 1 )
   {
      cout << "Usage: temp.exe a b c ... \n";
      cout << "   where a, b, c, .. are numbers to be averaged\n";
   }
   else
   {
      for ( int i = 1; i < argc; i++ ) sum += atof( argv[i] );
      cout << "Average is " << sum / ( argc - 1 );
   }
}



Functional form. This is how I would like to call the function, but it's unbelievably messy ... could someone show me how to sum and count in a simpler way?
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
#include <iostream>
using namespace std;

template <typename T> double avsum( int &counter, T a )
{
   counter = 1;
   return a;
}

template <typename T, typename... Tail> double avsum( int &counter, T a, Tail... b )
{
   double total = a + avsum( counter, b... );
   counter++;
   return total;
}

template <typename T> double average( T a )
{
   return a;
}

template <typename T, typename... Tail> double average( T a, Tail... b )
{
   int counter;
   return avsum( counter, a, b... ) / counter;
}

int main()
{
   cout << average( 10 ) << '\n';
   cout << average( 8.5, 16.5 ) << '\n';
   cout << average( 10.5, 21.1, 4 ) << '\n';
   cout << average( 1, 2, 3, 4, 5 ) << '\n';
}
lastchance, not sure if this counts as simpler, but maybe the use of "sizeof...(args)" would help?

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

#include <iostream>

// Modified from
// https://stackoverflow.com/questions/47941837/c-variadic-template-sum
namespace average_impl
{
    template<typename T>
    T sum(T first) {
        return first;
    }
    
    template <typename T, typename... Args>
    double sum(T first, Args... args) { // Note: double here prevents integer divsion
        return first + sum(args...);
    }
}

template <class... Numbers>
double average(Numbers... args)
{
    return average_impl::sum(args...) / sizeof...(args);
}

int main()
{
    using namespace std;
   
    cout << average(4) << endl;             // 4
    cout << average(1, 2, 3) << endl;       // 2
    cout << average(0, 0, 2) << endl;       // 0.33333
    cout << average(1.5, 2.5, 3.5) << endl; // 2.5
}




Last edited on
No, that's fantastic, @Ganado! I didn't know such a feature existed! One for cataloguing now.
1
2
template < typename... T >
constexpr auto average( T&&... v ) { return ( 0.0 + ... + v ) / sizeof...(T) ; }

http://coliru.stacked-crooked.com/a/dfcdb0b402686f51
Thanks lastchance!

Woah, that's nice JLBorges.

Mind explaining why the 0-arg instantiation produces -nan? I can't see where it's implicitly getting that number from.
Last edited on
The binary left fold evaluates to 0.0 when the pack is empty. 0.0/0 is nan.
Last edited on
Thanks. Obvious in hindsight... ;)

Edit 1: Well, I still don't get why 0.0/0 or 0.0/0.0 becomes -nan as opposed to [positive] nan, but it's "not a number" either way, so it doesn't really matter, I'll have to consult IEEE 754.

Edit 2: The negative sign printed apparently has no meaning, which makes sense.
https://stackoverflow.com/a/21350299
Many print routines happen to print the bit as a negative sign, but it is formally meaningless, and therefore there isn't much in the standard to govern what its value should be

Last edited on
Well that managed to reduce my four functions to one! Thank-you @Ganado and @JLBorges. There are some really neat features here.
That concludes today's How to make a function. ;)
Everyone thank you soo much , i wasnt ON for couple days.
I`ll look and learn from everyone . Wish you best to all.

But for me now , best exemple is the first from Mr. lastchance . is lot simpler lol.

Topic archived. No new replies allowed.