Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 什么&x2019;使用printf打印时钟的正确方法是什么?_C_Io_Printf_Clock - Fatal编程技术网

C 什么&x2019;使用printf打印时钟的正确方法是什么?

C 什么&x2019;使用printf打印时钟的正确方法是什么?,c,io,printf,clock,C,Io,Printf,Clock,我目前正在使用显式转换到unsigned long long并使用%llu打印它,但是既然size\u t有%z说明符,为什么clock\u t没有呢 甚至连宏都没有。也许我可以假设在x64系统(操作系统和CPU)上,size\u t的长度为8字节(即使在这种情况下,他们也提供了%z),但是clock\u t呢?这可能是因为时钟信号不是一个很好定义的单位。您可以将其转换为秒,并以双精度打印: time_in_seconds = (double)time_in_clock_ticks / (dou

我目前正在使用显式转换到
unsigned long long
并使用
%llu
打印它,但是既然
size\u t
%z
说明符,为什么
clock\u t
没有呢


甚至连宏都没有。也许我可以假设在x64系统(操作系统和CPU)上,
size\u t
的长度为8字节(即使在这种情况下,他们也提供了
%z
),但是
clock\u t
呢?

这可能是因为时钟信号不是一个很好定义的单位。您可以将其转换为秒,并以双精度打印:

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

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

据我所知,您的做法是最好的。除了
clock\t
可能是实型之外:

time\u t
clock\u t
应为整数或实浮点型


C标准必须适应各种各样的体系结构,这使得除了内部时钟类型是算术型之外,无法做出任何进一步的保证

在大多数情况下,您对时间间隔感兴趣,因此我将时钟滴答声的差值转换为毫秒。
无符号长的
即使是32位,也足以表示将近50天的间隔,因此对于大多数情况,它应该足够大:

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;
}

似乎没有完美的方法。问题的根源在于
clock\t
可以是整数或浮点

时钟可以是浮点类型

至于POSIX(投票给他),7.23.1/3还说:

[clock_t]是能够表示时间的算术类型

和6.2.5/18:

整数和浮点类型统称为算术类型

该标准将算术类型定义为整数或浮点类型

如果要除以时钟每秒,请使用长双精度

clock()
的返回值是由实现定义的,从中获得标准含义的唯一方法是除以
CLOCKS\u PER\u second
以找到秒数:

clock_t t0 = clock();
/* Work. */
clock_t t1 = clock();
printf("%Lf", (long double)(t1 - t0));
这已经足够好了,尽管还不够完美,但有以下两个原因:

  • 浮点类型似乎没有类似于
    intmax\u t
    :因此,如果明天出现更大的浮点类型,它可能会被使用并破坏您的实现

  • 如果
    clock\t
    是一个整数,则转换为float的定义很好,可以使用最接近的float。您可能会失去精度,但与绝对值相比,这并不重要,而且只会在大量时间内发生,例如,x86中的
    long int
    是80位浮点值和64位有效值,即数百万年(以秒计)

他说了类似的话

如果假设它是一个整数,请使用%ju和uintmax\u t

尽管
unsigned long
是目前可能的最大标准整数类型:

#include <stdint.h>

printf("%ju", (uintmax_t)(clock_t)1);
  • 将来可能会有一个更大的
  • 该标准已经(对@fuzzxl的赞誉)并且
    clock\t
    可能是其中之一
因此,最好将类型转换为可能的最大无符号整数类型:

#include <stdint.h>

printf("%ju", (uintmax_t)(clock_t)1);
#包括
printf(“%ju”,(uintmax)(时钟)1);
uintmax\u t
保证具有机器上可能的最大整数大小

uintmax\u t
及其printf说明符
%ju
是在c99中引入的,例如gcc实现了它们

作为奖励,这一次性解决了如何可靠地
printf
整数类型的问题(不幸的是
clock\u t
不一定如此)

如果是双精度的,会出现什么问题:

time_in_seconds = (double)time_in_clock_ticks / (double)CLOCKS_PER_SEC;
printf("%g seconds", seconds);
  • 如果太大而无法放入整数,则表示行为未定义
  • 远小于1,将四舍五入为0,您将看不到任何内容
由于这些结果比整数到浮点的转换要苛刻得多,所以使用浮点可能是一个更好的主意

在glibc 2.21上,它是一个整数

手册上说,使用
double
是一个更好的主意:

在GNU/Linux和GNU/Hurd系统上,clock_t相当于long int,CLOCKS_PER_SEC是一个整数值。但在其他系统中,时钟和宏时钟每秒都可以是整数或浮点类型。如上例所示,将CPU时间值强制转换为双倍,可以确保算术和打印等操作正常、一致地工作,而不管底层表示是什么

在glibc 2.21中:

  • clock\u t
    long int

    • 将其设置为
      \uu clock\t
    • 将其设置为
      \u时钟\u类型
    • 将其设置为
      \uuu SLONGWORD\u TYPE
    • 将其设置为
      long int
  • Linux中的
    clock()
    是通过
    sys\u clock\u gettime
    实现的:

    • 调用
      \u时钟\u获取时间
    • 调用SYSDEP\u GETTIME\u CPU
    • 调用
      SYSCALL\u GETTIME
      ,最终进行内联系统调用
    manclock\u gettime
    告诉我们它返回一个
    struct timespec
    ,它在GCC中包含
    long int
    字段

    因此,底层实现实际上返回整数

另请参见


说得很好,我已经忘记了它可能是浮点类型。有没有一种方法可以获得尽可能高精度的浮点类型,并且它的说明符可以用于具有
uintmax\t
%ju
的整数?那就是