DATA Step, Macro, Functions and more

Adding floating-point numbers

Accepted Solution Solved
Reply
New Contributor
Posts: 4
Accepted Solution

Adding floating-point numbers

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: 7,764

Re: Adding floating-point numbers

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.

So your CPU adds

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

View solution in original post


All Replies
Super User
Super User
Posts: 7,942

Re: Adding floating-point numbers

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

Re: Adding floating-point numbers

[ 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

Super Contributor
Posts: 438

Re: Adding floating-point numbers

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

Re: Adding floating-point numbers

Posted in reply to jklaverstijn
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: 7,764

Re: Adding floating-point numbers

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.

So your CPU adds

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
New Contributor
Posts: 4

Re: Adding floating-point numbers

Posted in reply to KurtBremser

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

☑ This topic is solved.

Need further help from the community? Please ask a new question.

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