Reputation: 21
Cheers!
Long story short I'm trying to deal with SAS rounding function and floating point precision.
Basically, I need to round half down to two decimals so, i.e. 1.235 should round to 1.23 and not 1.24
Here follow an example:
number | desired_output |
---|---|
1.230 | 1.23 |
1.235 | 1.23 |
1.2355 | 1.24 |
1.2305 | 1.23 |
1.231 | 1.23 |
1.236 | 1.24 |
I have tried many ways without success (i.e. several combinations of round(), ceil(), floor() and rounde() functions) but, to replicate the exercise, here below some tests:
data test;
input number desired_output;
datalines;
1.230 1.23
1.235 1.23
1.2355 1.24
1.2305 1.23
1.231 1.23
1.236 1.24
;
run;
data test;
set test;
round_01=round(number,.01);
round_ceil_01=ceil(round_01*100)/100;
round_floor_01=floor(round_01*100)/100;
round_even=rounde(number,.01);
less_half_rounding_factor=round(number-0.0005,.01);
run;
Thank you in advance!
Upvotes: 0
Views: 768
Reputation: 51611
How about:
round(number,0.01) - 0.01*(mod(number,0.01)=0.005)
Remove 0.01 when the next digit is exactly 5.
Test: Let's generate numbers to 5 decimal places and keep only those where the ROUND() function differs from the "round_down" logic above.
data test;
do integer=1 to 100000 ;
number=integer/100000 ;
round=round(number,0.01);
round_down = round(number,0.01) - 0.01*(mod(number,0.01)=0.005);
if round ne round_down then output;
end;
run;
Now let's check if any of them are those that are different are not those where the 3 least significant decimal places are 500, that is exactly X.XX500 .
data test2;
set test;
where 500 ne mod(integer,1000) ;
run;
So there were 100 cases where ROUND and ROUND_DOWN differed and they were all the cases where the value had a 5 in the thousands place and zeros after that.
Upvotes: 1
Reputation: 21
Hope this is what you are looking for
data test;
set test;
value = input(put(number,4.2)best.);
run;
Upvotes: 0