Skip to content

NDPluginTimeSeries: divide the averaged sum before narrowing, not after#596

Merged
MarkRivers merged 1 commit into
areaDetector:masterfrom
physwkim:fix/timeseries-average-narrowing
Jul 16, 2026
Merged

NDPluginTimeSeries: divide the averaged sum before narrowing, not after#596
MarkRivers merged 1 commit into
areaDetector:masterfrom
physwkim:fix/timeseries-average-narrowing

Conversation

@physwkim

Copy link
Copy Markdown
Contributor

(epicsType)averageStore_[signal]/numAveraged_ parses as ((epicsType)sum)/n — the double sum is truncated or wrapped to the narrow element type before the divide. With averaging on, three UInt8 samples of 200 sum to 600 → (epicsUInt8)600 == 8888/3 == 29 instead of 200. Parenthesize as (epicsType)(averageStore_[signal]/numAveraged_); float element types are unaffected. Proven with a driver reproducing the exact expression.

doTimeSeriesT() stored an averaged time-series point as

    pTimeCircular[...] = (epicsType)averageStore_[signal]/numAveraged_;

C++ precedence binds the cast tighter than the divide, so this evaluates
as ((epicsType)averageStore_[signal]) / numAveraged_. averageStore_ is a
double accumulator holding the SUM of numAveraged_ samples, so the sum is
truncated (and, for integer element types, wrapped) to the narrow element
type before the division ever happens.

For any integer signal with averaging enabled (numAveraged_ > 1) this
corrupts every averaged point once the running sum exceeds the element
type's range: three UInt8 samples of 200 sum to 600, which narrows to
(epicsUInt8)600 == 88, then 88 / 3 == 29 instead of 200.

Parenthesize as (epicsType)(averageStore_[signal]/numAveraged_) so the
double division runs at full precision and only the final average is
narrowed. Float element types were already correct and are unchanged.

Verified with a proof driver over the worked example: the old expression
yields 29, the parenthesized expression yields 200.
@MarkRivers
MarkRivers merged commit a3bd265 into areaDetector:master Jul 16, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants