News:

  • August 25, 2026, 09:16:11 AM

Login with username, password and session length

Author Topic: Wierd Result AVGR  (Read 19410 times)

Dean

  • Sr. Member
  • ****
  • Posts: 73
Wierd Result AVGR
« on: April 03, 2017, 11:52:34 AM »
I have a set of sensor values I want to do a running average on. The Average Range function is returning an odd value. See attached image. I'm sure this is a simple one, but I think I've blinded myself to the forest by looking at too many trees.
10 Lather
20 Rinse
30 GOTO 10

ADC Product Engineer

  • Hero Member
  • *****
  • Posts: 270
Re: Wierd Result AVGR
« Reply #1 on: April 03, 2017, 12:15:25 PM »
Is ST132 on after your Average Math box is complete?

Dean

  • Sr. Member
  • ****
  • Posts: 73
Re: Wierd Result AVGR
« Reply #2 on: April 03, 2017, 12:28:48 PM »
Is ST132 on after your Average Math box is complete?

No. See attached.
10 Lather
20 Rinse
30 GOTO 10

Controls Guy

  • Internal Dev
  • Hero Member
  • ****
  • Posts: 3626
  • Darth Ladder
Re: Wierd Result AVGR
« Reply #3 on: April 03, 2017, 12:43:12 PM »
I think you were on the right track, ADC PE.  As soon as the total exceeds 2^31, the real answer starts coming out negative.  Evidently, it's doing the sum of D's before promoting the answer to real and overflowing, ST132 or no ST132.  Not sure whether it's promoting before or after the division.  Use R's rather than D's for the range of variables and it will work OK.
I retract my earlier statement that half of all politicians are crooks.  Half of all politicians are NOT crooks.  There.

BobO

  • Host Moderator
  • Hero Member
  • *****
  • Posts: 6172
  • Yes Pinky, Do-more will control the world!
Re: Wierd Result AVGR
« Reply #4 on: April 03, 2017, 12:52:10 PM »
Out of range isn't set for an integer overflow. It is used for parameters that are functionally unusable, like trying to take the square root of a negative number.

All of the range instructions use the underlying data type to do the basic work, so if using D you will be doing integer math. The promotion happens on the final assignment. So yes, the answer is to store as float and do the AVGR on float types.
"It has recently come to our attention that users spend 95% of their time using 5% of the available features. That might be relevant." -BobO

Dean

  • Sr. Member
  • ****
  • Posts: 73
Re: Wierd Result AVGR
« Reply #5 on: April 03, 2017, 01:05:44 PM »
I never thought about the limits of the data type as it relates to the instruction. Thanks.
10 Lather
20 Rinse
30 GOTO 10

Controls Guy

  • Internal Dev
  • Hero Member
  • ****
  • Posts: 3626
  • Darth Ladder
Re: Wierd Result AVGR
« Reply #6 on: April 03, 2017, 01:46:10 PM »
All of the range instructions use the underlying data type to do the basic work, so if using D you will be doing integer math.

[Hides face in shame]  My brain slipped into DLX mode (where dedicated instructions for reals end in "R") and interpreted AVGR as the "real version of the AVG instruction", as opposed to "Range" and wondered why it didn't do the promotion first!   :D
I retract my earlier statement that half of all politicians are crooks.  Half of all politicians are NOT crooks.  There.

Evilbeard

  • Hero Member
  • *****
  • Posts: 160
Re: Wierd Result AVGR
« Reply #7 on: April 04, 2017, 07:50:42 AM »
Out of range isn't set for an integer overflow. It is used for parameters that are functionally unusable, like trying to take the square root of a negative number.

All of the range instructions use the underlying data type to do the basic work, so if using D you will be doing integer math. The promotion happens on the final assignment. So yes, the answer is to store as float and do the AVGR on float types.

I was doing some simulation on the code you posted the other day about storing information in a ring buffer. Doing it with a math box, I noticed the same thing. I made a set of math boxes to generate RandInt() for FirstFootage0-31. I was using:

FirstMonth[$Now.Month] = SumifNE(0,FirstFootage0,31) / TOREAL(CountifNE(0,FirstFootage0,31))

I was getting negative results. The code block FirstMonth is Real. FirstFootage is a signed DW. Do I need to convert FirstFootage to real?

franji1

  • Bit Weenie
  • Host Moderator
  • Hero Member
  • *****
  • Posts: 3843
    • Host Engineering
Re: Wierd Result AVGR
« Reply #8 on: April 04, 2017, 09:04:53 AM »
RandInt generates numbers between 0 and 2billion.  This is a rare range of values in a typical PLC system.

We utilize 32 bit integer math all the time in Do-more Designer's C++ code.  We rarely use double or float or 64 bit integers (but sometimes they are needed when calculation range exceeds 2 billion).

If you have 31 values, if they are mostly in the range 0..1,000,000, adding them up gets you 31,000,000 - nowhere close to the "overflow" integer range of 2,147,483,647‬.  Not sure what you measure in a PLC that equals 1,000,000, but that is rare.  Hence, you can/should use integer arithmetic for most of your summing calculations.

HOWEVER, you do need to be aware of this limitation, because sometimes you ARE summing up or doing integer math on large values (long time values in milliseconds, large raw encoder values, et. al.), then you do need to convert to REAL.  Also, if you are adding up 10,000 values all around 1,000,000 then you WILL exceed 2billion.

Note that REALs are also limited to 32 bits, but they provide wider range of values, but sometimes with less accuracy than integers.  You have 24 bits of significant digits in a REAL, which is around 7 significant digits in decimal.  So you can have approximate numbers like 1,234,567,000,000,000,000,000 or like 0.0000000000000001234567, but you cannot differentiate between numbers like 2,147,483,647 and 2,147,483,646 (nearly 10 significant digits) which you can have in a 32 bit integer.

Just ball park your guestimate of the calculation.  If it gets close or over 2billion, you probably need to consider using REAL.  If it stays below that (e.g. 31 values worst-case being around 1 million), you can stick with 32 bit integer to get the speed and accuracy of integer math.

Evilbeard

  • Hero Member
  • *****
  • Posts: 160
Re: Wierd Result AVGR
« Reply #9 on: April 04, 2017, 09:09:00 AM »
RandInt generates numbers between 0 and 2billion.  This is a rare range of values in a typical PLC system.

We utilize 32 bit integer math all the time in Do-more Designer's C++ code.  We rarely use double or float or 64 bit integers (but sometimes they are needed when calculation range exceeds 2 billion).

If you have 31 values, if they are mostly in the range 0..1,000,000, adding them up gets you 31,000,000 - nowhere close to the "overflow" integer range of 2,147,483,647‬.  Not sure what you measure in a PLC that equals 1,000,000, but that is rare.  Hence, you can/should use integer arithmetic for most of your summing calculations.

HOWEVER, you do need to be aware of this limitation, because sometimes you ARE summing up or doing integer math on large values (long time values in milliseconds, large raw encoder values, et. al.), then you do need to convert to REAL.  Also, if you are adding up 10,000 values all around 1,000,000 then you WILL exceed 2billion.

Note that REALs are also limited to 32 bits, but they provide wider range of values, but sometimes with less accuracy than integers.  You have 24 bits of significant digits in a REAL, which is around 7 significant digits in decimal.  So you can have approximate numbers like 1,234,567,000,000,000,000,000 or like 0.0000000000000001234567, but you cannot differentiate between numbers like 2,147,483,647 and 2,147,483,646 (nearly 10 significant digits) which you can have in a 32 bit integer.

Just ball park your guestimate of the calculation.  If it gets close or over 2billion, you probably need to consider using REAL.  If it stays below that (e.g. 31 values worst-case being around 1 million), you can stick with 32 bit integer to get the speed and accuracy of integer math.

Generally, my numbers will be around 100,000 to 150,000, and it'll run 20-24 days of that 31 days. So I'm looking at a much smaller number. I was just putting a simulation together and using random values to test the calculations and what happens when it rolls from one month to the next, etc. I noticed it gave me negative numbers, and I saw this topic and wondered if those two situations were related.

franji1

  • Bit Weenie
  • Host Moderator
  • Hero Member
  • *****
  • Posts: 3843
    • Host Engineering
Re: Wierd Result AVGR
« Reply #10 on: April 04, 2017, 09:12:03 AM »
My brain slipped into DLX mode

That never happens here, NOT!  ;)

franji1

  • Bit Weenie
  • Host Moderator
  • Hero Member
  • *****
  • Posts: 3843
    • Host Engineering
Re: Wierd Result AVGR
« Reply #11 on: April 04, 2017, 09:20:04 AM »
Generally, my numbers will be around 100,000 to 150,000, and it'll run 20-24 days of that 31 days. So I'm looking at a much smaller number.

Yes, so you can use integer math.  RandInt gave you values between 0 and 2 billion, ten thousand times larger than your actual values. 

One way to get a good range of "random" values is to use RandReal(), which gives you a random real between 0.0 and 1.0.  So, something like
TOINT(RandReal() * 150000)
in your MATH expression will give you random integers between 0 and 150,000.

Or for more typical data points, something like
100000 + TOINT(RandReal() * 75000)
will give you random numbers between 100,000 and 175,000

RandReal(), which generates a uniform distribution between 0.0 and 1.0, is used a lot for simulation.