News:

  • September 24, 2026, 05:02:03 AM

Login with username, password and session length

Author Topic: Comparisons Using Reals  (Read 9728 times)

RBPLC

  • Hero Member
  • *****
  • Posts: 586
Comparisons Using Reals
« on: April 21, 2020, 05:21:55 PM »
Is it possible for rounding/precision issues with floats to affect the evaluation of comparison contacts (such as Not-Equal-To Relational Contact)? I've got a != comparison contact comparing two reals. I'm having some "screwy" behavior that I'm having trouble tracking down but it seems like it might be related to using != with two reals. It looks like when evaluating .23333333 and .21666667 some "weird" things seem to happen. This also seems to happen when evaluating .11666667 and .4333333 as well. Just wondering if this could potentially be an issue.

BobO

  • Host Moderator
  • Hero Member
  • *****
  • Posts: 6176
  • Yes Pinky, Do-more will control the world!
Re: Comparisons Using Reals
« Reply #1 on: April 21, 2020, 07:16:36 PM »
Is it possible for rounding/precision issues with floats to affect the evaluation of comparison contacts (such as Not-Equal-To Relational Contact)? I've got a != comparison contact comparing two reals. I'm having some "screwy" behavior that I'm having trouble tracking down but it seems like it might be related to using != with two reals. It looks like when evaluating .23333333 and .21666667 some "weird" things seem to happen. This also seems to happen when evaluating .11666667 and .4333333 as well. Just wondering if this could potentially be an issue.

It shouldn't, but we'll look into it.
"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

franji1

  • Bit Weenie
  • Host Moderator
  • Hero Member
  • *****
  • Posts: 3847
    • Host Engineering
Re: Comparisons Using Reals
« Reply #2 on: April 22, 2020, 07:54:50 AM »
Best way to compare two reals is to take the absolute value of the difference and see if it is within a tolerance.

MATH C0 "ABS(R0 - R1) < 0.1"


ADC Product Engineer

  • Hero Member
  • *****
  • Posts: 270
Re: Comparisons Using Reals
« Reply #3 on: April 22, 2020, 07:59:12 AM »
It depends on the source.  If it is from analog, the values are likely to fluctuate and potentially be true even though the PLC display doesn't show it due to communications speed.

Good practice for such values is to use a deadband using a couple of comparisons to eliminate fluctuations or to do averaging to deaden the swing.

RBPLC

  • Hero Member
  • *****
  • Posts: 586
Re: Comparisons Using Reals
« Reply #4 on: April 22, 2020, 08:55:15 AM »
Thanks for the input. In this instance it's not analog input, it's a fractional conversion of seconds to minutes, e.g. seconds/60, hence the irrational numbers. It seems to be problematic with 14/60, 13/60 but 12/60 has no issue. Thanks for the recommendation franji, I was having a brain fart and trying to come up with some way to do something similar to what you suggested. My approach was going to be to ask you guys to extend the functionality of TRUNC(R0) to TRUNC(R0, #Digits) like is available in Excel. Your recommendation would work as well. I'm still curious if the floats are a potential issue as I'd like to file this away for "good programming practices".

franji1

  • Bit Weenie
  • Host Moderator
  • Hero Member
  • *****
  • Posts: 3847
    • Host Engineering
Re: Comparisons Using Reals
« Reply #5 on: April 22, 2020, 10:00:22 AM »
IEEE floating point is always an approximation of a number.  For example, it would take infinite memory to store 1/3 as a floating point number.  That is why when you do 30.0 * (1.0/3.0) it doesn't necessarily come out exactly 10.0 because of the "error" in the representation of 1.0/3.0 (for that expression, it's best to leave division last, so better to do (30.0 * 1.0) / 3.0 )

Unless it can be represented as a power of two (negative exponents) e.g. 1/4 1/8, it will always be an approximation.

In Computer Science, you learn about this and know to do the (ABS(delta) < epsilon) for numbers that are reasonably close relative to epsilon.  Note that it will NOT work if you have huge numbers and want to see if they are within 0.1, e.g.

1,234,567.8 vs 1,234,567.9 because 32 bit IEEE cannot get to within 0.1 with that many digits.

What is the range of your real numbers?  What is a good-enough value your "epsilon"?  (not too small, not too big).