AB Floating Point errors

Hakutsuru

Member
Join Date
Nov 2005
Location
Texas
Posts
168
I saw where this was discussed last month, but I didn't want to necropost to that thread, and it didn't completely answer my situation.

I have a PLC5 and I am counting an input pulse with an add statement that adds .1 with every positive transition. Now, I read the posts, especially by alaric, where he says that when adding .1, I should be able to get accurate numbers up to 2097152. I am not. In fact, I can't even get to 1 without seeing the plc try to add .0999999 or .1000001 instead of .1. As the accumulated value got larger, it seemed more likely to add too much. For instance, if I take the number up to 999999.0 (it rolls over at 1000000), it'll take only 7 or 8 clicks of the input to get to the rollover point. Even when i started at 10000, it seemed to add .2 about 25% of the time. One more thing. I did not write down where the numbers got messed up, but I do not think it was happening at the same number everytime.

I got a lot better results when I added 1 everytime, and then divided by 10 later for the display. In fact, I didn't see a single error with that setup. But, after reading that I wasn't supposed to be seeing errors until the number got very large, I'm worried that even adding 1 is not safe. So I guess my question is, do PLC5s use an even less accurate form of floating points? Can it reliably add 1 to a floating point value or do I need to just bite the bullet and redesign the counter with integers? This is a legacy system and they are quite wary of letting me make big changes to things they *thought* were working just fine.


thanks for the help,
-jeff
 
Here's an exercise in floating point fractions.
Remember that each binary position is worth one half of that to its left. So lets look at numbers less than 1. Let's use a 'binary point' which looks suspiciously like a decimal point.

1.0 = 1

.1 = 1/2
.01 = 1/4
.001 = 1/8
.0001 = 1/16
.00001 = 1/32
etc.

You probably have the idea by now.

Now - pick out which of these (either on or off) you want to add up to EXACTLY 1/10th. When you have an exact answer get back to us.
 
Its not just AB that suffers from this problem, but EVERY computer that uses IEEE754 floating point, which is most of them.
(other formats are also not without problems)

Here is an online calculator where you can see the results in binary and see how some numbers cannot be represented exactly.
 
Last edited:
Hakutsuru said:
I got a lot better results when I added 1 everytime, and then divided by 10 later for the display.
This is the best way. Even then you will run into problems when you get to 16777216. You can count cascading two integers and then mulitplying the integraters by a floating point number and then summing the float point numbers. You will still lose precision but it will not accumulated like adding floats will.

Integers and double integers are for counting and incrementing, not floats.
 
Peter, in the other thread about floating points, you said "NEVER DIVIDE WHEN YOU CAN MULTIPLY BY THE RECIPRICAL". So I should multiply by .1 instead of dividing by 10? I didn't quite understand the reason, and now that I see how much trouble a PLC is going to have with .1, it doesn't seem right. Can you please explain?



-jeff
 
Multiplies are MUCH faster. There are also times when you have a choice between dividing by 0.1 and mulitply by 10. In this case mulitply by 10 will be MUCH more accurate. This little trick make a big difference when calculating coefficients for polynomials like we did a week and a half ago only in my case I often need to divide by 0.001 or 0.0005 ( the sample time ) to the 4th or 5th power. It is MUCh more accurate and faster to mulitply by 1000 or 2000 to the 4th or 5th power given 0.001 or even 0.1 can't be accurate respresented in a float.

I know this is a little thing but in floating point math the little errors become big ones.
 
Also, when multiplying a floating point number by 1000, enter the number as 1000.0. This will eliminate the need for the processor to convert the integer 1000 to the float 1000.0 - something that requires several steps to do. Some compilers automatically make the change for you, but its good practice to enter it as a float.
 
I had the problem in the thread I started last month. I ended up changing my actual hours fron 149757.4 to 1497574, then I add 1 every tenth of an hour, then I scale my number in Wonderware, which is where it is displayed, to get the tenth hour decimal back.
 

Similar Topics

I need to check an axis actual travel position, and to compare it to the master travel position. To do this I have to multiply the axis travel...
Replies
6
Views
2,559
We have AOIs for projects, which handle material dosing (by hand or by pipes and pumps), obviously they have comparison between setpoint and...
Replies
50
Views
14,196
Hi eveyone. I need transfer signal from system 1 to DCS via modbus. System 1 only can send 32 bit floating point. DCS receive 16 bit integer. How...
Replies
20
Views
10,565
Hi, In my ladder logic, I've got a data register D60 whose value is -0.001 (when using monitor mode to see values). D406 is 0.250. But then...
Replies
5
Views
1,302
Hi, can anybody tell that how can we move floating point data from one Regiter to another register in Fatek PLC.?
Replies
0
Views
1,546
Back
Top Bottom