data test;
set datei;
vitdk3=0; vitdk4=0; vitdk5=0;
if vitd=24.4 then vitdk3=1;
if round(vitd,0.00000000000001)=24.4 then vitdk4=1;
if round(vitd,0.000000000000001)=24.4 then vitdk5=1;
* vitdk4 hat als einzige Kategoriale Variable korrekten Inhhalt:;
if vitdk4=1 then do;
format vitd 32.29;
put vitd= ;
end;
* Ausgabe im LOG:
VITD=24.40000000000000000000000000000
;
run;
Hi,
I don't have your original 'datei' table so I made some up in my 'datei' step.
If you take the FORMAT 32.29 away the displayed values are 'displayed as rounded'
but the internal value is unchanged.
In the 'datei' step:
The first thing to note is that decimal precision problems are being encountered:
Input value 24.3999999999999 (13 decimal places ) and input values 24.39999999999999
(14 decimal places) are both displayed as 24.3999999999999 with 13 places!
The effect is demonstrated again with 0.00...1 vs 0.09...1 (converts to 0.089...)
In the 'test' step we see the following effects:
SAS cannot display the 14 decimal places correctly but internally the value is closer to 14 decimal places and the round function still works!
The decision to round before every analysis will probably be based on the following factors:
1) data content / type of data
2) business area (rules and conventions)
3) desired outcome
All of which will be influenced or overridden by the precision of SAS 8 byte numeric data!
There are many SAS Papers on the subject of precision. One solution is to multiply decimals
to whole numbers for calculation (whole number precsion is superior to decimal places) and then divide the
end result. There is also a paper to implement a JAVA class
(http://www2.sas.com/proceedings/forum2008/021-2008.pdf) in order to use 'BigDecimal'.
Finally to answer your question:
SAS always uses the internal value for calculation. The round function, when applied appropriately, will
influence the calculation which can compensate for discrepancies between the displayed value and the
internally held value.
The round function will not rescue the situation where the internally held value has been
altered (corrupted) due to 8 byte precision issues.
Best Regards, Viele Grüße,
Ian
Sample Code and Data:
data datei;
/* Numeric Precision effects using SAS 9.3 on Windows 7 (64bit) - other Operating Systems may
display different values */
format vitd 32.29;
vitd = 24.4 ; OUTPUT;
put vitd ;
vitd = 24.3 ; OUTPUT;
put vitd ;
vitd = 24.3999999999999 ; OUTPUT;
put vitd ;
vitd = 24.39999999999999 ; OUTPUT;
put vitd ;
vitd = 24.5 ; OUTPUT;
put vitd ;
vitd = 1.00000000000000000000000000001 ; OUTPUT;
put vitd ;
vitd = 0.00000000000000000000000000001 ; OUTPUT;
put vitd ;
vitd = 0.09000000000000000000000000001 ; OUTPUT;
put vitd ;
run ;
data test;
set datei;
format vitd 32.29;
vitdk3=0; vitdk4a=0; vitdk4b=0; vitdk4c=0; vitdk5=0;
if vitd=24.4 then vitdk3=1;
/* 12 places */
if round(vitd,0.000000000001)=24.4 then vitdk4a=1;
/* 13 places */
if round(vitd,0.0000000000001)=24.4 then vitdk4b=1;
/* 14 places */
if round(vitd,0.00000000000001)=24.4 then vitdk4c=1;
/* 15 places */
if round(vitd,0.000000000000001)=24.4 then vitdk5=1;
* vitdk4 hat als einzige Kategoriale Variable korrekten Inhhalt:;
if vitdk4a=1 then do;
put vitd= ;
end;
if vitdk4b=1 then do;
put vitd= ;
end;
if vitdk4c=1 then do;
put vitd= ;
end;
run;
There are no hidden decimals in SAS. You've got 8 bytes to store a number and you can see every single bit of it. 8 bytes give you full precision for 15 digits.
Use format "best32." (best16. would do actually).
data _null_;
i=1;
format var best32.;
do while(i<1000000);
var=i/3;
put var=;
i=i*10;
end;
stop;
run;
You get often issues with precision when moving floating point values between systems - eg. between SAS and a data base. It's a good idea to round the values there before any comparison.
For your case where it's about re-coding: You could also create a format (Proc Format) with a fuzz factor and then simply apply the format "new_val=put(old_val,myfmt.);
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!