CLX when put a LARGE number to DINT tag

coolblind

Member
Join Date
Apr 2008
Location
WA
Posts
36
Let me put it short.

Rslogix5000 V15, Controllogix 5563, and this is what I got just now (in ST):

x := 16#1fffffff;
y := x*(2*1);
z := x*(2**1);

And in the tag monitor window:

y: 16#3fff_fffe (which is what I expected, just shift ONE bit to the left)

z: 16#4000_0000 (I don't know how this comes out!!)

SO, is there any one please give me some hints about this?

Thanks.
 
Btw, I know the max number for the DINT tag is 2**31-1(2^31-1), but when I wrote as:

x := 2**31-1 (I think maybe there is a overflow when 2**31.)

I got x as16#8000_0000

I had to either put
x := 16#7fffffff
or
x := 2147483647
in order to get the max number.

So, how does CLX handle the power (**) calculation?

Is there other way to get the 2**31-1 value?
 
Last edited:
I believe XPY instruction internally uses floating point math and after that result converted to DINT.

Because floating point mantissa is only 23 bits, results with large numbers may not be accurate.

I think you get similar error if you do 10**7.
This is a limitation of 32 bit IEEE floating point.
 
coolblind said:
Is there other way to get the 2**31-1 value?

I'm not sure what you are trying to do... why can't
you enter it as a constant? Exponential instructions are CPU intensive, they are not simple math instructions.
 
Alaric said:
I'm not sure what you are trying to do... why can't

you enter it as a constant? Exponential instructions are CPUintensive, they are not simple math instructions.

I just want to make sure how CLX handle the exponential instructions, have any idea for my fist question?
 
Contr_Conn said:
I believe
internally uses floating point math and after that result converted to DINT.

Because floating point mantissa is only 23 bits, results with large numbers may not be accurate.

I think you get similar error if you do 10**7.
This is a limitation of 32 bit IEEE floating point.

Contr_Conn, if you look at the expression of y and z, I cannot find what is difference between (2**1) and (2*1).

Here I only did the XPY for the 2, and the result should be 2. It is not a large number anyway...
 
Contr_Conn said:
I believe XPY instruction internally uses floating point math and after that result converted to DINT.
You are probably right, but it also shows that the compiler optimizer is poor or non-existant. The compiler should be smart enough to recognize that the exponent is a constant integer. In this case the compiler should
100=10*10 ; 10**2
1000=100*10 ; 10**3
1000000=1000*1000 ; 10**6
10000000=1000000*10 ; 10**7
4 integer mulitplies does the trick and this is much faster than taking the log, mulitplying and then using the exponent function. That is what a x**y function does.

Because floating point mantissa is only 23 bits, results with large numbers may not be accurate.

I think you get similar error if you do 10**7.
The math should work all the way to 16,777,??? which is greater than 10**7

Note, I give my guys grief about this all the time. This is one of my favorite compiler tests.
 
Peter, I agree with you.

They really should do better about the complier stuff. At least, I expect the consistent result no matter what to use:

y := x*(2*1);

or

z := x*(2**1);
 
if you look at the expression of y and z, I cannot find what is difference between (2**1) and (2*1).

Here I only did the XPY for the 2, and the result should be 2. It is not a large number anyway...
2**1 works OK, but in your case X is large number and once XPY used it will be converted to float first.
You are probably right, but it also shows that the compiler optimizer is poor or non-existant. The compiler should be smart enough to recognize that the exponent is a constant integer.
There is no optimization as far as I know. All based on internal 32bit Real math. BTW softlogix uses 64bit Windows math and does it correctly.
 
Contro_Conn:
Do you mean as long as there is a XPY in the equation, the complier will conver all calculation to real math?

Otherwise, for z := x*(2**1), as long as it gets 2**1=2, the complier should convert it back to DINT, and does the "*", then I should get the same result from z := x*(2**1) and y :=x*(2*1).
 
As far as I know all math in ST done via Compute instruction, compiler will not break it in to two separate instructions.

You can try two lines instead:
Z1=2**1;
Z=X*Z1;

As long as all tags declared as DINT it should work - I did not try this.

But like I said this is a limitation of XPY instruction, so if you use something other than 2**1 you may get wrong result again.
try 10**7 or larger...
 
Contr_Conn, Thanks for all your have done.

Now I now come to know what you talked about, I just did a little test in Matlab:

x=single(10^7) // single() will make x to be a 32-bit float number

Then if:

x+0.4 I got 10^7
x-0.4 I got 10^7

and if you try "eps(x)", you got 1.

That means the next single float is 10^7+1 and 10^7-1, basically you lost all of the numbers between them (such as 10^7+0.4...)

And the larger the number, the larger the cap will be.

But this does not answer my question in the first post, why I got different result in "y" and "z", even like you said, the complier treats all the number as REAL...

Any one any inputs? Thanks.
 
x := 16#1fffffff;
for y := x*(2*1): internall operations will be
(DINT)2 * (DINT)1 * (DINT)16#1ffffff


for z := x*(2**1); internall operations will be
((REAL)2**(REAL)1)*(REAL)16#1ffffff, =>covert result REAL to DINT

23 bit mantissa can't fit 16#1ffffff, so you will loose some accuracy here.

You can do simple test:
REAL:= x;
z:=REAL;
if x is a large number like 16#1fffffff, z will not be equal to x

Again, there is no bug here, this is a nature of 32-bit REAL number handling
 
Contr_Conn and Peter, I believe I have got it now, and I repeat it in the Matlab, as you said, it is NOT A BUG, I got the same result using following Matlab code:

x=int32(hex2dec('1fffffff')) // 536870911
y=x*(2*1) // the result is '3FFFFFFE' in hex
z=single(x)*(2^1) // the result is '40000000' in hex
x1=single(x) // the result is 536870912 which is not Equal to x

This also remind me to be careful with the SINGLE tag when deal with the large number.

Thanks everyone again.
 

Similar Topics

I'm currently going through and integration with an old machine. For the outputs I've spec'd 1756 - OA16's which offer everything I need however...
Replies
0
Views
2,124
Hi all, I cannot find any analog output module for ControlLogix that can output a negative current: -20 mA --> +20 mA ??? Did I miss...
Replies
2
Views
1,663
I'm running a CLX setup with the high speed analog I/O cards. I have a rung where I am doing a calculation, and check the divisor variable to make...
Replies
22
Views
4,641
I have CLX 5561 that has some inputs that are dropping out and I cant figure out why. I have a counter to catch them dropping out and also a timer...
Replies
19
Views
6,168
Controller: 1756-L84E v.35 Prosoft MVI56E-MNETC for ModbusTCP/IP I'm having an issue with some of my write commands. The write command that...
Replies
0
Views
195
Back
Top Bottom