什么是正确的方式使用printf打印clock_t?
题
目前,我正在使用一个明确的投到 unsigned long long
和使用 %llu
打印,但是由于 size_t
有的 %z
说明,为什么不 clock_t
有一个吗?
甚至没有一个宏观。也许我可以假设,在64系统(OS和CPU) size_t
8字节的长度(而且,即使在这种情况下,他们提供 %z
的),但是什么有关 clock_t
?
解决方案
似乎没有完美的方式。根本的问题是 clock_t
可能是整数或浮点。
clock_t可以是一个浮点类型
作为 Bastien Léonard提到 为POSIX(去投票他), C99N1256草案 7.23.1/3还说:
[clock_t是]算类型的能够代表倍
和6.2.5/18:
整和浮动类型统称为算术的类型。
和标准界定的算术类型,无论是作为整数或浮点类型。
如果你将通过CLOCKS_PER_SEC,使用双长
回值 clock()
是执行定义,只有这样,才能获得标准的含义是除 CLOCKS_PER_SEC
找到多少秒:
clock_t t0 = clock();
/* Work. */
clock_t t1 = clock();
printf("%Lf", (long double)(t1 - t0));
这个足够好,虽然不完美,对于以下两个原因:
似乎没有任何模
intmax_t
对于浮点类型: 如何获得最大的精度浮点的数据类型的执行和其printf符? 因此,如果一个较大的浮点类型出来的明天,这可能是使用,并打破你的实现。如果
clock_t
是一个整数,转换为浮动是很好的定义使用的最近的浮动可能的。你可能会失去精确,但它不会有问题很相比的绝对值,而只会发生大量的时间,例如long int
在x86是80位浮动有64位重要,这是数百万年在几秒钟内。
去投票lemonad 谁说类似的东西。
如果你假设它是一个整数、使用%ju和uintmax_t
虽然 unsigned long long
是目前最大的标准整数类型的可能:
- 一个较大的一个会出来的未来
- 标准已经 明确允许更大的执行情况定义的类型 (荣誉@FUZxxl)和
clock_t
可能是他们中的一个
所以它是最佳类型转换的最大unsigned integer类型可能:
#include <stdint.h>
printf("%ju", (uintmax_t)(clock_t)1);
uintmax_t
为保证具有大小尽可能大的整数的大小机器上。
uintmax_t
和其printf符 %ju
介绍了在c99和海湾合作委员会为例子实现他们。
作为奖励,这种解决了一次对所有的问题如何可靠地 printf
整数类型(其是遗憾的是没有一定的情况 clock_t
).
有什么可以去错误的,如果它是一个双:
- 如果太大,不适合成整数,未定义的行为
- 远小于1,将获得圆到0,你会看不到任何东西
由于这些后果都严厉得多于整数的浮动转换,使用浮动可能是一个更好的主意。
在glibc2.21它是一个整数
该手册说,使用 double
是一个更好的想法:
在GNU/Linux与GNU/Hurd系统,clock_t相当于长int和CLOCKS_PER_SEC是一个整数值。但在其它系统中,两clock_t和宏CLOCKS_PER_SEC可能是整数或浮点类型。铸造CPU时间值的一倍,因为在上面的例子中,可以确保作业如,算术和印刷工作的正确和一贯无论在什么基础的代表性。
在glibc2.21:
clock_t
是long int
:- 时间/时间。h 集到
__clock_t
- 比特/类型。h 集到
__CLOCK_T_TYPE
- 比特/typesizes.h 集到
__SLONGWORD_TYPE
- 比特/类型。h 集到
long int
- 时间/时间。h 集到
clock()
在Linux的实施与sys_clock_gettime
:- sysdeps/unix/sysv/linux/钟。c 电话
__clock_gettime
- sysdeps/unix/clock_gettime.c 电话
SYSDEP_GETTIME_CPU
- sysdeps/unix/sysv/linux/clock_gettime.c 电话
SYSCALL_GETTIME
这最后使得联系电话
man clock_gettime
, 告诉我们,它返回struct timespec
这在海湾合作委员会中包含long int
领域。所以基础实现真正的返回整数。
- sysdeps/unix/sysv/linux/钟。c 电话
也参看
其他提示
据我所知,你正在做的方式是最好的。不同之处在于clock_t
可以是实数型:
和
time_t
clock_t
应整数或实浮点型。
http://www.opengroup.org/onlinepubs/ 009695399 / basedefs / SYS / types.h.html
这可能是因为时钟滴答是不是一个很好定义的单元。可以将其转换为秒和打印为双:
time_in_seconds = (double)time_in_clock_ticks / (double)CLOCKS_PER_SEC;
printf("%g seconds", seconds);
在CLOCKS_PER_SEC宏扩展到表示时钟的节拍在第二数量的表达式。
C标准具有以适应各种各样的架构,这使得它不可能从一个事实,即内部时钟类型是算术作任何进一步的保证预留。
在大多数情况下,你感兴趣的时间间隔,所以在时钟滴答到毫秒我要转换的差异。一个unsigned long
大到足以代表的近50天,即使它的32位的时间间隔,所以它应该是足够大多数情况下:
clock_t start;
clock_t end;
unsigned long millis = (end - start) * 1000 / CLOCKS_PER_SEC;
的一种方式是通过使用gettimeofday
功能。人们可以使用该功能发现的区别是:
unsigned long diff(struct timeval second, struct timeval first)
{
struct timeval lapsed;
struct timezone tzp;
unsigned long t;
if (first.tv_usec > second.tv_usec) {
second.tv_usec += 1000000;
second.tv_sec--;
}
lapsed.tv_usec = second.tv_usec - first.tv_usec;
lapsed.tv_sec = second.tv_sec - first.tv_sec;
t = lapsed.tv_sec*1000000 + lapsed.tv_usec;
printf("%lu,%lu - %lu,%lu = %ld,%ld\n",
second.tv_sec, second.tv_usec,
first.tv_sec, first.tv_usec,
lapsed.tv_sec, lapsed.tv_usec);
return t;
}