0

OK this time I have a really weird mistake that does not always appear. Here is the function that actually contains problems. All it does is literally summing elements of a vector. It works in most cases but in a few cases it tend to become highly problematic.

int sumvec(vect v) {
    int i = 0;
    int sum = 0;
    int l = v.length();
    std::cout << "Sum of vector " << v.tostring(3) << std::endl;
    for (; i < l; i++) {
        sum += v[i];
        std::cout << v[i] << " " << sum << " ";
    };
    std::cout << std::endl;
    return sum;
}

Here vect is defined using typedef alglib::real_1d_array vect;. OK so what do I get? Huh..

Sum of vector [1.000,1.000,0.000,1.000,1.000,1.000] 1 0 1 0 0 0 1 0 1 0 1 1

What?!!!!!

Ying Zhou
  • 189
  • 3
  • 16
  • 2
    are your elements actually 1 or a number very slightly less than 1? If they aren't quite 1 then summing them as an integer would produce 0. Try printing `(int)v[i]`. We need an [mcve] – Alan Birtles Oct 16 '18 at 15:41
  • @AlanBirtles Aha. I see. I have changed `int` to `double`. – Ying Zhou Oct 16 '18 at 15:50

2 Answers2

1

As commented use a double to store the sum if you are working with floating point integers. using an integer will cause the variable to be implicitely casted to an int which just cuts of the mantissa:

0.9999998 -> 0

Depending on cout::precision, 0.99999 would be printed as 1.0000(rounded) or without std::fixed just as 1 what propably happens in your example.

double a = 0.999;
std::cout.precision(2);
std::cout << a << std::endl; /* This prints 1 */
std::cout << std::fixed;
std::cout << a << endl; /* This prints 1.00 */
Yastanub
  • 1,227
  • 8
  • 19
1

As your sum variable is an integer you may not get the expected results when summing elements in your vector which are not integers.

If your elements have the value of 0.999999999 rather than 1.00000 then printing them could be rounded to 1.00000 but when you add them to an integer the value will be truncated to 0.

Judging by the provided output all of your values are less than 1 apart from the last one which is greater or equal to 1.

There are 2 possible solutions:

  1. Change the type of sum to be float or double.
  2. Change your calculation to: sum += static_cast<int>(round( v[i] ));

Note that your compiler was probably warning about the truncation of a double to an integer. Pay attention to compiler warnings, they often indicate a bug.

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60