Structured text math data types

ASF

Lifetime Supporting Member
Join Date
Jun 2012
Location
Australia
Posts
3,921
I have an expression in a structured text routine of a Logix controller that looks more or less like the following:
Code:
ResultInteger := Integer1 * Integer 2 * Integer 3 / (Integer4 / Integer5);
As you might infer, all of the variables are DINT data types. The value of the complete calculation will always be a number in the thousands, and decimal accuracy is not important, so I have no problem with the final answer being truncated, rounded, or whatever else a PLC might conceivably do with a non-integer.

What I'm concerned about is that Integer5 will always be larger than Integer4, meaning that the first part of the calculation to be executed - Integer4 / Integer5 - will always result in a number less than 1. If the PLC truncates that (or rounds it, for that matter) before performing the rest of the multiplication steps, my result will invariably be zero. However, if the PLC performs the calculation as a floating point and just truncates/rounds it at the end, everything will work as intended.

Can anyone point me to the relevant section of documentation to understand how calculations like this will be performed?
 
Have you ever head of a zero division?
Make sure (Integer4 / Integer5) is not zero, and use a floating point data type for the whole calculation. Round it in the end if mantissa is not needed.
 
None of the values in this calculation can ever be zero.

I'll use floating point if I have to, but I'd like to know if I have to.
 
You say that the calculation doest work (always results in zero), shouldnt that indicate that you need floating point?
Otherwise do the calculation in steps and and check where it fails.
 
Can anyone point me to the relevant section of documentation to understand how calculations like this will be performed?
Without knowing the exact PLC make and model are in play, no one can point you to the documentation; there is the Logix manual here (non- @OkiePC-safe link), and you can search for round and truncat). There is the also IEC-61131 standard, in which the behavior of integer division may be covered, but that does not guarantee your PLC is compliant with that part of the standard. The best result will come from an empirical approach: characterize the behavior by passing integers of various values to the PLC itself and see how the expression behaves (N.B. this may cause processor faults and PLC halts).

Sidebar

If none of the IntegerN values in that calculation can ever be 0, and Integer4 is always less than Integer 5, then only the parenthetical divisor (Integer4 / Integer5) can be 0, and the overall result is either non-zero or there is a divide-by-0 error.

The general practice in most computer programming languages is that a divide with two integers returns an integer result; the remainder is usually discarded and the result truncated, so if the Integer4 is less than Integer5, the parenthetical divisor would be 0, which would cause a divide-by-0 in the overall expression. Some PLCs will round the result (e.g. RSLogix 500), but if Integer4 is less than half of Integer5, the parenthetical divisor would still be 0.

Although it will produce a different result in practice, these is arithmetically equivalent:
Code:
ResultInteger := (Integer1 * Integer2 * Integer3  * Integer5 ) / Integer4;

ResultInteger := Integer1 * Integer2 * Integer3  * (Integer5  / Integer4);
and does not have the divide-by-zero if Integer4 is either smaller than either Integer5 or smaller than half of Integer5 (depending on the PLC), but the term in parentheses in the first option may overflow; even the second option could have an overflow.

If the ranges of those integers are known, it is possible the expression can be rearranged to eliminate overflow and still provide a decent value.

All of those caveats are why converting each argument to floating-point, and then converting the result back to integer, is likely the best solution.
 
None of the values in this calculation can ever be zero.

I'll use floating point if I have to, but I'd like to know if I have to.
If Integer5 is twice as big as Integer4, the result of Integer4/Integer5 will be rounded to zero.
Every part of the equation will be calculated with integer rounding and truncating.
You should probably convert the integers REALs, perform the calculation with floating point math, and convert the result back to Integer at the end.
Notice that REALs also have limitations. Study the data types, and understand how to chose and work with them.
 
Although it will produce a different result in practice, these is arithmetically equivalent:
Code:
ResultInteger := (Integer1 * Integer2 * Integer3  * Integer5 ) / Integer4;

ResultInteger := Integer1 * Integer2 * Integer3  * (Integer5  / Integer4);
and does not have the divide-by-zero if Integer4 is either smaller than either Integer5 or smaller than half of Integer5 (depending on the PLC), but the term in parentheses in the first option may overflow; even the second option could have an overflow.
Good explanation. Both variants have the advantages and pitfalls. Multiplying 4 integers risks an overflow.
Using floating point math avoids the most obvious pitfalls, but is still possible to fail if used without understanding.
 
Have you ever head of a zero division?
Make sure (Integer4 / Integer5) is not zero, and use a floating point data type for the whole calculation. Round it in the end if mantissa is not needed.

agreed would always check Int4 is not zero its belt and braces so may programs have issues when a value like that becomes Zero.
 
I agree that it is better to do all the multiplications first and lastly the division and I also say that you have to carefully study the maximum values involved to avoid overflow (or underflow, if they are signed integers)

Also if it is a repetitive calculation, for example, calculating the increment or decrement to apply to something, you can also save the remanider of the division and add it previously in the next repetition division, this achieves great precision.
 
Thanks all. I'm across the general complexity of integer vs floating point calculations, and the strengths/limitations/pitfalls of each. I've gone down this rabbit hole in ladder logic, working out how all of this operates in a CPT instruction, but I've not done a lot with ST previously. I don't have the PLC on hand to test with yet and when I do I will be under time pressure so I was hoping I could at least learn the theory first.

The manual posted by @drbitboy doesn't specify either; it just makes one vague mention of "You can mix data types, but loss of accuracy and rounding error might occur". Not especially helpful - I know that it might occur, that's why I'm here, to find out where the rounding might occur.

If anyone has a Logix PLC on hand and has nothing better to do, I'd be interested to see the results of each of the following calculations:

Code:
RealResult = Integer1 * Integer2 / (Integer3 / Integer4);
IntResult = Integer1 * Integer2 / (Real3 / Integer4);
IntResult = Integer1 * Integer2 / (Integer3 / Real4);
IntResult = Integer1 * Integer2 / (Real3 / Real4);
IntResult = Real1 * Real2 / (Real3 / Real4);
RealResult = Real1 * Real2 / (Real3 / Real4);

P.S. Accuracy is of little importance in this calculation. The result will be somewhere in the range of 1000-6000, and an accuracy of +/-5 wouldn't be the end of the world. All of the inputs to the calculation are based on guesswork and speculation anyway.
 
Memory is cheap in Logix. Do a proper float calculation for maximum accuracy and conver the final product to a DINT.
 
Other more IEC compliant PLCs may offer more explicitly specified data types for various operations. This appears to be an extra level of complication since you might find several versions of an ADD instruction - int, uint, dint, udint, real, and so on. Type conversion instructions are used to specify what happens when mixing types.

The Schneider compiler has a settable option that gives you more latitude to slop the types without as many conversions. I always leave it off since I'm obsessed about precisely specifying types and how the operations work.

One of the characteristics of the ADA programming language that the military used to emphasize was a tremendous emphasis on data types. It 'took an act of Congress' to put in a CAST type conversion. The success of ADA may be debated - but it showed that some people placed a great deal of confidence in the value of strict type declaration. JavaScript seems to go the other way...

One of my complaints with AB stuff is the lack of strong data typing requirements. This may be a classic 'two-ditch' issue with Schneider being too tight and AB being too loose. I guess you decide what part of the road you want to drive on. I work with both platforms and I avoid the AB CPT instruction.
- - - - -
The June 1996 Ariane 5 rocket explosion comes up during discussions on data type capacities. The Feb 25, 1991 Patriot missile failure comes up during discussions of using the right data type for the job - don't count into a real! And don't assume that reals can solve all numeric problems ...
 
The thing to remember is if any divide instruction has a zero as the divisor it will fall over, so it wwould be better to use floats then convert the final figure to a integer/Dinteger, also just as a belt & braces I would split the calculation into the two & do a zero check as maybe not for sometime but it may happen mud on your face if you get a call 6 months or even years down the line in the middle of the night with a message saying the PLC has a flashing red light, seen this a few times, making your code look pretty has little concequence if it falls over.
 
The precision of a 32-bit float is approximately 7 significant decimal digits, any operation that does not affect those digits will have no effect, for example adding 1 to 10,000,000.

But for the proposed multiplications and divisions I think it is good to use floats.
 

Similar Topics

Hello, I am using studio 5000 pro and am trying to figure out the structured text. Here's my scenario: An operator scans a barcode, the barcode...
Replies
15
Views
255
Good evening. I display the step number of a SFC on a display. Sometimes, on a trip, it goes quickly through many steps and I need to prove to...
Replies
1
Views
134
I am trying to set up a piece of equipment with a Horner HE-X4R. I'd like to use structured text and so far I'm just trying to get a basic On/off...
Replies
0
Views
72
Good morning. I'm doing a rehab and I need to recycle some part of the old code that won't change and that I need. This is a calculation that...
Replies
22
Views
1,372
I'm writing some structured text that's handling a data structure that comes from a PC. The PC structure is in the "new" LREAL 64-bit floating...
Replies
3
Views
494
Back
Top Bottom