Why in SAS does a numeric literal in scientific notation give a different number to the number written out explicitly

floating-pointsasscientific-notation

The following SAS code:

data _null_;
  format t u best32.;
  t = 10000000000000000000000000;
  u = 1e25;
  put t u;
  if t ne u then put 'diff';
run;

on my Windows machine prints out:

10000000000000000905969664 9999999999999998758486016
diff

While I understand that only the first 15-16 digits are to be trusted, why do they give different underlying numbers at all? How is SAS computing 1e25?

Edit: I've been asked to give the output for other powers of 10 up to 1e25. The following program:


%macro doit;
data _null_;
  format t u best32.;
%let t=1;
%do i=1 %to 25;
  %let t=&t.0;
  t = &t;
  u = 1e&i;
  put t u;
%end;
run;
%mend;
%doit;

gives the following output:


10 10
100 100
1000 1000
10000 10000
100000 100000
1000000 1000000
10000000 10000000
100000000 100000000
1000000000 1000000000
10000000000 10000000000
100000000000 100000000000
1000000000000 1000000000000
10000000000000 10000000000000
100000000000000 100000000000000
1000000000000000 1000000000000000
10000000000000000 10000000000000000
100000000000000000 100000000000000000
1000000000000000000 1000000000000000000
10000000000000000000 10000000000000000000
100000000000000000000 100000000000000000000
1000000000000000000000 1000000000000000000000
10000000000000000000000 10000000000000000000000
99999999999999991611392 99999999999999991611392
999999999999999983222784 999999999999999983222784
10000000000000000905969664 9999999999999998758486016

Best Solution

It looks like it might actually be calculating 1 * 10 * 10 ... * 10 and the errors are creeping in as soon as you get beyond the significant number of bits for the underlying float type.

But I don't believe that would happen for an IEE754 type float/double since it's quite able to represent 1x10full-range without loss of precision.

One possibility is that the problem you are having is related to the ability to store floats with less precision than allowed (which could possibly screw up a 1e25 calculation) - see http://www.uc.edu/sashtml/lrcon/z0695157.htm#z0695187 for an explanation.

Update 1:

Okay, so based on your comment, you're not restricting the length. What does the following code give you?

t = 10;
u = 1e1;
put t u;
t = 100;
u = 1e2;
put t u;
t = 1000;
u = 1e3;
put t u;
: : :
t = 10000000000000000000000000;
u = 1e25;
put t u;

Based on that output, we can probably deduce what's going on under the covers.

Related Question