## the floating point addition is it a commutative ?

Super Contributor
Posts: 378

# the floating point addition is it a commutative ?

[ Edited ]

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

Posts: 1,242

## Re: the floating point addition is it a commutative ?

[ Edited ]

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."

Super Contributor
Posts: 378