Carol Wang | 9bbe602 | 2019-08-01 17:31:30 +0800 | [diff] [blame] | 1 | #include "average.hpp" |
| 2 | |
| 3 | #include <cassert> |
| 4 | |
| 5 | std::optional<Average::averageValue> |
| 6 | Average::getAverageValue(const Average::averageKey& sensorKey) const |
| 7 | { |
| 8 | const auto it = _previousAverageMap.find(sensorKey); |
| 9 | if (it == _previousAverageMap.end()) |
| 10 | { |
| 11 | return {}; |
| 12 | } |
| 13 | |
| 14 | return std::optional(it->second); |
| 15 | } |
| 16 | |
| 17 | void Average::setAverageValue(const Average::averageKey& sensorKey, |
| 18 | const Average::averageValue& sensorValue) |
| 19 | { |
| 20 | _previousAverageMap[sensorKey] = sensorValue; |
| 21 | } |
| 22 | |
Patrick Williams | 02e598a | 2024-08-16 15:21:23 -0400 | [diff] [blame] | 23 | std::optional<int64_t> |
| 24 | Average::calcAverage(int64_t preAverage, int64_t preInterval, |
| 25 | int64_t curAverage, int64_t curInterval) |
Carol Wang | 9bbe602 | 2019-08-01 17:31:30 +0800 | [diff] [blame] | 26 | { |
| 27 | int64_t value = 0; |
| 28 | // Estimate that the interval will overflow about 292471 |
| 29 | // years after it starts counting, so consider it won't |
| 30 | // overflow |
| 31 | int64_t delta = curInterval - preInterval; |
| 32 | |
| 33 | assert(delta >= 0); |
| 34 | // 0 means the delta interval is too short, the value of |
| 35 | // power*_average_interval is not changed yet |
| 36 | if (delta == 0) |
| 37 | { |
| 38 | return {}; |
| 39 | } |
| 40 | // Change formula (a2*i2-a1*i1)/(i2-i1) to be the |
| 41 | // following formula, to avoid multiplication overflow. |
| 42 | // (a2*i2-a1*i1)/(i2-i1) = |
| 43 | // (a2*(i1+delta)-a1*i1)/delta = |
| 44 | // (a2-a1)(i1/delta)+a2 |
Patrick Williams | 02e598a | 2024-08-16 15:21:23 -0400 | [diff] [blame] | 45 | value = |
| 46 | (curAverage - preAverage) * (static_cast<double>(preInterval) / delta) + |
| 47 | curAverage; |
Carol Wang | 9bbe602 | 2019-08-01 17:31:30 +0800 | [diff] [blame] | 48 | |
| 49 | return value; |
| 50 | } |