I'm trying to calculate a rolling average, and to try and get and optimize a bit, I've simplified the calculation so there is only one division. When the value is decreasing, there is a point where the current value is lowered to less than the average. At this point the average jumps. I imagine this is because the division is unsigned, and my numerator's sign bit is interpreted as a massive unsigned number. I am just not sure where I need to cast unsigned to insure this problem doesn't reappear.
unsigned int AverageUsage;
unsigned int TotalUsage;
unsigned int incCount;
AverageUsage = (TotalUsage - AverageUsage)/++incCount + AverageUsage;
AverageUsage will always be positive, but when TotalUsage drops below AverageUsage, I'm not sure what to expect with the division
AverageUsage = (signed int)(TotalUsage - AverageUsage)/++incCount + AverageUsage;
Will set the numerator to signed, but I am not sure how the division will occur.
AverageUsage = (signed int)((signed int)(TotalUsage - AverageUsage)/++incCount) + AverageUsage;
Should work (I can guarantee the result of this full operation will never be negative), but I am worried about cases when incCount reaches a value that 'looks' negative.
Is there a simple solution to this that hopefully:
Thanks!
You have 2 options.
Use Floating Point Math
I think you want to do this to get a proper average anyway.
There is no such thing as a mixed floating/integer divide. So, both numerator and denominator will be converted to a floating point.
Whether the numerator or denominator is signed or unsigned then doesn't matter. There is no such thing as unsigned floating point. The denominator incCount will be converted to a floating point and full floating point division will be done.
Use Integer division and handle the special cases
If for some reason you want to stay with integer division, then both the numerator and denominator have to be the same signed/unsigned type.
Both Numerator/Denominator are signed
incCount will be converted to a signed number. If it is too large then it will look like a negative number and your answer will be wrong. You have to test for this overflow.
Both Numerator/Denominator are unsigned
You have to make the numerator unsigned and use a if () statement to handle the two cases: TotalUsage < AverageUsage
and TotalUsage > AverageUsage
. Here incCount can use the full range of integer bits since it will be treated as an unsigned number.