Welcome to our new forum
All users of the legacy CODESYS Forums, please create a new account at account.codesys.com. But make sure to use the same E-Mail address as in the old Forum. Then your posts will be matched.

## Am I crazy? A-B [REAL] give wrong result? document.SUBSCRIPTION_OPTIONS = { "thing": "topic", "subscribed": false, "url": "subscribe", "icon": { "css": "fa fa-envelope-o" } };

hki75
2017-09-14
2017-09-28
• hki75 - 2017-09-14

a simple code:
PROGRAM PLC_PRG
VAR
A: REAL:=50.0;
B: REAL:=50.15;
C:REAL;
END_VAR

C:=A-B;

C value is -0.1500015 ? Why?

I'm using 2.3.9.53

• Anonymous - 2017-09-14

Originally created by: scott_cunningham

Accuracy limits of REAL type. If you need higher accuracy, then you need to use LREAL, if it is supported on your platform.

• hki75 - 2017-09-15

mmm....I don't think is the REAL data type limit...by doing the same calculation on codesys 3 is ok. Or by trying to adding (50+50.15=100.15 , not 100.1500015..)the result is correct. I think is something related to the fraction and exponent management ...
No one had the same trouble?

• Anonymous - 2017-09-18

Originally created by: scott_cunningham

You are hitting accuracy errors. Keep in mind that 0.15 is a repeating number in base 2, so depending on internal implementation, you will have an error when you define the value because of truncation. Also, I am pretty sure you will see more accuracy problems with 50-50.15 (negative, fractional number) than with 50 + 50.15. This page (http://ccm.net/contents/62-representati ... d-integers) gives an explanation of how real numbers are stored as a 32 bit number.

This calculator (https://baseconvert.com/) shows:

-0.1500000 = -0.0010 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 1
-0.1500015 = -0.0010 0110 0110 0110 0111 1111 1001 0000 1101 1001 1101 0111 0111 0111 0100 1010 1

Bit deviation starts at bit 20 (23 bits would be absolute max performance, based on 23 bit mantissa)

Now, if we look at your 50-50.15:

50.00 = 11 0010.0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0
50.15 = 11 0010.0010 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 1

50.00 will be: 1.10010000000000000000000 e^(127+5) s=0, m=10010000000000000000000, e=10000100
50.15 will be: 1.10010001001100110011001 e^(127+5) s=0, m=10010001001100110011001, e=10000100

Ultimately, you are subtracting a truncated repeating number, so error will appear sooner.

I created a project with CoDeSys 3.5.6.66 that has an error already with 50.15 (as expected) - see the screen shot. I also used 50.5 instead, and received a "perfect" answer (because 0.5 is 0.1 in base 2 notation). See screen shots.

Are you sure your CoDeSys 3 test was still using 32 bit REALs? With LREAL, you will see -0.15 in the online debug mode, but not in the variable header - you will see truncation error of infinite repeating 0.15 in base 2:

• shooter - 2017-09-28

REAL is not exact, so you can see a small deviation.
the same can be done on a simple calculator, just add 1 and after 1 million times the result will not be exact.
It is indeed to do with the way the mantisse works, as it is not endless resolution.