double numbers[ ] = { 1, 0.5 ,0.333333 ,0.25 ,0.2, 0.166667, 0.142857, 0.125,
0.111111, 0.1 } ;
std::vector<double> doublenumbers ( numbers , numbers + 10 ) ;
std::cout << std::accumulate ( doublenumbers.begin( ) , doublenumbers.end( ) , 0 ) ;
Run Code Online (Sandbox Code Playgroud)
这产生1,这显然是错误的.有什么解释吗?
Ara*_*raK 59
你应该写下面的内容:
std::cout <<
std::accumulate ( doublenumbers.begin( ) , doublenumbers.end( ) , 0.0 ) ;
Run Code Online (Sandbox Code Playgroud)
因为0的类型是int.
当std::accumulate使用第三个参数的类型进行实例化时int,则会转换总和的右侧.例如:
result += *iter;
// int += double
Run Code Online (Sandbox Code Playgroud)
这将强制转换double为int,而不是你想到的是相反的.
std::accumulate ( doublenumbers.begin( ) , doublenumbers.end( ) , .0 ) ;
Run Code Online (Sandbox Code Playgroud)
要么
std::accumulate ( doublenumbers.begin( ) , doublenumbers.end( ) , (double) 0 ) ;
Run Code Online (Sandbox Code Playgroud)
"accumulator"变量的类型是最后一个参数的类型std::accumulate.你提供0了一个参数 - 一个int文字 - 这意味着累加器将具有类型int."累积"在int累加器中完成(即int在每次单独求和后四舍五入)并产生int结果.在这种情况下,它显然是1.
std::accumulate将开始对作为第3个参数传递的类型进行求和,如果传递整数,则返回类型将为int。并在这种情况下隐式转换为double。
在C ++ 11和C ++ 14中,如果要防止缩小转换,可以使用direct-list-initialization创建一个对象:
double sum { std::accumulate(doublenumbers.begin(), doublenumbers.end(), 0) };
Run Code Online (Sandbox Code Playgroud)
然后,编译器会警告您说您正在尝试从int转换为double以及在哪一行转换。这样可以节省调试时间。您可以轻松地对其进行修复,以使其变得正确:
double sum { std::accumulate(doublenumbers.begin(), doublenumbers.end(), 0.0) };
Run Code Online (Sandbox Code Playgroud)