On 12 Mar, 2014, at 23:08 , Hal Murray <hmur...@megapathdsl.net> wrote: > b...@evoria.net said: >> In the moving averages I'm doing, I'm saving the last bit to be shifted out >> and if it's a 1 (i.e. 0.5) I increase the result by 1. > > That's just rounding up at an important place. It's probably a good idea, > but doesn't cover the area I was trying to point out. Let me try again... > > Suppose you are doing: > x_avg = x_avg + (x - x_avg) * a_avg; > > For exponential smoothing, a_avg will be a fraction. Let's pick a_avg to be > 1/8. That's a right shift by 3 bits. I don't think there is anything magic > about shifting, but that makes a particular case easy to spot and discuss. > > Suppose x_avg is 0 and x has been 0 for a while. Everything is stable. Now > change x to 2. (x - x_avg) is 2, the shift kicks it off the edge, so x_avg > doesn't change. (It went 2 bits off, so your round up doesn't catch it.) > The response to small steps is to ignore them.
Note that you can't do fixed-point computations exactly the same way you would do it in floating point, you often need to rearrange the equations a bit. You can usually find a rearrangement which provides equivalent results, however. Let's define an extra variable, x_sum, where x_avg = x_sum * a_avg; The equation above can then be rewritten in terms of x_sum, i.e. x_sum = x_sum * (1 - a_avg) + x; With an a_avg of 1/8 you'll instead be multiplying x_sum by 7, shifting it right 3 bits (you might want to round before the shift) and adding x. The new value of x_avg can be computed from the new value of x_sum with a shift (you might want to round that too), or you could pretend that x_sum is a fixed-point number with the decimal point 3 bits from the right. In either case x_sum carries enough bits that you don't lose precision. Dennis Ferguson _______________________________________________ time-nuts mailing list -- time-nuts@febo.com To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts and follow the instructions there.