Sign in to follow this  
Followers 0
Milosh

Float substraction?

6 posts in this topic

Hi all.

I use instruction -F(455) to subtract two real numbers from work area. Store result in TmpVariable also Real type from work area.

Why is +70,00000 - (+69,95000) = +0,05000305?  ...NOT OK

+70,00000 - (+69,90000) = +1,000000... OK

Thanks in advance...

Share this post


Link to post
Share on other sites

70.0 - 69.95 = 0.05  - nothing wrong with that...  0.05000305 is just closest floating point representation possible in 32-bit...

 

note that not all REAL numbers can be presented accurately, most are approximated. and you get "artifacts" after 6th place or so.

 

Share this post


Link to post
Share on other sites

Thanks for reply, 

Can we make some rounding after 2, 3 decimals?

Share this post


Link to post
Share on other sites

i don't see why would one care unless this is data to be displayed on HMI.

in that case HMI should have options to display specific format (number of decimal places etc.).

If for some reason this is not available, don't use floating point, use fixed point format...

for example multiply value by 1000 and place result into an integer variable.

so value such as 79500 will really represent 79.500 (three decimal places are implied).

This is something even oldest HMIs would handle.

1 person likes this

Share this post


Link to post
Share on other sites

Yes, but on panel I have mentioned two variables, formated with 2 decimal places.

If I set first to 70.00 and second to 69.95 the result is 0.05000305?

The problem is third parameter which I compare with this value.

If I have parameter which is set to 0.05, and want to do some action if following conditions are met:

 IF result<=Param then .... IF 0.05000305 <= 0.05000000 this is a problem?

 

Share this post


Link to post
Share on other sites

Computer representation of numbers in different formats is a really interesting topic. Key is to use correct format...

Note, REAL is encoded data format. If you are interested in making each and every digit count.... do not use REAL data type!

This is why servo controllers count pulses. You only see distances in REAL format as a secondary result.

Many things about REAL look nice and easy at first but there are pitfalls. For example:

- comparing floating points directly for equality is generally a bad idea (even if some systems may have some sort of a workaround in place)

- adding or subtracting floating point values that greatly differ in size is a bad idea. one can check it by making loop and adding very small value to a real number. eventually it will stop increasing, usually long before reaching maximum value that REAL can hold.

- etc.

 

I see cases all the time when programmers favor REAL in calculations thinking they get "better resolution" because software they look at generates bunch of meaningless digits. They don't realize that 32-bit is 32-bit. both 32-bit INT and 32-bit REAL can represent same number of different states.... they are just distributed differently. in case of integers, distribution is uniform. in case of REAL it is not. you get really small increments when values are close to zero. but you get really huge increments when values are big.

in fact REALs have a problem with significant figures because they only use 23-bit for this. There is no magic or "free lunch". 32 bits are divided into groups:

         1 bit is sign

         8 bits are exponent

         23 bits are significant

those 23 bits are determining how many significant figures in your number are correct. 23 bits in binary comes up to some 6, in best case 7 significant figures in decimal. Anything after that is garbage.... there is no point in using so many decimal places in your examples when system that is used to do calculation can at best do 6-7 significant figures.

 

Back to your question:

 IF result<=Param then .... IF 0.05000305 <= 0.05000000 this is a problem?

 

I would not even consider it.... 

 

note:

Value 0.05000000 is a result of subtraction from "70.000000". i would not count on more than 6 significant figures. this means 70.000000 is an exaggeration as only four decimal places are useful so this should be displayed as 70.0000 instead of 70.000000.

subtracted number is of same magnitude so result is going to be good only for up to those four places after decimal point.

Anything beyond 0.0500 in this case is nothing but wishful thinking... values such as 0.05000305 or 0.05000000 make no sense as they are really no better than 0.0500.

Sure you can get "wrong" result at the very slim margins of your range but why would you care.

And if you do .... don't use REALs (floating point numbers), use integers to represent fixed point numbers.

 

 

 

 

 

numbers.jpg

2 people like this

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0