turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

Find a Community

- Home
- /
- SAS Programming
- /
- Base SAS Programming
- /
- the floating point addition is it a commutative ?

Topic Options

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

01-16-2016 08:18 PM - edited 01-16-2016 08:20 PM

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

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

Posted in reply to LineMoon

01-17-2016 07:22 PM - edited 01-18-2016 06:19 AM

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

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

Posted in reply to FreelanceReinhard

01-27-2016 05:29 PM

Thank you very much

That's very kind from you