Hello everyone,
I’m encountering an unexpected rounding behavior when applying the TIME12.3 format to numeric values that share the same decimal part.
For example, consider the values 99.3765 and 67.3765. After applying TIME12.3, I obtain different results:
99.3765 → 0:01:39.377
67.3765 → 0:01:07.376
This suggests that 99.3765 is being rounded up to .377, while 67.3765 is not.
Suspecting a floating-point representation issue, I examined their binary64 representations and converted them back to decimal. The results are:
Both values are stored slightly below 0.3765, so based purely on their numeric representations, neither appears to meet the usual rounding threshold for .377. However, SAS rounds up 99.3765 but not 67.3765.
Does anyone know why TIME12.3 would produce different rounding behavior for these two values? Could this be related to how SAS internally decomposes time values (for example, hours, minutes, seconds) or applies rounding during formatting?
For reference, here is the code I used:
data num;
input value;
datalines;
99.3765
67.3765
;
run;
data time;
set num;
time = put(value, time12.3);
b64 = put(value, binary64.);
run;
Any insight into SAS’s internal rounding logic for time formats would be greatly appreciated.
Interesting observation is that up to 100 minutes the rounding changes several times:
data num;
do i=0 to 1e6;
value=i+0.3765;
output;
end;
format value 12.5;
run;
data time;
set num;
time = put(value, time12.3);
r=scan(time,-1,"."); /* group by rounding */
run;
data time2;
set time;
by r notsorted;
if first.r or last.r then output; /* get start and end of every group */
run;
Printout:
The higher number of seconds the "longer" the group.
Bart
Hi Bart,
Thanks for your input, this is a very interesting experiment. It appears that the flip points occur at powers of two and near minute/second boundaries (e.g., 120, 180, 240). It seems that the internal rounding behavior may be related to the binary64 representation of the data and how SAS handles minute/second carry-over internally.
There a several places that decimal conversions can act oddly. If you see one then it may be that you should round to a desired decimal level before applying an inconsistent format.
Thanks for your input! I agree that the best practice is to use round() to control the decimal precision before applying a TIMEw.d format. I was mainly curious about the underlying logic and implementation details that lead to these edge-case behaviors.
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!
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.