Bad Math Formula solved
This line gives unexpected results:
I can get the desired relsults using this
Any insights?
dataAverage := ((dataAverage+DataIn)/b)
I can get the desired relsults using this
temp :=((temp + DataIn) )
dataAverage := (temp/b)
Any insights?
CON _CLKMODE = XTAL1 + PLL16X _XINFREQ = 5_000_000 OBJ serial: "fullduplexserial" ' Communication to Parallax Serial Terminal Var word DataIn word temp word DataAverage word b pub DataAveraging serial.Start(31,30,0, 9600) waitcnt((clkfreq*4) +cnt) 'Time to start up the terminal. b:=1 temp:= 0 DataIn:=7 DataAverage:= 0 repeat while b < 11 'dataAverage := ((dataAverage+DataIn)/b) ' Bad Math Formula temp :=((temp + DataIn) ) ' working formula. dataAverage := (temp/b) ' working formula. serial.dec(b) 'b value sent to the terminal. serial.str(string(" ")) 'Space sent to the terminal. serial.dec( DataAverage) 'DataAverage sent to the terminal. serial.str(string(" ")) 'Space sent to the terminal. serial.dec( DataIn) 'DataIn sent to the terminal. serial.str(string(" ")) 'Space sent to the terminal. serial.tx(13) ' New line waitcnt((clkfreq/2) +cnt) b:=b+1
Comments
But, you might have better luck with variables defined as "long" instead of "word".
I think most things run better as long. I only use words for big arrays of things to save space...
The first loop dataAverage (DA) would equal 7 using the first equation, The second time through the loop would it would also equal 7, but the third time through the loop DA would equal 4 ((7+7)/3).
Your second method of finding the average doesn't have this problem.
Sometimes the intermediate values in an expression will be too small to represent properly as a single expression and you need to rewrite the expression to maintain precision in the intermediate variables.
Often times it's easier to read and enforce a particular evaluation order by breaking the expression up into multiple lines. In SPIN, what you see is what you get, there is no trick optimization to get in the way,
however in C you can run into optimizations that will break how an expression is evaluated unless you break it into multiple expressions that are evaluated in a specific order.
I thought I knew basic algebra.
Here is how I thought it was going to go.
I renamed the values in the formula for an easier discussion.
X starts at zero and C starts at 1.
Repeat the following
X=(X+7)/C
C = C+1
Loop back
This is what I thought was going to happen.
The first time through, x=7 because: of this equation… . X=(0+7)/1. Not this x=(0/1 + 7/1)
The second time through, x=7 because: of this equation…. X=(7+7)/2. Not this x=(7/2 + 7/2)
The third time through, x=7 because: of this equation… . X=(14+7)/3. Not this x=(14/3 + 7/3)
The fourth time through, x=7 because: of this equation… . X=(21+7)/4. Not this x=(21/3 + 7/4)
This would certainly take in to account the unexpected results I saw.
I did read that section in the manual (a few times). In my manual (version 1.0), that chapter is on page 252. It is the same text.
I still don't see where the parenthesis have a lower precedent compared to of an addition or subtraction operation.
Any how... it is what it is.
Is there a way to write " X=(X+7)/C " in one line?
X is suppose to equal the summation of "X+7" before dividing by C.
I see in an earlier post I switched to "Z" as the divider. I will edit that post.
The loop producing the following results.
x=(0+7)/1 = 7
x=(7+7)/2 = 7
x=(7+7)/3 = 4
x=(4+7)/4 = 2
x=(2+7)/5 = 1
This will produce the expected results from post #5
If you are trying to do an average with and unknown number of samples then you must accumulate the the total in x and divid by the number of iterations. If you know the number of samples the math is
x += s/#ofSamples
Be careful with the later equation. This is integer based math - so - x must be significantly larger than #ofSamples. If x is close in value to #ofSamples then multiply x buy some value 10^y.
Yes, I seem to have a logic problem.
Oh well, I'll get over it.
But until then....
x=(1+7)/1 = 7. x evaluates correctly (in my mind).
x=(7+7)/2 = 14. x evaluates correctly (in my mind). Again.
x=(7+7)/3 = 4. but why is this not (14+7)?
x=(4+7)/4 = 2. can see where the 4+7 came from , because the previous result was 4.
x=(2+7)/5 = 1. I can see where the 2+7 came from , because the previous result was 2.
I'll look at the loop again and try seeing it differently.
Mike just made a few math errors (or typos) while explaining your logic error. I wonder what kind of error I'm making as I explain this?
Again, I really do appreciate your input.
Very best regards.
avg = (avg + sample) / samples
avg = (0 + 10) / 1 = 10
avg = (10 + 10) / 2 = 10
avg = (10 + 10) / 3 = 6.67?
John Abshier
An average can be simple:
a = (a+b) / 2
or weighted:
a = ((a * c) + b) / (c + 1)
Breaking it down for larger values of a or c:
a = a * c
a = a + b
a = a / (c+1)
The weighted average has the advantage that outliers won't dramatically change the averaged value, so the average represents data over c samples.
The simple average has the advantage that it doesn't require much arithmetic or large variable sizes:
add a, b
shr a,#1
Generally the third answer would be 6 because we usually are working with integer numbers.
OK, we could use a floating point object and get 6.66666....
Or using integer math avg = (10 + 10) * 1000/ 3 = 666
Duane J