Environment: VS 2013, Boost 1.58
I wrote something that is a friendlier interface for the Boost battery, which you can use to create a sum over the window, and calculate the actual moving average of the window. While clicking to switch to VS 2013 as the main compiler, one of the unit tests for this class started to fail. Exfoliating the layers, I narrowed it down to this minimal example:
#include <boost/accumulators/accumulators.hpp> #include <boost/accumulators/statistics.hpp> #include <boost/accumulators/statistics/rolling_mean.hpp> namespace ba = boost::accumulators; namespace bt = ba::tag; typedef ba::accumulator_set < uint32_t, ba::stats <bt::rolling_mean > > MeanAccumulator; int main() { MeanAccumulator acc(bt::rolling_window::window_size = 5u); for (uint32_t i : { 3, 2, 1, 0 }) { acc(i); std::cout << i << " actualMean: " << std::fixed << boost::accumulators::rolling_mean(acc) << "\n"; } }
On the last pass of the cycle, I don't get the expected average value (1.5), but instead get a crazy high value (1431655766.333333).
This code runs correctly in VS 2008 with Boost 1.49 (with the initialization of the C ++ 11 vector, obviously), but with an error in VS 2012 and VS 2013 with Boost 1.58. I find it difficult to explain this error and, therefore, cannot fix it.
Other interesting points:
- Manually checking the memory values ββinside the battery shows that its ring buffer contains the correct data.
- If the data stored in the drive is ordered in increasing order, the roll_mean value will be correct.
- As soon as the window is filled, if any new element is less than the number that it knocks out of the window, the roll_mean value will be incorrect. If it is equal to or greater, the roll_mean value will be correct.
This seems to be a Boost bug, but I wanted to check that I wasnβt doing something stupid before reporting an error or trying to create Boost 1.59. Thanks in advance!
EDIT: Thanks for the answers as this seems like a Boost bug. The related Boost ticket is here. . This is an unsigned integer problem with batteries. In particular, if the value added to the drive after the window is full is strictly less than all the values ββin the window, the roll_mean call will return an incorrect result.
There is a workaround that should not use unsigned integers with batteries. This solves my problem, so thanks for the help!