Rounding Off in AB-Control logix PLC

You can move a REAL data type into a DINT data type using a MOV instruction and rounding will occur, but you need to be aware of how the Logix processor rounds the fractional part of a Floating Point value while converting to integer data types, or performing arithmetic operations on fractional Floating Point values.

For the Logix Platform, the REAL data type is of a 32 bit Single Precision Binary Floating Point format.

It consists of...

1 Sign bit (+/-) ¦ 8 exponent bits (whole number) ¦ 23 Mantissa bits (fractional part).

For any fractional part of Floating Point values above or below N.5 the Logix processor will round UP or DOWN accordingly. But for any fractional part equal to N.5 the Logix processor handles the rounding according to the default rounding method set out in the IEEE Standard for Floating Point Arithmetic (IEEE 754). This rounding method is simply known as "Round half to even", but has been called many things such as "Unbiased Rounding", "Gaussian Rounding" and even "Broken Rounding".

If a Floating Point value has a N.5 fractional part, then the Logix processor will always round to the nearest EVEN number. This means that for an N.5 fractional part the rounding is dependent on the whether the N.X value is ODD or EVEN to begin with. This is very important to remember as normally one might expect an N.5 fractional part to always round UP to the nearest WHOLE number.

If a Floating Point value has any other fractional part besides N.5, such as N.2, N.8, N.45, etc., then the Logix processor will always round to the nearest WHOLE number, whether UP or DOWN, ODD or EVEN.

So...

Any Floating Point value of N.5 may round UP or DOWN to the nearest EVEN number depending on the WHOLE value being ODD or EVEN.

Any Floating Point value with a fractional part less than N.5 will always round DOWN to the nearest WHOLE number.

Any Floating Point value with a fractional part greater than N.5 will always round UP to the nearest WHOLE number.

Example 1: Move with N.5 fractional part

MOV REAL 123.5 > DINT = 124 <<<Nearest EVEN number (Rounds UP)
MOV REAL 124.5 > DINT = 124 <<<Nearest EVEN number (Rounds DOWN)

Example 2: Move with non N.5 fractional part

MOV REAL 123.6 > DINT = 124 <<<Nearest WHOLE number (Rounds UP)
MOV REAL 123.4 > DINT = 123 <<<Nearest WHOLE number (Rounds DOWN)
MOV REAL 123.45 > DINT = 123 <<<Nearest WHOLE number (Rounds DOWN)

Example 3: Move N.5 fractional part either side of zero

MOV REAL 0.5 > DINT = 0 <<<Nearest EVEN number (Rounds DOWN)
MOV REAL -0.5 > DINT = 0 <<<Nearest EVEN number (Rounds UP)

The same principles apply when performing arithmetic operations on Floating Point values and storing them in non REAL data types such as SINT, INT and DINT integers.

Example 4: Addition - WHOLE number is EVEN

ADD REAL 10 + CONSTANT 8.5 > DINT = 18 <<<Nearest EVEN number (Rounds DOWN)
ADD REAL 10 + CONSTANT 7.5 > DINT = 18 <<<Nearest EVEN number (Rounds UP)

Example 5: Addition - WHOLE number is ODD

ADD REAL 9 + CONSTANT 8.5 > DINT = 18 <<<Nearest EVEN number (Rounds UP)
ADD REAL 9 + CONSTANT 7.5 > DINT = 16 <<<Nearest EVEN number (Rounds DOWN)

These are just some examples of perhaps unexpected rounding results from performing move and arithmetic operations on Floating Point values while storing them in integer values.

If you specifically need to round in a particular way other than the default, such as always DOWN, you can use these Add On Instructions from Rockwell to select which rounding method to use...

55148 - Round Up and Round Down Add-On Instructions for RSLogix5000
Access Level: TechConnect

Regards,
George
 
Last edited:
JaxGTO said:
Simple solution is subtract 0.499999 from it and then move it to an integer.

Are you talking about using 0.499999 as a constant for the SUB instruction?

Yep, that's fine if you always want to round DOWN to the presented whole number, irrespective of lost accuracy. Some applications may need to ignore any fractional part of a value. So only whole units are ever used or operated upon.

But if accuracy does matter, to some degree, and you have say, 123.99?

Where might one prefer it to round to?

DOWN to 123 or UP to 124?

SUB REAL 123.99 - CONSTANT 0.499999 = REAL 123.490001

MOV REAL 123.490001 > DINT = 123 <<<Nearest WHOLE number (Rounds DOWN)

If your preference is to round N.99 values UP, then the above will not achieve this.

Whatever method one finds to achieve always rounding UP or always rounding DOWN, some degree of accuracy will always be lost. How much may, or may not have to be considered. The required application should obviously be a deciding factor in which way you swing it.

Just something to ponder.

Regards,
George
 
there is always the big hammer method of modulus divide the number, compare the remainder, round as appropriate

Little bit slower operation, but works if accuracy is desired. I have used modulus for similar operations in C and C#

Edit: TRN (truncate) is key in this operation
 
Last edited:
If constant updating is not needed make it in a sub-routine and only call it when a new number is available
 
Truncate is basically what happens in C when you're casting a float to an int so for rounding you add 0.5 so that anything less (or equal) than x.4999999 gets rounded down and anything above (or equal to) x.5 gets rounded up.
 
To round just move it into an integer then. The PLC will round it, but make sure the rules that AB uses are what you want.
 
The "Round all" AOI is useful because it outputs three separate results for you to select from...

Round Up
Round
Round Down

Round being the normal IEE 754 "Round half to even" method.

G.
 
TRN uses those crazy rules? That sucks. Truncate in anything I have ever used it just removes any decimal without evaluating its value. If it is evaluating the number it is removing it is performing some sort of rounding function then truncating, which to me defeats the purpose of having a truncate command

EDIT: I like having separate Round (round then truncate) and Truncate functionality, they both have their time and place.
 
Last edited:
dlweber said:
TRN uses those crazy rules? That sucks. Truncate in anything I have ever used it just removes any decimal without evaluating its value...

Have you used the TRN instruction in RSLogix 5000 before?
Have you viewed the Rounding AOIs linked above?

Removing the fractional part is exactly what, and all, the TRN does.

From the Help...

Truncate (TRN)
The TRN instruction removes (truncates) the fractional part of the Source and stores the result in the Destination.

The TRN instruction is used in the AOI's in conjunction with other instructions.

Regards,
George
 
No I have not used it in a Logix5000, we have 1 compatible processor in house and all I have done is minor adj to it.

I have read it in the help file that is why I used the name of that instruction.

I miss understood what you said



The TRN instruction is what is used in the AOIs I linked in my first post.

By saying that I thought you meant the TRN instruction used the rounding method that you listed above...now that that's cleared up the TRN instruction will work in the method of rounding I used above


Danatomega

Truncate is basically what happens in C when you're casting a float to an int

Yes that is typically how I would truncate in C.

For the rounding part instead of adding decimals I do a comparison on the modulus, based on that I would either add 1 to the truncated number or leave it alone. The processor I used for C was not a floating point processor so if I could get away with not messing with numbers smaller than 1 in decimal form I would.
 
Ah yes, ok. My statement was really to point out that we were both advocating the same thing, except perhaps you did not realize so, as you would have had to add and view the AOIs to see it being used. (y)

G.
 

Similar Topics

I have a Beckhoff PLC with many AI modules. Most devices are loop powered using the same +24 VDC power as the Beckhoff Bus Coupler and all is...
Replies
5
Views
668
So far so good, Almost done with this migration stuff Someone please help me on this one: ERROR IS: ''Bit and LSBit triggered alarms that used...
Replies
2
Views
1,699
Hi all,Is anyone able to help me with a method for rounding off a value following a division instruction. I am using Siemens S7 and plan to...
Replies
10
Views
3,384
Hi all, I'm connecting several 4-20mA sensors together in parallel (only one shown below) The enclosure is ABS plastic with metal backplate DAQ...
Replies
5
Views
274
I have Rhino 120 to 24 dc power supply and it has 2 Positive and 2 negative terminals on the DC side but no ground terminal. Should I connect one...
Replies
9
Views
435
Back
Top Bottom