Arithmetic Mean Function C++

Sep 3, 2018 at 11:11am
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).
Sep 3, 2018 at 11:59am
Sep 4, 2018 at 8:40am
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';
}
Sep 4, 2018 at 5:32pm
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 Sep 4, 2018 at 5:34pm
Sep 4, 2018 at 5:36pm
No, that's fantastic, @Ganado! I didn't know such a feature existed! One for cataloguing now.
Sep 4, 2018 at 6:23pm
1
2
template < typename... T >
constexpr auto average( T&&... v ) { return ( 0.0 + ... + v ) / sizeof...(T) ; }

http://coliru.stacked-crooked.com/a/dfcdb0b402686f51
Sep 4, 2018 at 6:28pm
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 Sep 4, 2018 at 6:35pm
Sep 4, 2018 at 6:31pm
The binary left fold evaluates to 0.0 when the pack is empty. 0.0/0 is nan.
Last edited on Sep 4, 2018 at 6:32pm
Sep 4, 2018 at 6:36pm
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 Sep 4, 2018 at 6:52pm
Sep 4, 2018 at 6:53pm
Well that managed to reduce my four functions to one! Thank-you @Ganado and @JLBorges. There are some really neat features here.
Sep 4, 2018 at 7:17pm
That concludes today's How to make a function. ;)
Sep 5, 2018 at 12:19pm
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.