## DATA Step, Macro, Functions and more

Solved
New Contributor
Posts: 4

I am trying to understand how floating-point numbers are added in SAS. I have the following code:

data data1;
format b c d binary64.;
b=0.5; c=0.3; d=b+c;
if d=0.8 then flag=1;
RUN;

And flag is really set to 1.

In binary64:

b=0011111111100000000000000000000000000000000000000000000000000000

c=0011111111010011001100110011001100110011001100110011001100110011

d=0011111111101001100110011001100110011001100110011001100110011010

and 0.8 is represented the same as d. My problem is that when I try to add b and c, normalize the mantissas and add bit by bit I get a number that differs from d. I checked all my calculations and this is not the case. Does anyone know why this can happen?

Accepted Solutions
Solution
‎08-16-2016 08:45 AM
Super User
Posts: 10,209

Keep in mind that 52 bits are stored, but the precision is actually 53 bits (there's always a "hidden" 1 at the beginning of the mantissa) and the math unit in the CPU can probably use all it's 64 integer bits for adding.

```10000000000000000000000000000000000000000000000000000+
010011001100110011001100110011001100110011001100110011
=
110011001100110011001100110011001100110011001100110011```

Before you store that back, the leading 1 is eliminated, the exponent once again set to -1, and the 53rd bit from the remaining number is rounded to the 52nd, which is also 1, so the 51st is set to 1 and the 52nd to 0.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
How to convert datasets to data steps
How to post code

All Replies
Super User
Posts: 9,599

You should use round() around calculated floating point.  There is a quirk in machines - can't remember the exact term, where a number can have a very small amount on the end of the number, e.g. 0.80000000000000001, but SAS does not display that.  If you apply the round() to this it will return exactly the number:

if round(d,.1)=0.8 then flag=1;

you will see this a fair bit in proc sompare ouputs, where it shows differences in numbers which you cant see.  Just make sure to round your values to the correct decimal places.

New Contributor
Posts: 4

[ Edited ]

Thanks for the tip. When I perform the comparison 0.5+0.3 does equal 0.8, however when I actually try to repeat what SAS does in the way I understand it I can't. I get a different value, not 0011111111101001100110011001100110011001100110011001100110011010

Valued Guide
Posts: 533

There is a thorough discussion on the topic in the SAS online docs called Numerical Accuracy in SAS Software. In my view a must-read for every SAS user.

Regards,

- Jan.

New Contributor
Posts: 4

Hi Jan, I've seen this and I am trying to repeat the process the same way in my understanding SAS would do it: i.e. adjust the mantissas, truncate afterwards but probably I am missing something as for this example I am not able to recreate the values. However if I take 0.7 and 0.1 and do the same I can recreate the values and see that 0.7+0.1 is not equal to 0.8
Solution
‎08-16-2016 08:45 AM
Super User
Posts: 10,209

Keep in mind that 52 bits are stored, but the precision is actually 53 bits (there's always a "hidden" 1 at the beginning of the mantissa) and the math unit in the CPU can probably use all it's 64 integer bits for adding.

```10000000000000000000000000000000000000000000000000000+
010011001100110011001100110011001100110011001100110011
=
110011001100110011001100110011001100110011001100110011```

Before you store that back, the leading 1 is eliminated, the exponent once again set to -1, and the 53rd bit from the remaining number is rounded to the 52nd, which is also 1, so the 51st is set to 1 and the 52nd to 0.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
How to convert datasets to data steps
How to post code
New Contributor
Posts: 4

Thanks so much! I forgot about the rounding. Now everything is pretty clear.

☑ This topic is solved.

Discussion stats
• 6 replies
• 398 views
• 2 likes
• 4 in conversation