3 回答
TA贡献1826条经验 获得超6个赞
似乎没有完美的方法。问题的根源clock_t
可以是整数或浮点数。
clock_t可以是浮点类型
正如BastienLéonard在POSIX中提到的(赞成他),C99 N1256草案 7.23.1 / 3也说:
[clock_t是]能够表示时间的算术类型
和6.2.5 / 18:
整数和浮点类型统称为算术类型。
该标准将算术类型定义为整数或浮点类型。
如果要除以CLOCKS_PER_SEC,请使用long double
返回值clock()
是实现定义的,唯一获得标准含义的方法是除以CLOCKS_PER_SEC
秒数:
clock_t t0 = clock();/* Work. */clock_t t1 = clock();printf("%Lf", (long double)(t1 - t0));
由于以下两个原因,这虽然不够完美,但却足够好:
似乎没有类似于
intmax_t
浮点类型的方法:如何获得实现的最大精度浮点数据类型及其printf标识符?因此,如果明天出现更大的浮点类型,则可以使用它并破坏您的实现。如果
clock_t
为整数,则将float强制转换为尽可能使用最近的float。您可能会失去精度,但是与绝对值相比并没有多大关系,只会发生大量时间,例如,long int
在x86中,80位浮点数具有64位有效值,数百万年以秒为单位。
如果您认为它是整数,请使用%ju和uintmax_t
尽管unsigned long long
目前是可能的最大标准整数类型:
将来可能会出现更大的一个
该标准已经明确允许更大的实现定义类型(@FUZxxl的荣誉),并且
clock_t
可能是其中之一
因此,最好将类型转换为最大的无符号整数类型:
#include <stdint.h>printf("%ju", (uintmax_t)(clock_t)1);
uintmax_t
确保机器上具有最大可能的整数大小。
uintmax_t
它的printf说明符%ju
在c99中引入,例如gcc实现了它们。
另外,这可以彻底解决如何可靠地对printf
类型进行整数处理的问题(不幸的是,不一定是这种情况clock_t
)。
如果是双重的话可能会出问题:
如果太大而无法容纳整数,不确定的行为
小于1的数字将四舍五入为0,您将看不到任何内容
由于这些后果比整数到浮点数转换要严重得多,因此使用浮点数可能是一个更好的主意。
在glibc 2.21上,它是一个整数
手册说使用double
是一个更好的主意:
在GNU / Linux和GNU / Hurd系统上,clock_t等效于long int,而CLOCKS_PER_SEC是整数。但是在其他系统中,clock_t和宏CLOCKS_PER_SEC都可以是整数或浮点类型。如上面的示例中所示,将CPU时间值强制转换为两倍,可确保无论基础表示是什么,算术和打印之类的操作都能正常且一致地工作。
在glibc 2.21中:
clock_t
是long int
:time / time.h将其设置为
__clock_t
bits / types.h将其设置为
__CLOCK_T_TYPE
bits / typesizes.h将其设置为
__SLONGWORD_TYPE
bits / types.h将其设置为
long int
clock()
在Linux中是通过sys_clock_gettime
以下方式实现的:man clock_gettime
,告诉我们它struct timespec
在GCC中返回包含long int
字段的。因此,底层实现实际上返回整数。
sysdeps / unix / sysv / linux / clock.c调用
__clock_gettime
sysdeps / unix / clock_gettime.c调用
SYSDEP_GETTIME_CPU
sysdeps / unix / sysv / linux / clock_gettime.c调用
SYSCALL_GETTIME
最终会进行内联系统调用
也可以看看
TA贡献1982条经验 获得超2个赞
可能是因为时钟节拍不是一个定义明确的单位。您可以将其转换为秒并打印为双精度:
time_in_seconds = (double)time_in_clock_ticks / (double)CLOCKS_PER_SEC;printf("%g seconds", seconds);
CLOCKS_PER_SEC宏扩展为一个表达式,表示一秒钟的时钟滴答数。
- 3 回答
- 0 关注
- 2115 浏览
添加回答
举报