c++ - sumar - ¿Por qué la función std:: acumulate muestra la suma incorrecta de un vector<double>?
vectores en c++ ejercicios resueltos (4)
Cambio de 0
a 0.0
. Entonces recibe 10.4
para mí. Si bien el contenedor es doble, la deducción de tipo es int
debido al argumento inicial que se pasó a std::accumulate
. Por lo tanto, al contenedor se le asignan valores int
.
Considere el siguiente código para agregar todos los elementos de un vector
:
#include<iostream>
#include<algorithm>
#include<numeric>
#include<vector>
using namespace std;
int main(void)
{
std::vector<double> V;
V.push_back(1.2);
V.push_back(3.6);
V.push_back(5.6);
double sum = accumulate(V.begin(),V.end(),0);
cout << "The sum of the elements of the vector V is " << sum << endl;
return 0;
}
Cuando compilo esto en Cygwin en Windows y lo ejecuto, obtengo la salida en el terminal como
La suma de los elementos del vector V es 9.
La función de accumulate
parece estar redondeando todos los números y sumándolos, lo que explicaría la respuesta.
¿Es esto algo malo con el compilador Cygwin g ++, o mi interpretación errónea de la función de accumulate
para sumar un vector
de double
s?
El último argumento de la llamada std::accumulate
determina el tipo de la suma interna así como el tipo de retorno. Como 0
es un int
todo se redondea hacia abajo durante la suma, y el resultado también es un entero.
El valor que se devuelve de la función std :: baterías es un entero, no un doble debido a esto:
double sum = accumulate(V.begin(), V.end(), 0);
// ^-- Integer!
La inferencia de parámetros de plantilla realizada por el compilador de C ++ hace que el tipo de retorno de la función de accumulate
el mismo que el parámetro de init
, que en su caso es un entero. Por lo tanto, el valor de retorno se redondea al número entero más cercano. El valor de retorno se vuelve a convertir implícitamente en un doble cuando se asigna a la sum
.
Para solucionar esto, simplemente puede pasar el cero como un doble (es decir, 0.0
) en su lugar.
std::accumulate
se declara como tal:
template <typename InputIt, typename T>
T accumulate(InputIt first, InputIt last, T init);
El segundo argumento de plantilla para std::accumulate
se deduce como int
porque 0
es de tipo int
. Pase un doble en su lugar, como 0.0
.