Hi,
We have an issue with proc format
For .88000000000001 value format should give ‘VH’ as it is greater than 0.88 but it is giving out ‘H’.
Below is the code:
proc format;
value tempfmt low -< 0.205000 = 'VL'
0.205000 -< 0.410000 = 'L'
0.410000 -< 0.645000 = 'M'
0.645000 -< 0.880000 = 'H'
0.880000 - high = 'VH'
other = ' '
;
run;
data funny;
input ORIGINAL_VALUE;
format ORIGINAL_VALUE best32.30;
informat ORIGINAL_VALUE best32.30;
datalines;
.87999999999999
.88000000000000
.88000000000001
.88000000000002
.88000000000003
.88000000000004
.88000000000005
.88000000000006
.88000000000007
.88000000000008
.88000000000009
.88000000000010
.88000000000011
.88000000000100
.88000000000110
.88000000001000
.88000000001100
.88000000001110
.88000000001111
.88000000001110
.88000000011110
.88000000111110
.88000001111110
.88000011111110
.88000111111110
.88001111111110
.88011111111110
.88111111111110
.88111111111110
;
run;
data funny;
set funny;
FORMAT_VALUE= put(ORIGINAL_VALUE, tempfmt.);
run;
proc print data=work.funny noobs;
format ORIGINAL_VALUE comma32.30;
run;
Output is:
ORIGINAL_VALUE | FORMAT_VALUE |
0.879999999999990000000000000000 | H |
0.880000000000000000000000000000 | VH |
0.880000000000010000000000000000 | H |
0.880000000000020000000000000000 | H |
0.880000000000030000000000000000 | H |
0.880000000000040000000000000000 | H |
0.880000000000050000000000000000 | H |
0.880000000000060000000000000000 | H |
0.880000000000070000000000000000 | H |
0.880000000000080000000000000000 | H |
0.880000000000090000000000000000 | H |
0.880000000000100000000000000000 | H |
0.880000000000110000000000000000 | H |
0.880000000001000000000000000000 | H |
0.880000000001100000000000000000 | VH |
0.880000000010000000000000000000 | VH |
0.880000000011000000000000000000 | VH |
0.880000000011100000000000000000 | VH |
0.880000000011110000000000000000 | VH |
0.880000000011100000000000000000 | VH |
0.880000000111100000000000000000 | VH |
0.880000001111100000000000000000 | VH |
0.880000011111100000000000000000 | VH |
0.880000111111100000000000000000 | VH |
0.880001111111100000000000000000 | VH |
0.880011111111100000000000000000 | VH |
0.880111111111100000000000000000 | VH |
0.881111111111100000000000000000 | VH |
0.881111111111100000000000000000 | VH |
Thank you,
Sarat.
Hi @puramsarat
As @yabwon writes, you need to specify a fuzz value. It works with this value:
*fuzz = 0.000000000000001
*value = 0.88000000000001
;
proc format;
value tempfmt (fuzz=0.000000000000001)
low -< 0.205000 = 'VL'
0.205000 -< 0.410000 = 'L'
0.410000 -< 0.645000 = 'M'
0.645000 -< 0.880000 = 'H'
0.880000 - high = 'VH'
other = ' '
;
run;
Hi @puramsarat ,
You entered the "numerical precision errors" ground.
Check out the documentation for the FUZZ= option in the proc format:
All the best
Bart
Hi @puramsarat
As @yabwon writes, you need to specify a fuzz value. It works with this value:
*fuzz = 0.000000000000001
*value = 0.88000000000001
;
proc format;
value tempfmt (fuzz=0.000000000000001)
low -< 0.205000 = 'VL'
0.205000 -< 0.410000 = 'L'
0.410000 -< 0.645000 = 'M'
0.645000 -< 0.880000 = 'H'
0.880000 - high = 'VH'
other = ' '
;
run;
Hi @puramsarat,
I would prefer fuzz=0 in this situation -- following the advice in the documentation (see link in yabwon's post): "A best practice is to use FUZZ=0 when you use the < exclusion operator with numeric formats."
Also, I guess that in practice values such as .87999999999999 or .88000000000001 more often than not are the result of rounding errors, mostly linked to numeric representation issues. I would not rely on them being less or greater than 0.88. Here's an example:
data _null_;
a=1234.88;
v=a-1234;
put v best16.;
run;
Result (SAS 9.4 under Windows):
0.88000000000011
Obviously, the mathematically correct result would be 0.88 and it would be obtained by using the ROUND function appropriately, e.g.
v=round(a-1234, 1e-9);
With "clean" numeric values (as obtained with the ROUND function) your format would much less likely produce incorrect results, even with the default FUZZ= value (1E-12).
April 27 – 30 | Gaylord Texan | Grapevine, Texas
Walk in ready to learn. Walk out ready to deliver. This is the data and AI conference you can't afford to miss.
Register now and lock in 2025 pricing—just $495!
Still thinking about your presentation idea? The submission deadline has been extended to Friday, Nov. 14, at 11:59 p.m. ET.
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.
Ready to level-up your skills? Choose your own adventure.