BookmarkSubscribeRSS Feed
LineMoon
Lapis Lazuli | Level 10

Hello,

Please, I want to get some exemples where the floating point addition is not a commutative ?

a+b is not equal to b+a

Thank yo

 

2 REPLIES 2
FreelanceReinh
Jade | Level 19

Hello @LineMoon,

 

I would be surprised to see such a case (with two summands) in SAS 9.4 on Windows. (For three summands see PG's post in the thread where you originally brought up this question.) However, in 2012 I encountered strange results with SAS 9.2 TS2M3 on Windows Server 2008, which came close to this (different results, in a sense, even without modifying the expression):

 

Example 1 (log excerpt): Identical values with a non-zero difference

12938  data _null_;
12939  a=0.1; b=0.7; c=a+b; d=a+b; e=d-c;
12940  put c hex16.;
12941  put d hex16.;
12942  put e hex16.;
12943  run;

3FE9999999999999
3FE9999999999999
3C80000000000000

Example 2 (program and output): Identical calculations (d minus c) with slightly different results in the same data step

data test;
a=0.1; b=0.7; c=a+b; d=0.8; e=d-c; f=d-c;
proc print;
run;

Obs     A      B      C      D          E             F

 1     0.1    0.7    0.8    0.8    8.3267E-17    1.1102E-16

Example 3 (log excerpt): A variable which seems to contain a different value than it has been assigned in the previous statement

12843  data _null_;
12844  a=0.1; b=0.7; c=a+b; d=0.8; e=d-c;
12845  if e ne d-c then put '?!!';
12846  run;

?!!
NOTE: DATA statement used (Total process time):

Example 4 (log excerpt): Two identical pairs of numerical expressions with neither LHS>RHS, nor LHS<RHS, nor LHS=RHS

12851  data _null_;
12852  a=0.1; b=0.7; c=a+b; d=0.8;
12853  if d-c>1e-16 | d-c<1e-16 | d-c=1e-16 then put 'Ok';
12854  run;

NOTE: DATA statement used (Total process time):

(Please note that the above examples were not written to point out the well-known fact that 0.1+0.7 ne 0.8 in (Windows) SAS, which is due to numeric representation error.)

 

I suspected the common reason of these phenomena to be that the initial calculation of d-c gave a different result than the second and, in fact, subsequent calculations because the latter were optimized not to repeat the calculation and the former used extended real precision (80 bits; cf. one of the standard references on numeric representation issues: SAS Technical support document TS-654, p. 5 -- I've replaced the URL, SAS Institute seem to have removed the document recently from http://support.sas.com/techsup/technote/ts654.pdf and redirected the link to SAS 9.4 documentation).

 

Now, with SAS 9.4 on Windows 7 I cannot replicate any of the above results. Therefore, I assume that SAS Institute have fixed that in the meantime.

 

To be more confident that a+b=b+a in SAS 9.4 on Windows 7, I checked this with 1 billion random pairs (a, b) with a and b having absolute values in the range 2**-20 to 2**20, i.e., roughly from one millionth to one million:

/* Check a+b=b+a with randomly selected internal representations of floating-point numbers a and b */

data _null_;
call streaminit(3141592);
array x a b;
array c[2] $16;
do j=1 to 1e9; /* 1 billion pairs of random numbers with abs. values between 2**-20 and 2**20 */
  do i=1 to 2;
    e=1003+(int(40*rand('uniform')));     /* exponent -- from 1003 (i.e. -20) to 1042 (i.e. 19) */
    if rand('uniform')<0.5 then e=e+2048; /* negative sign */
    m1=int(16777216*rand('uniform'));     /* mantissa, first 6 hex digits */
    m2=int(268435456*rand('uniform'));    /* mantissa, last 7 hex digits */
    c[i]=cats(put(e,hex3.),put(m1,hex6.),put(m2,hex7.));
    x[i]=input(c[i],hex16.);
  end;
  if a+b ne b+a then do; 
    put '######################################## ALARM! ########################################';
    put _all_;
    put '########################################################################################';
  end;
end;
run; /* Result: No "alarm" occurred with SAS 9.4 on Windows 7. */

The following modification (extension to almost the whole range of numbers representable in Windows SAS) did not yield a surprise either with (only) 100 million samples: 

e=1+(int(2045*rand('uniform')));      /* exponent -- excluding 2046 to avoid overflow in the summation */

 Please note that it would have been less likely to find an example with a+b ne b+a in this second setting because many of the pairs (a, b) combined numbers of so different orders of magnitude that, numerically, "a+b=a" or "a+b=b."

 

LineMoon
Lapis Lazuli | Level 10

Thank you very much

That's very kind from you

 

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 2 replies
  • 1105 views
  • 1 like
  • 2 in conversation