Author Topic: Perplexed by puzzling parentheses pecualiarity  (Read 8381 times)

nealbert

  • Newbie
  • Posts: 20
  • I'm a llama!
    • View Profile
Perplexed by puzzling parentheses pecualiarity
« on: February 18, 2019, 03:26:21 PM »
I'm not sure if this is a bug or a feature, but I'll throw it out there for your consideration....

In my FMD88-10 I have a Custom Function that takes an incoming analog voltage, scales it and converts the voltage to a temperature.  The last step in my CF is to convert the temperature from degrees C to degrees F using the commonly known equation:

F = (C * (9/5)) +32

Great, right?  WRONG!  The unnecessary pair of parentheses around the "9/5" causes the TBasic to yield an incorrect answer.
At room temperature (25C), the above equation yields and answer that's 17F degrees low.  At a temperature of 200C, the answer is over 150F too low.

What I know is...
  • That the "()" around the "9/5" is unnecessary.  
  • That "F = (C * (9/5)) +32" is mathematically identical to "F = (C * 9/5) +32".
  • That with or without the "()", the above equations will yield the identical answers when calculated in a spreadsheet, with a hand calculator or using simple pencil and paper.
So, the question is... why does TBasic yield an incorrect answer when unnecessary "()" are there?  Shouldn't it just ignore them?

garysdickinson

  • Hero Member
  • Posts: 502
  • Old PLC Coder
    • View Profile
Re:Perplexed by puzzling parentheses pecualiarity
« Reply #1 on: February 19, 2019, 04:36:25 AM »
Integer math and operator precedence is the answer to your perplexity.

9 divided by 5 is 1 with integer math.

Your spreadsheet and your calculator are doing floating point math. 9 divided by 5 is 1.8 with floating point math.  That is why the results are different then when you use a spreadsheet or a calculator.

Operator precedence.  The parenthesis in your expression:

     F = (C * (9/5)) +32

Forces TBASIC to perform the 9/5 division first.  Remember that 9/5 is 1.  The next thing TBASIC does is multiply the value of C by 1. Then TBASIC adds 32 and finally will assign the results of the arithmetic expression to the variable F.

I do not know how smart TBASIC's expression parser is.  If it was really smart it would, at compile time, precompute that the division of the constant subexpression 9/5 to be 1 and not actually do a division at run time. If may, also, recognize that the multiplication of the variable C by 1 is always the value of C.  TBASIC could simplify your expression to this because this is exactly what you wrote:

  F = C +32
Rule #1 for integer math is to do all your additions and multiplications first.  Do your division last to preserve accuracy.

You might want to rethink how you are converting an ADC value to temperature in F.  if you need F go from ADC units directly to F.

I would used scaled integer values.

I would, also, oversample the ADC so that I are working with a 14 bit ADC value rather than the advertised 12 bit value.

Gary D*ckinson
« Last Edit: February 19, 2019, 02:45:06 PM by garysdickinson »

garysdickinson

  • Hero Member
  • Posts: 502
  • Old PLC Coder
    • View Profile
Re:Perplexed by puzzling parentheses pecualiarity
« Reply #2 on: February 20, 2019, 11:01:04 AM »
Neal,

I suggest that you try this equation to convert from C to F:

     F = (C * 9) / 5 + 32

That equation just forces the multiply before the division operation.  It gets you more accurate results when you are limited to integer math.

This is my spreadsheet results comparing doing the conversion with floating point vs. integer math:

C   F Float   F Integer   Error %
0   32.0           32           0.000
1   33.8           33           2.424
2   35.6           35           1.714
3   37.4           37           1.081
4   39.2           39           0.513
5   41.0           41           0.000
6   42.8           42           1.905
7   44.6           44           1.364
8   46.4           46           0.870
9   48.2           48           0.417
10 50.0           50           0.000

If you can tolerate the size of the errors then your are good to go!

Best regards,

Gary D* ckinson
« Last Edit: February 20, 2019, 11:55:48 AM by garysdickinson »

support

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3170
    • View Profile
    • Internet Programmable PLCs
Re:Perplexed by puzzling parentheses pecualiarity
« Reply #3 on: February 21, 2019, 12:16:14 PM »
Thanks Gary for the formula.

To increase precision you can use a fixed point format

F = C*90/5 + 320

The result will be expressed in 0.1 degree F.

E.g. C = 22 degree

F = 22*90/5 + 320 = 716  = 71.6 degree F.
Email: support@triplc.com
Tel: 1-877-TRI-PLCS

nealbert

  • Newbie
  • Posts: 20
  • I'm a llama!
    • View Profile
Re:Perplexed by puzzling parentheses pecualiarity
« Reply #4 on: March 06, 2019, 01:37:21 PM »
Gary, et al,

Thanks for the explanation.  I totally forgot I'm working with Integer math.

The conversion equation works fine without the extra parentheses and the client is happy now.

I'll keep in mind the methods you describe to increase accuracy.  I may need that some day.

Thanks again,
Neal Cooper

garysdickinson

  • Hero Member
  • Posts: 502
  • Old PLC Coder
    • View Profile
Re:Perplexed by puzzling parentheses pecualiarity
« Reply #5 on: March 07, 2019, 11:19:21 AM »
Neal,

I am glad that you were able to get the PLC firmware sorted out for your client.

Please feel free to contact me if you have questions with how to get the most out of these PLCs.  My email address is in my profile on the forum.

Thanks,

Gary D*ckinson