Why are you treating numbers as strings? That is, to be very polite, not a bright thing to do.
If you want 253.3 and 253 to be equal, just do this:
data test;
input x y;
if round(x,1) = round(y,1)
then test = "yes";
else test = "no";
datalines;
253.3 253
;
So you consider a difference of .001 important, but a difference of .3 (larger by a factor of 300!) not?
What is your rule for this?
Quote from your original post:
"IMO or in terms of project, value 253.3 or 253.30 or 253.0000000000 should be equal. "
Please proofread your posts, and edit them if you find such crucial mistakes.
But my basic point stays: Store numbers as NUMBERS, and you can make simple comparisons.
If not, input values to numbers, and compare those:
data test; input x :$20. y :$20.; if input(x,32.) = input(y,32.) then test = "yes"; else test = "no"; datalines; 253.3 253 253.3 253.300000000 253.312 253.313 ; proc print data=test noobs; run;
Result:
x y test 253.3 253 no 253.3 253.300000000 yes 253.312 253.313 no
Hi @Babloo,
I suspect the reason why you're doing this is that you encountered numeric representation issues.
Example:
data _null_;
x=253.3;
y=759.9/3;
put (x y)(/=25.20);
if x ne y then put 'different!';
run;
Result (with SAS 9.4M5 under Windows):
x=253.30000000000000000000 y=253.30000000000000000000 different!
So, it happens easily to obtain numbers which should be equal (mathematically) and which look equal (with common display formats), but SAS considers them different because of tiny rounding errors.
Similar issues can even occur without involving calculations, just by appending zeros to decimal fractions (see examples further below).
The standard way of dealing with said issues is using the ROUND function with a suitable rounding unit -- where "suitable" means: small enough not to influence results, but big enough to correct rounding errors in the least significant bits. It depends to some extent on the order of magnitude of the values to be rounded, but a value of 1E-9 is suitable for many practical applications.
Example:
data test;
input x;
r=round(x,1e-9);
cards;
1E-5
1.0E-5
1.00E-5
1.000E-5
253.3
253.3000000000000000000
253.30000000000000000000000
253.300000001
;
proc print data=test;
format x r hex16.;
run;
Result:
Obs x r 1 3EE4F8B588E368F1 3EE4F8B588E368F1 2 3EE4F8B588E368F0 3EE4F8B588E368F1 3 3EE4F8B588E368F0 3EE4F8B588E368F1 4 3EE4F8B588E368F1 3EE4F8B588E368F1 5 406FA9999999999A 406FA9999999999A 6 406FA99999999999 406FA9999999999A 7 406FA9999999999B 406FA9999999999A 8 406FA999999A230A 406FA999999A230A
Note how the ROUND function maps the different internal values of obs. 1 vs. 2 and obs. 3 vs. 4 to the same value. The same goes for obs. 5, 6 and 7 -- but without losing the ability to distinguish between values that differ by 1E-9 (the rounding unit), see obs. 8.
Edit: Your attempt using the NUMX18.10 (in)format must fail in general because a value displayed with this format will mostly have more than one decimal place (in fact up to 10 -- if space permits) and contain a comma rather than a decimal point, so it can't be equal to something like "253.3". Moreover, note that using the decimal specification (e.g. numx18.10) in the informat is risky because it causes a division of integers by a power of 10 and is ignored for values already containing a decimal point (or comma in this case).
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 25. Read more here about why you should contribute and what is in it for you!
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.