BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
MichaelChung
Calcite | Level 5

Hi,

 

I just did a practice of array and happened to find that one arithmetic result is not logical.

 

 

**** data preparation ;
data visits;
    infile datalines;
    input patid visdt0 visdt1 visdt2 visdt3 visdt4;
    datalines;
1001 0.1 1.1 2.1 3.1 4.1
1002 0.2 1.2 2.2 3.2 4.2
;
run;

**** foolproof dataset;
data work.checkvisits;
    set work.visits (keep=patid visdt0 visdt1 visdt2 visdt3 visdt4);
    array visdt(1:5) visdt0 visdt1 visdt2 visdt3 visdt4;
    do i=2 to 5;
        x = visdt(i) - visdt(i-1);
        if x gt 1 then do;
            * there should be no output since all differences;
            * should equal to 1 ;
            put visdt(i-1)= visdt(i)= x=;
            output;
        end;
    end;
    drop i x;
run;

**** print ;
proc print data=checkvisits;
run;

 

 

and the log:

 

```log

visdt1=1.2 visdt2=2.2 x=1
NOTE: There were 2 observations read from the data set WORK.VISITS.
NOTE: The data set WORK.CHECKVISITS has 1 observations and 6 variables.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds

```

 

The environment is SAS 9.2 on Linux. Please advise, thanks.

1 ACCEPTED SOLUTION

Accepted Solutions
3 REPLIES 3
Reeza
Super User

Numerical precision. 

 

http://support.sas.com/documentation/cdl/en/lrcon/68089/HTML/default/viewer.htm#p0ji1unv6thm0dn1gp4t...

 

Although reference is 9.4 it does apply to 9.2 as well 

MichaelChung
Calcite | Level 5

Thanks so much Reeza, I adjusted a bit the program and found two remainings do not match the real value probably due to truncation in binary numbers.

 

13         **** foolproof dataset;
14         data work.checkvisits;
15             set work.visits;
16             array visdt(1:5) visdt0 visdt1 visdt2 visdt3 visdt4;
17             do i=2 to 5;
18                 * the expeced result should be 0 ;
19                 x = visdt(i) - visdt(i-1) - 1;
20                 put visdt(i-1)= visdt(i)= x=;
21                 if x gt 0 then do;
22                     output;
23                 end;
24             end;
The SAS System

25             drop i x;
26         run;

visdt0=0.1 visdt1=1.1 x=0
visdt1=1.1 visdt2=2.1 x=0
visdt2=2.1 visdt3=3.1 x=0
visdt3=3.1 visdt4=4.1 x=-4.44089E-16
visdt0=0.2 visdt1=1.2 x=0
visdt1=1.2 visdt2=2.2 x=2.220446E-16
visdt2=2.2 visdt3=3.2 x=0
visdt3=3.2 visdt4=4.2 x=0
NOTE: There were 2 observations read from the data set WORK.VISITS.
NOTE: The data set WORK.CHECKVISITS has 1 observations and 6 variables.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds
ballardw
Super User

Those are the exact types of issues that arise with numerical precision for decimals. If you do something like

 

x = round( visdt(i) - visdt(i-1), 0.00001) -1;

 

you may be happier.

sas-innovate-wordmark-2025-midnight.png

Register Today!

Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.


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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 3 replies
  • 1199 views
  • 0 likes
  • 3 in conversation