CoS*_*oCo 1 c formatting time printf
我想从一个双精度点打印一个以分钟和秒为单位的时间,包括它们的小数部分(最多6位),而不用零结尾。
由于格式的本质,应该有可能在单个printf()语句中将解决方案嵌套在其他参数中!
我要打印的时间变量是秒单位的两倍,并且不超过几十小时的范围。
double time1 = 123.456789; // 2:03.456789 some text
double time2 = 12345.6; // 205:45.6 some text
printf("format: %-16s time1: %.6g some text\n", "%.6g", time1);
printf("format: %-16s time2: %.6g some text\n", "%.6g", time2);
printf("format: %-16s time1: %3d:%09.6f some text\n", "%3d:%09.6f", (int)time1 / 60, fmod(time1, 60));
printf("format: %-16s time2: %3d:%09.6f some text\n", "%3d:%09.6f", (int)time2 / 60, fmod(time2, 60));
printf("format: %-16s time1: %3d:%09.6g some text\n", "%3d:%09.6g", (int)time1 / 60, fmod(time1, 60));
printf("format: %-16s time2: %3d:%09.6g some text\n", "%3d:%09.6g", (int)time2 / 60, fmod(time2, 60));
printf("format: %-16s time1: %3d:%0.6g some text\n", "%3d:%0.6g", (int)time1 / 60, fmod(time1, 60));
printf("format: %-16s time2: %3d:%0.6g some text\n", "%3d:%0.6g", (int)time2 / 60, fmod(time2, 60));
printf("format: %-16s time1: %3d:%02d%.6f some text\n", "%3d:%02d%.6f", (int)time1 / 60, (int)time1 % 60, fmod(time1, 1));
printf("format: %-16s time2: %3d:%02d%.6f some text\n", "%3d:%02d%.6f", (int)time2 / 60, (int)time2 % 60, fmod(time2, 1));
printf("format: %-16s time1: %3d:%02d%.6g some text\n", "%3d:%02d%.6g", (int)time1 / 60, (int)time1 % 60, fmod(time1, 1));
printf("format: %-16s time2: %3d:%02d%.6g some text\n", "%3d:%02d%.6g", (int)time2 / 60, (int)time2 % 60, fmod(time2, 1));
printf("format: %-16s time1: %3d:%02d%0.6g some text\n", "%3d:%02d%0.6g", (int)time1 / 60, (int)time1 % 60, fmod(time1, 1));
printf("format: %-16s time2: %3d:%02d%0.6g some text\n", "%3d:%02d%0.6g", (int)time2 / 60, (int)time2 % 60, fmod(time2, 1));
Run Code Online (Sandbox Code Playgroud)
预期:
time1: 2:03.456789 some text
time2: 205:45.6 some text
Run Code Online (Sandbox Code Playgroud)
结果:
format: %.6g time1: 123.457 some text
format: %.6g time2: 12345.6 some text
format: %3d:%09.6f time1: 2:03.456789 some text <- OK
format: %3d:%09.6f time2: 205:45.600000 some text <- trailing zeros
format: %3d:%09.6g time1: 2:003.45679 some text <- 3 digits for minutes, missing 8
format: %3d:%09.6g time2: 205:0000045.6 some text <- 7 digits for minutes
format: %3d:%0.6g time1: 2:3.45679 some text <- 1 digit for minutes, missing 8
format: %3d:%0.6g time2: 205:45.6 some text <- OK
format: %3d:%02d%.6f time1: 2:030.456789 some text <- leading 0
format: %3d:%02d%.6f time2: 205:450.600000 some text <- leading 0, trailing zeros
format: %3d:%02d%.6g time1: 2:030.456789 some text <- leading 0
format: %3d:%02d%.6g time2: 205:450.6 some text <- leading 0
format: %3d:%02d%0.6g time1: 2:030.456789 some text <- leading 0
format: %3d:%02d%0.6g time2: 205:450.6 some text <- leading 0
Run Code Online (Sandbox Code Playgroud)
另一种格式会很好:
time2: 3:25:45.6 some text
Run Code Online (Sandbox Code Playgroud)
对于正的时间值,请尝试以下格式:
printf("%d:%d%g\n",
(int)time / 60, // number of minutes
(int)time % 60 / 10, // number of tens of seconds
time - (int)time / 10 * 10); // number of seconds units and fraction thereof
Run Code Online (Sandbox Code Playgroud)
但是请注意,如果分数值大于或等于该值将不起作用,0.9999995因为最后一项将舍入到下一个整数。
将时间转换为整数微秒并以这种方式打印会更安全:
int us = (int)(time * 1000000 + 0.5);
printf("%d:%02d.%06d\n", us / 60000000, us / 1000000 % 60, us % 1000000);
Run Code Online (Sandbox Code Playgroud)
用这种方法去掉尾随的零点会更加乏味,恐怕使用函数会更好。正确处理无限值和nan等极端情况并保持正确的舍入是很难的。
这是一个测试程序的示例:
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// print a time in minutes and seconds with up to <places> decimal places and correct rounding
char *format_time(char *dest, size_t size, double time, int places) {
char buf[400];
int len = snprintf(buf, sizeof buf, "%.*f", places, time);
int sign = (*buf == '-');
char *p = strchr(buf, '.');
if (p != NULL) {
*p = '\0';
double rounded_time = atof(buf + sign);
double seconds = fmod(rounded_time, 60);
double minutes = (rounded_time - seconds) / 60;
*p = '.';
len -= (p - buf);
while (p[len - 1] == '0')
len--;
if (len == 1)
len--;
snprintf(dest, size, "%.*s%.0f:%02.0f%.*s",
sign, buf, minutes, seconds, len, p);
} else {
snprintf(dest, size, "%s", buf);
}
return dest;
}
#ifndef DBL_MAX
#define DBL_MAX 1.7976931348623157e+308
#endif
int main() {
double a[] = {
0, 1, 59, 60, 61,
121.1, 121.11, 121.111, 121.1111, 121.11111, 121.111111,
4321.0, 12345.6, 123.456789,
129.9999994, 129.9999995,
599.9999994, 599.9999995, 599.99999951, 599.9999999,
23.9999999999, 59.9999994, 59.9999996,
999.0000005, 1000.0000005, 999.9999999,
1e6, 1e10, 1e12, 1e15, 1e18, 1e20, 1e25, 1e30,
INT_MAX * 60.0, INT_MAX * 60.0 + 1234,
(double)ULLONG_MAX * 64.0, DBL_MAX, 1.0 / 0.0, (double)NAN,
};
for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); i++) {
char buf[400];
printf("%32.16g --> %s\n", a[i], format_time(buf, sizeof buf, a[i], 6));
printf("%32.16g --> %s\n", -a[i], format_time(buf, sizeof buf, -a[i], 6));
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
0-> 0:00
-0-> -0:00
1-> 0:01
-1-> -0:01
59-> 0:59
-59-> -0:59
60-> 1:00
-60-> -1:00
61-> 1:01
-61-> -1:01
121.1-> 2:01.1
-121.1-> -2:01.1
121.11-> 2:01.11
-121.11-> -2:01.11
121.111-> 2:01.111
-121.111-> -2:01.111
121.1111-> 2:01.1111
-121.1111-> -2:01.1111
121.11111-> 2:01.11111
-121.11111-> -2:01.11111
121.111111-> 2:01.111111
-121.111111-> -2:01.111111
4321-> 72:01
-4321-> -72:01
12345.6-> 205:45.6
-12345.6-> -205:45.6
123.456789-> 2:03.456789
-123.456789-> -2:03.456789
129.9999994-> 2:09.999999
-129.9999994-> -2:09.999999
129.9999995-> 2:10
-129.9999995-> -2:10
599.9999994-> 9:59.999999
-599.9999994-> -9:59.999999
599.9999994999999-> 9:59.999999
-599.9999994999999-> -9:59.999999
599.99999951-> 10:00
-599.99999951-> -10:00
599.9999999-> 10:00
-599.9999999-> -10:00
23.9999999999-> 0:24
-23.9999999999-> -0:24
59.9999994-> 0:59.999999
-59.9999994-> -0:59.999999
59.9999996-> 1:00
-59.9999996-> -1:00
999.0000005000001-> 16:39.000001
-999.0000005000001-> -16:39.000001
1000.0000005-> 16:40.000001
-1000.0000005-> -16:40.000001
999.9999999-> 16:40
-999.9999999-> -16:40
1000000-> 16666:40
-1000000-> -16666:40
10000000000-> 166666666:40
-10000000000-> -166666666:40
1000000000000-> 16666666666:40
-1000000000000-> -16666666666:40
1000000000000000-> 16666666666666:40
-1000000000000000-> -16666666666666:40
1e + 18-> 16666666666666666:40
-1e + 18-> -16666666666666666:40
1e + 20-> 1666666666666666752:40
-1e + 20-> -1666666666666666752:40
1e + 25-> 166666666666666697424896:04
-1e + 25-> -166666666666666697424896:04
1e + 30-> 16666666666666666704873979904:16
-1e + 30-> -16666666666666666704873979904:16
128849018820-> 2147483647:00
-128849018820-> -2147483647:00
128849020054-> 2147483667:34
-128849020054-> -2147483667:34
1.180591620717411e + 21-> 19676527011956854784:04
-1.180591620717411e + 21-> -19676527011956854784:04
1.797693134862316e + 308-> 2996155224770526471302168869341711813188863443303040828151933426890179148788615168103226874770040896498710950234612783266345520226229959458788419419124700807563385759480436831271585473539816641201208858853854529842024245866346857407520574852654654654752654654654654760752752654654654-230-8257608251
-1.797693134862316e + 308-> -29961552247705264713021688693417118131888634433030408281519334268901791487886151681032268747700700964964109502346127832663455202262299594587884194197007005633857594804368312760854735398166412012088488524438545298420245258684256784275245080654654654654654752654654654654654654842842842654842654654654752842842654654654692842654690692654692094654654692094654685692654692654692654692654692654692654692654692654692654654654692654654654692685692654654654692654692654692654654654692654692654692654692654692654654690842654690692685692685692
inf-> inf
-inf-> -inf
楠->楠
楠->楠
| 归档时间: |
|
| 查看次数: |
144 次 |
| 最近记录: |