Странная ошибка в получении суммы элементов в alglib :: real_1d_array - PullRequest
0 голосов
/ 16 октября 2018

ОК, на этот раз у меня действительно странная ошибка, которая не всегда появляется.Вот функция, которая на самом деле содержит проблемы.Все, что он делает, - это буквальное суммирование элементов вектора.Это работает в большинстве случаев, но в некоторых случаях это становится очень проблематичным.

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;
}

Здесь vect определяется с помощью typedef alglib::real_1d_array vect;.ОК, так что я получу?Хм ..

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

Что? !!!!!

Ответы [ 2 ]

0 голосов
/ 16 октября 2018

Поскольку ваша переменная суммы является целым числом, вы можете не получить ожидаемых результатов при суммировании элементов вашего вектора, которые не являются целыми числами.

Если ваши элементы имеют значение 0.999999999, а не 1.00000, тогдапечать их может быть округлена до 1.00000, но при добавлении их в целое число значение будет усечено до 0.

Судя по предоставленному выводу, все ваши значения меньше, чем 1, кроме последнегоодин, который больше или равен 1.

Существует 2 возможных решения:

  1. Измените тип sum на float или double.
  2. Измените ваш расчет на: sum += static_cast<int>(round( v[i] ));

Обратите внимание, что ваш компилятор, вероятно, предупреждал об усечении двойного до целого.Обратите внимание на предупреждения компилятора, они часто указывают на ошибку.

0 голосов
/ 16 октября 2018

Как прокомментировано, используйте double для хранения суммы, если вы работаете с целыми числами с плавающей запятой.использование целого числа приведет к тому, что переменная будет неявно приведена к типу int, который просто обрезает мантиссу:

0.9999998 -> 0

В зависимости от cout :: precision 0,99999 будет напечатано как 1,0000(округлено) или без std :: fixed как 1, что, вероятно, происходит в вашем примере.

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