Jump to content
Sign in to follow this  
CltOff

"Formula" intermediate calculation

Recommended Posts

Hi to everybody,

I'm using this banal formula Y=A*[100 - B]/100

where A and B are MI

A goes from 0 to 4095 (MI is perfect)

B goes from 0 to 100 (MI is perfect again)

Y goes from 0 to A (MI...)

all seems to be coherent with the use of MI, but is it true?

In other terms: if I look at the intermediate calculation I find an A*[100 - B] that in case of (for example)

A=4000 and B = 0 will have a result equal to 400.000 that isn't compatible with an MI.

My question is: when I use formula, have I to take account of the intermediate calculations?

tks

CltOff

Share this post


Link to post
Share on other sites

I'm not sure I understand what you mean by "intermediate"? The formula block follows standard algebraic order of operations, so anything in () is processed first.

Are you actually using [] instead of () in your formula? I didn't think you could do that. If so, try using () and see if it corrects.

Thanks,

TM

Share this post


Link to post
Share on other sites

I've used [] instead () because if I use B with ) it becomes an emoticon B)

when I speak about intermediate calculations, I intend the calculation done inside the PLC.

I've read a post in wich Phil Salkie said that all internal calculation about formulas are done using 32bit. If this is true the problem I've posted isn't really a problem...

CltOff

Share this post


Link to post
Share on other sites

If I may rephrase the question: "Are the internal calculations of a FORMULA block performed in 16 bit integers, 32 bit integers, or floating point?"

The answer would appear to be "That depends" (I've tested this on the V570, your results may vary). If no floating point constants or variables are used, the internal calculations seem to be done with 32 bit integers. If a floating point constant or variable is used, then all internal calculations are done in floating point.

A=MI0

B=MI1

Result in MI2

The formula:

(A *  / 10000

(divide by ten thousand)

works properly throughout the 16 bit integer ranges of the MI sources, so long as the result will fit into a 16 bit integer.

A=ML0

B=ML1

Result in ML2

This formula:

(A *  / 10000000

(that's a divide by ten million)

will give incorrect results for A=1,000,000 and B=1000 because the intermediate result (10,000,000,000) is larger than a 32 bit integer.

However, this formula:

(A *  / 10000000.000001

(still effectively dividing by ten million, but forcing the calculations to floating point)

will give correct results with A=2,000,000,000 and B=10,000,000 (the end result being 2,000,000,000 and the intermediate being 2 * 10^16)

Oddly enough, the FORMULA block's parser interprets 10000000.0 as an integer, not a floating point, so I had to put that extra .000001 on the ten million in order to force a floating point calculation.

And, as always, check the ranges of your variables before doing a calculation - there doesn't seem to be any SB to tell your program that an integer calculation has gone out of range, so if you were to have a FORMULA block working in the integer range, and an intermediate calculation overflowed the internal 32-bit registers, your program would have no way to know, and it would basically be operating on a random result - that would be, at best, BAD.

Share this post


Link to post
Share on other sites

Hi to everybody,

I'm using this banal formula Y=A*[100 - B]/100

where A and B are MI

A goes from 0 to 4095 (MI is perfect)

B goes from 0 to 100 (MI is perfect again)

Y goes from 0 to A (MI...)

all seems to be coherent with the use of MI, but is it true?

In other terms: if I look at the intermediate calculation I find an A*[100 - B] that in case of (for example)

A=4000 and B = 0 will have a result equal to 400.000 that isn't compatible with an MI.

My question is: when I use formula, have I to take account of the intermediate calculations?

tks

CltOff

If I understand you correctly, I think the answer to your question is you will lose any precision after the decimal place.

To maintain the precision to the left of the decimal, take care to perform the division last.

Share this post


Link to post
Share on other sites

First of all tks for your answer.

So if I use MI variables inside a "Formula block" I haven't to take care of intermediate calculation (exept for overflow on 32bit) because they're done in 32bits and not in 16, and if I want max precision on integer part of the result I have to do the division at the end of calculation.

If I use ML I have to take care of intermediate possible overflow...

If I want the best result I've to force some MF -> calculation are done in MF -> overflow quite impossible... But in that case, if I'm using all the 25 MF available in the PLC, do I risk to loose some data?

CltOff

Share this post


Link to post
Share on other sites

So if I use MI variables inside a "Formula block" I haven't to take care of intermediate calculation (exept for overflow on 32bit) because they're done in 32bits and not in 16, and if I want max precision on integer part of the result I have to do the division at the end of calculation.

That's true of _any_ integer mathematics anywhere. For example, in the real number (infinite precision floating point) world, ((X / 10) * 10) = X, no question about that. However, in integer-only math, if X is 4, then (4 / 10) = 0, remainder 4. and 0 * 10 = 0, so your result is obviously not what you expected. If you reverse the order of operations, making intermediate results larger instead of smaller, then you would rephrase the formula as ((X * 10) / 10), X * 4 = 40, 40 / 10 = 4. This works until you overflow the internal 32-bit integers.

If I use ML I have to take care of intermediate possible overflow.

That's true of MI or ML - you always run the risk of an internal overflow with no warning - it's just easier to do if the sources are 32-bit integers.

If I want the best result I've to force some MF -> calculation are done in MF -> overflow quite impossible... But in that case, if I'm using all the 25 MF available in the PLC, do I risk to loose some data?

The internal calculations of the function block are not done in any of the 25 MF registers that are available to the PLC program, so your data is safe - similarly, the intermediate results of the 32 bit integer calculations are not done in any of the PLC's ML or DW registers. If you are using all the MF registers for other things, all you have to do is use some floating point constant in your formula - such as multiplying the result by 1.0000001 (since the formula parser doesn't recognize 1.0 as a floating point number.) in order to force the entire calculation into floating point - the sources and result can all be integers, but the calculation will take place in floating point.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...