3

I have a vector where are 2 values 1.18973e+4932, 1.18973e+4932

vector<long double> v;

In my coursework, I need to find mean and variance of all values in the vector.

  long double mean() const {
     long double sum = 0;

     for (unsigned int i = 0 ; i < len ; i ++)
       sum += v[i];

     return sum/len;
  }

Here I try to find variance

  long double variance() const {
     long double m = mean();
     long double sum = 0;

     for (unsigned int i = 0 ; i < len ; i ++) 
       sum += (v[i] - m) * (v[i] - m);

     return sum/len;
}

But I am getting inf as result with 1.18973e+4932 values

Josh Lo
  • 33
  • 3
  • 3
    It depends on what `long double` compiles to in your build environment, but I do know that `1.18973e+4932` is waaaaay bigger than the [maximum range of a 64-bit float](http://stackoverflow.com/questions/1848700/biggest-integer-that-can-be-stored-in-a-double), and is only barely smaller than the maximum range of an 80-bit float. – Xirema Dec 02 '16 at 19:34

2 Answers2

2

I'm going forwards with this answer assuming that you're using long double because your compiler is compiling it into 80-bit floats.

Your first problem is in your mean() function, where 1.18973e+4932 + 1.18973e+4932 is immediately overflowing into infinity, as the maximum value of 80-bit floats is ~1.2e+4932. inf / 2 is still equal to inf, so your mean() function is returning inf as the value.

Then, in your variance function, you're calculating (1.18973e+4932 - inf) * (1.18973e+4932 - inf) which resolves to -inf * -inf which resolves to inf. Then, yet again, inf / 2 equals inf.

As you mentioned in your own answer, dividing each member by 2 as you sum them, instead of summing and then dividing, avoids the overflow (though this solution will fail if, instead of dealing with extremely large numbers, you start dealing with extremely small numbers!)

The other solution is to borrow a multiprecision library (like boost.multiprecision) and drop your values into a quad or larger floating point type that won't overflow when dealing with these kinds of calculations.

Xirema
  • 19,889
  • 4
  • 32
  • 68
0

I am ashamed. that I wasn't able to solve it before...

The answer that you can divide value before the addition of numbers

mean:

  long double mean() const {
     long double sum = 0;

     for (unsigned int i = 0 ; i < len ; i ++)
       sum += v[i]/len;

     return sum;
    }

variance:

it uses mean it will be 0

Josh Lo
  • 33
  • 3