RSLogix 5000 DINT

Source A - L55_4004_D17
Source B - L55_4004_AUXR13 (always 3.12)
Dest - L55_4004_D17

That is the whole calculation.

Breaking this down....

Source A is a DINT
Source B is a REAL

Since at least one of the operands of the ADD instruction is a REAL tag, this will force the processor to use the floating-point "calculator", so ....

0 + 3.12 = 3.12 which then has to be stored back into a DINT tag - it will store it in the DINT as 3

3 + 3.12 = 6.12 which then has to be stored back into a DINT tag - it will store it as 6

6 + 3.12 = 9.12 which then has to be stored back into a DINT tag - it will store it as 9

after just 3 samples your stored value is way off, you are losing the 0.12 every time the ADD is triggered.

You need to rethink what the algorithm is supposed to do, and modify the program/tag types to make it work the way you want.

Hint : all maths instructions do what they need to complete, the crucial thing is where is the result stored, if you store a REAL result to a DINT tag, it is rounded, and you lose (or gain) data
 
Last edited:
I know this is an old thread, but a coworker just asked me a similar question and even though almost every answer on this thread was right, no one explained it with apples (Which seems necessary)

Here is the thing about that magic number 67,108,864 and IEEE Standard 754 Floating Point Numbers.

As someone mentioned, that value is the last value where the REALS increased by one's and started increasing non-linearly.
The next value after 67,108,864 is 67,108,872 an increment of 8, so if your increment is only a shy 3.1200, the addition of those two numbers results in a value that if rounded to an integer the nearest value on the IEE-754 standard is magically the same 67,108,864 value.

This will happen if your increments are small, at some point, you will end with that wall even if your increment is more than 3.12 since the step size increases at bigger values.

Value IEEE-754
67,108,860 = 67,108,860
67,108,861 = 67,108,861
67,108,862 = 67,108,862
67,108,863 = 67,108,863
67,108,864 = 67,108,864
67,108,865 = 67,108,864
67,108,866 = 67,108,864
67,108,867 = 67,108,864
67,108,868 = 67,108,864
67,108,869 = 67,108,872
67,108,870 = 67,108,872
67,108,871 = 67,108,872
67,108,872 = 67,108,872
67,108,873 = 67,108,872
67,108,874 = 67,108,872
67,108,875 = 67,108,872
67,108,876 = 67,108,880
67,108,885 = 67,108,888

67,108,864
+ 3.12
67,108,867.12
Round 67,108,867.00

The solution to this threat:
-Count Revs in a DINT will give you almost 100 more times the capacity of storage
-Tape a scientific calculator to the side of the HMI so they can calculate by themselves or
- If they need to hit a target or something, divide the target by 3.12 and make it the new target or convert some units like feet or meters if possible. I know that changing the mindset of the operators could be difficult but can't be more difficult than dealing with floating values at a 32-bit CPU.
 
...

Value IEEE-754
67,108,860 = 67,108,860
67,108,861 = 67,108,860
67,108,862 = 67,108,864
67,108,863 = 67,108,864
67,108,864 = 67,108,864
67,108,865 = 67,108,864
67,108,866 = 67,108,864
67,108,867 = 67,108,864
67,108,868 = 67,108,864
67,108,869 = 67,108,872
...
Minor typo; fixed above
 
Expanding on what @omar.fiscal wrote, for those that want to go deeper ...

When I saw this thread, the first thing I noticed was how close the "cap" was to 64 million, which meant it was around 4 (=22) time 16,777,216 (=224 = 0x1000000).

So the first thing I tried was putting that cap value into a calculator in Programming Mode, which confirmed that it was a power of 2:
24bits.png

The significance of 16,777216 (224[) is that is the largest whole number, represented in 32-bit REAL (IEEE-754 Single-Precision Floating-Point) that can be the result of adding 1 to another whole number, because the mantissa of 32-bit reals has 24 bits available (with another 8 for the exponent and 1 for the sign).

Anyway, a slightly more interesting value is 67,108,860, four less than the ...,864 cap that spawned this thread all those years ago.
24bits_next.png

Note especially
  • that the last two binary digits (bits), highlighted in green, are 0, and
  • that the next 24 bits, highlighted in red, are all 1s.
The primary issue of this thread is analogous to a decimal display using scientific notation with two digit places (a ones digit and a tenths digit) and a power-of-10 place e.g. "9.8 x 103"). When the display is "9.8 x 103" the value is 9800; the next two greater and closest values that can be displayed are "9.9x 103" (9900) and "1.0 x 104" (10000), i.e. the displayable values increment in steps of 100 (= 0.1x 103). After 1.0 x 104 however, the next greater and closest value is 1.1x 104 i.e. a step of 1000 (= 0.1x 104). The "00" and "000" suffixes are the ones, tens, and hundred digits, assume to be 0 because they are after the last displayed (tenths) digit of the scientific notation.

In 32-bit REAL, the corresponding values are
Decimal___base-2 scientific notation
67,108,856 1.11111111111111111111110 x 225
67,108,860 1.11111111111111111111111 x 225
67,108,864 1.00000000000000000000000 x 226
67,108,872 1.00000000000000000000001 x 226

As a final, if pedantic, example of what is happening, consider the following Python code and output:
>>> import numpy
>>> f=numpy.float32
>>> for i in range(67108856,67108881): print((i,int(f(i)),i==int(f(i)) and '==' or ' ',bin(i),bin(int(f(i))),))
...
(67108856, 67108856, '==', '0b11111111111111111111111000', '0b11111111111111111111111000')
(67108857, 67108856, ' ', '0b11111111111111111111111001', '0b11111111111111111111111000')
(67108858, 67108856, ' ', '0b11111111111111111111111010', '0b11111111111111111111111000')
(67108859, 67108860, ' ', '0b11111111111111111111111011', '0b11111111111111111111111100')
(67108860, 67108860, '==', '0b11111111111111111111111100', '0b11111111111111111111111100')
(67108861, 67108860, ' ', '0b11111111111111111111111101', '0b11111111111111111111111100')
(67108862, 67108864, ' ', '0b11111111111111111111111110', '0b100000000000000000000000000')
(67108863, 67108864, ' ', '0b11111111111111111111111111', '0b100000000000000000000000000')
[B][COLOR=rgb(44, 130, 201)](67108864, 67108864, '==', '0b100000000000000000000000000', '0b100000000000000000000000000')[/COLOR][/B]
(67108865, 67108864, ' ', '0b100000000000000000000000001', '0b100000000000000000000000000')
(67108866, 67108864, ' ', '0b100000000000000000000000010', '0b100000000000000000000000000')
(67108867, 67108864, ' ', '0b100000000000000000000000011', '0b100000000000000000000000000')
(67108868, 67108864, ' ', '0b100000000000000000000000100', '0b100000000000000000000000000')
(67108869, 67108872, ' ', '0b100000000000000000000000101', '0b100000000000000000000001000')
(67108870, 67108872, ' ', '0b100000000000000000000000110', '0b100000000000000000000001000')
(67108871, 67108872, ' ', '0b100000000000000000000000111', '0b100000000000000000000001000')
(67108872, 67108872, '==', '0b100000000000000000000001000', '0b100000000000000000000001000')
(67108873, 67108872, ' ', '0b100000000000000000000001001', '0b100000000000000000000001000')
(67108874, 67108872, ' ', '0b100000000000000000000001010', '0b100000000000000000000001000')
(67108875, 67108872, ' ', '0b100000000000000000000001011', '0b100000000000000000000001000')
(67108876, 67108880, ' ', '0b100000000000000000000001100', '0b100000000000000000000010000')
(67108877, 67108880, ' ', '0b100000000000000000000001101', '0b100000000000000000000010000')
(67108878, 67108880, ' ', '0b100000000000000000000001110', '0b100000000000000000000010000')
(67108879, 67108880, ' ', '0b100000000000000000000001111', '0b100000000000000000000010000')
(67108880, 67108880, '==', '0b100000000000000000000010000', '0b100000000000000000000010000')

The first column is a source integer incrementing by one from 67,108,856 to 67,108,880, i.e. from eight less than, to 16 greater than, the 67,108,864 cap. The second column is the result of that integer converted to 32-bit float (REAL) and then back to integer i.e. analogous to values written in the x.y x 10z display format described above and then back to an integer (e.g. 10,501 => 1.1 x 104 => 11,000). The third value is '==' or ' ' if the original value is equal or not equal, respectively, to the converted value. The fourth and fifth columns are the original and converted integer values expressed in binary.

Since only the 24 most-significant digits of the original integer value can be stored and preserved in the 32-bit REAL, some number of least-significant bits are truncated (lost) in the conversion, as can be seen by comparing the fourth and fifth columns:
  • two bits are truncated above the 67,108,864 cap
    • the last two bits are always 00 in the fifth column;
  • three bits are truncated below the cap
    • the last three bits are always '000' in the fifth column
 
Last edited:

Similar Topics

Hi! I had a little problem yesterday regarding how to link two DINTs together, but after some time thinking, I feel my question is actually, “How...
Replies
29
Views
7,193
I've always been a bit confused as to how RSLogix 5000 converts between data types of floating point to whole numbers. For the application I am...
Replies
5
Views
12,114
PLC Programming Noob here... Converting a Micro/WIN program to RSLogix 5000. Anyway to do an Unsigned DINT in RSLogix 5000? Have a value of...
Replies
4
Views
4,250
Hey all, I've reviewed many threads regarding converting one data type to another and I have something I'm working on that I'm stumped on and...
Replies
9
Views
5,927
Hi Everyone, Im here to ask how to convert DINT to REAL. Im using modscan32 to inject current & read from 2 word address register, eg: 40001 &...
Replies
2
Views
31,660
Back
Top Bottom