为了账号安全,请及时绑定邮箱和手机立即绑定

使用printf打印clock_t的正确方法是什么?

使用printf打印clock_t的正确方法是什么?

C iOS
ibeautiful 2019-09-26 11:01:00
使用printf打印clock_t的正确方法是什么?我当前正在使用显式强制转换unsigned long long并%llu用于打印它,但是既然size_t有说明%z符,为什么没有clock_t一个?甚至没有宏。也许我可以假设在x64系统(操作系统和CPU)size_t上长度为8个字节(即使在这种情况下,它们也提供了%z),但是那又如何clock_t呢?
查看完整描述

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目前是可能的最大标准整数类型:

因此,最好将类型转换为最大的无符号整数类型:

#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中:

也可以看看


查看完整回答
反对 回复 2019-09-26
?
临摹微笑

TA贡献1982条经验 获得超2个赞

可能是因为时钟节拍不是一个定义明确的单位。您可以将其转换为秒并打印为双精度:

time_in_seconds = (double)time_in_clock_ticks / (double)CLOCKS_PER_SEC;printf("%g seconds", seconds);

CLOCKS_PER_SEC宏扩展为一个表达式,表示一秒钟的时钟滴答数。


查看完整回答
反对 回复 2019-09-26
  • 3 回答
  • 0 关注
  • 2115 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信