環境:VS 2013,升壓1.58的boost ::蓄電池:: rolling_mean返回不正確平均值
我寫的東西,提出了一個更友好的界面來提高的蓄能器,它可以用來預測在一個總和窗口,並計算窗口上的實際滾動平均值。在推進到VS 2013作爲我們的主編譯器時,這個類的單元測試之一開始失敗。剝離層,我已經將範圍縮小到這個最小例如:
#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";
}
}
在循環的最後一傳,我沒有得到預期的平均值(1.5),而是得到一個瘋狂的高值(1431655766.333333)。
此代碼在VS 2008中以Boost 1.49正確執行(顯然,C++ 11矢量初始化被替換),但在VS 2012和VS 2013中失敗且升級1.58。我無法解釋這種失敗,因此無法解決這個問題。
其它有趣的點:
- 手動檢查存儲器內的值累加器揭示了正確的數據被包含在它的循環緩衝器。
- 如果放入累加器的數據按遞增值排序,那麼rolling_mean將是正確的。
- 一旦窗口已滿,如果任何新元素小於它從窗口中敲出的數字,那麼rolling_mean將不正確。如果它相同或更大,rolling_mean將是正確的。
它似乎是一個Boost錯誤,但是想要在報告錯誤或嘗試構建Boost 1.59之前驗證我沒有做什麼愚蠢的事情。提前致謝!
編輯:感謝您的迴應,因爲這看起來似乎是一個助推器的錯誤。相關的Boost票據是here.。這是一個與帶累加器的無符號整數有關的問題。具體來說,如果窗口已滿後添加到累加器的值嚴格小於窗口中的所有值,那麼rolling_mean調用將返回無效結果。
有一種解決方法,即不使用無符號整數與累加器。這解決了我的問題,所以感謝您的幫助!
看看你的位模式:它是ccccccccc/4。再加上一點。這是未初始化的堆棧內存。調試升壓代碼,直到看到一個cccccccc讀取也許。 – Yakk
我剛和一位同事討論這個問題。謝謝你的提示!我會看看它。 – iamtheddrman
下面是一個大大簡化的樣本,展示了GCC(4.8-5.2)的問題:** [Live On Coliru](http://coliru.stacked-crooked.com/a/1fb8265aaac32e12)** – sehe