Я столкнулся с некоторыми проблемами при изучении функции накопления в С++ 11: Я знаю, что третий параметр этой функции должен получить понятный тип и действовать по расчету. Я попытался разрешить ему использовать тип int по умолчанию для тестирования, чтобы наблюдать за происходящим преобразованием типа. Как показано ниже, я использую 0 в качестве третьего входного параметра, надеясь, что он распознает тип суммы как int. Я ожидаю, что процесс расчета должен быть (-9) + (3) = -6
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
int main() {
std::vector<double> v = {-9.4, 3.3};
std::cout << std::accumulate(v.cbegin(), v.cend(), 0) << std::endl;
return 0;
}
Результат на выходе не тот, что я ожидал. На самом деле это должно быть преобразование типа, но это не то значение -6, которое мне нужно. Выходной результат равен -5. Я искал некоторую информацию, но не решил эту проблему. В процессе я также провел другие тесты. Я не уверен, возникает ли эта ошибка в процессе преобразования чисел с плавающей запятой. Я надеюсь, что кто-нибудь может помочь мне решить эту проблему или дать мне несколько способов проверить эту ошибку.
Я попробовал кое-что и неожиданно получил правильный ответ после замены исходных значений, но до сих пор не знаю, почему.
Подробности и возможные реализации в инструкции std::accumulate
std::accumulate(v.cbegin(), v.cend(), 0)
вызов примерно эквивалентен
int acc = 0;
for (double elem : v) {
acc = acc + elem;
}
Обратите внимание, что acc + elem
добавляет int
и double
. Согласно стандартным правилам арифметического продвижения, левый аргумент повышается до double
, результат имеет тип double
; затем присваивание преобразует его в int
.
Другими словами, acc = acc + elem
вычисляется как
acc = int(double(acc) + elem);
и не как
acc = acc + int(elem);
как вы, кажется, ожидаете.
Итак, тогда
int(0 + (-9.4)) == int(-9.4) == -9
int(-9 + 3.3) == int(-5.7) == -5
И это результат, который вы наблюдаете. КЭД.
На каждом шаге алгоритм складывает
int
иdouble
, а затем преобразует результат вint
. Сложение осуществляется с плавающей запятой. Итак,int(0 + (-9.4)) == -9
. Тогдаint(-9 + 3.3) == int(-5.7) == -5