Ying Zhou
Ying Zhou

Reputation: 219

Weird mistake in taking the sums of elements in alglib::real_1d_array

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?!!!!!

Upvotes: 0

Views: 189

Answers (2)

Alan Birtles
Alan Birtles

Reputation: 36488

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.

Upvotes: 1

Yastanub
Yastanub

Reputation: 1237

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 */

Upvotes: 1

Related Questions