CltOff Posted October 29, 2010 Report Posted October 29, 2010 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
External Moderators tmoulder Posted October 29, 2010 External Moderators Report Posted October 29, 2010 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
CltOff Posted October 29, 2010 Author Report Posted October 29, 2010 I've used [] instead () because if I use B with ) it becomes an emoticon 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
Phil Salkie Posted October 29, 2010 Report Posted October 29, 2010 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.
Damian Posted October 29, 2010 Report Posted October 29, 2010 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.
CltOff Posted October 31, 2010 Author Report Posted October 31, 2010 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
Phil Salkie Posted November 1, 2010 Report Posted November 1, 2010 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.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now