Skip to main content
replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link
URL Rewriter Bot
URL Rewriter Bot

As Bastien Léonard mentionsBastien Léonard mentions for POSIX (go upvote him), C99 N1256 draft 7.23.1/3 also says that:

Go upvote lemonadGo upvote lemonad who said something similar.

As Bastien Léonard mentions for POSIX (go upvote him), C99 N1256 draft 7.23.1/3 also says that:

  • there seems to be no analogue to intmax_t for floating point types: How to get the largest precision floating point data type of implemenation and its printf specifier? So if a larger floating point type comes out tomorrow, it could be used and break your implementation.

  • if clock_t is an integer, the cast to float is well defined to use the nearest float possible. You may lose precision, but it would not matter much compared to the absolute value, and would only happen for huge amounts of time, e.g. long int in x86 is the 80-bit float with 64-bit significant, which is millions of years in seconds.

Go upvote lemonad who said something similar.

As Bastien Léonard mentions for POSIX (go upvote him), C99 N1256 draft 7.23.1/3 also says that:

  • there seems to be no analogue to intmax_t for floating point types: How to get the largest precision floating point data type of implemenation and its printf specifier? So if a larger floating point type comes out tomorrow, it could be used and break your implementation.

  • if clock_t is an integer, the cast to float is well defined to use the nearest float possible. You may lose precision, but it would not matter much compared to the absolute value, and would only happen for huge amounts of time, e.g. long int in x86 is the 80-bit float with 64-bit significant, which is millions of years in seconds.

Go upvote lemonad who said something similar.

edited body
Source Link
Ciro Santilli OurBigBook.com
  • 392.5k
  • 120
  • 1.3k
  • 1.1k
  • there seems to be no analogue to intmax_t for floating point types: How to get the largest precision floating point data type of implemenation and its printf specifier? So if a larger floating point type comes out tomorrow, it could be used and break your implementation.

  • itif clock_t is an integer, the cast to float is well defined to use the nearest float possible. You may lose precision, but it would not matter much compared to the absolute value, and would only happen for huge amounts of time, e.g. long int in x86 is the 80-bit float with 64-bit significant, which is millions of years in seconds.

  • there seems to be no analogue to intmax_t for floating point types: How to get the largest precision floating point data type of implemenation and its printf specifier? So if a larger floating point type comes out tomorrow, it could be used and break your implementation.

  • it clock_t is an integer, the cast to float is well defined to use the nearest float possible. You may lose precision, but it would not matter much compared to the absolute value, and would only happen for huge amounts of time, e.g. long int in x86 is the 80-bit float with 64-bit significant, which is millions of years in seconds.

  • there seems to be no analogue to intmax_t for floating point types: How to get the largest precision floating point data type of implemenation and its printf specifier? So if a larger floating point type comes out tomorrow, it could be used and break your implementation.

  • if clock_t is an integer, the cast to float is well defined to use the nearest float possible. You may lose precision, but it would not matter much compared to the absolute value, and would only happen for huge amounts of time, e.g. long int in x86 is the 80-bit float with 64-bit significant, which is millions of years in seconds.

added 3645 characters in body
Source Link
Ciro Santilli OurBigBook.com
  • 392.5k
  • 120
  • 1.3k
  • 1.1k

There seems to be no perfect way. The root of the problem is that clock_t can be either integer or floating point.

clock_t can be a floating point type

As Bastien Léonard mentions for POSIX (go upvote him), C99 N1256 draft 7.23.1/3 also says that:

[clock_t is] arithmetic types capable of representing times

and 6.2.5/18:

Integer and floating types are collectively called arithmetic types.

and the standard defines arithmetic type as either integers or floating point types.

If you will divide by CLOCKS_PER_SEC, use long double

The return value of clock() is implementation defined, and the only way to get standard meaning out of it is to divide by CLOCKS_PER_SEC to find the number of seconds:

clock_t t0 = clock(); /* Work. */ clock_t t1 = clock(); printf("%Lf", (long double)(t1 - t0)); 

This is good enough, although not perfect, for the two following reasons:

  • there seems to be no analogue to intmax_t for floating point types: How to get the largest precision floating point data type of implemenation and its printf specifier? So if a larger floating point type comes out tomorrow, it could be used and break your implementation.

  • it clock_t is an integer, the cast to float is well defined to use the nearest float possible. You may lose precision, but it would not matter much compared to the absolute value, and would only happen for huge amounts of time, e.g. long int in x86 is the 80-bit float with 64-bit significant, which is millions of years in seconds.

Go upvote lemonad who said something similar.

If you suppose it is an integer, use %ju and uintmax_t

Although unsigned long long is currently the largest standard integer type possible:

clock_t can be a floating point type What could go wrong if it was a double:

  • if too large to fit into the integer, undefined behavior
  • much smaller than 1, will get rounded to 0 and you won't see anything

As @Bastien Léonard mentions for POSIXSince those consequences are much harsher than the integer to float conversion, C99 N1256 draft 7.23using float is likely a better idea.1 paragraph 3 also says that:

[clock_t is] arithmetic types capable of representing times

On glibc 2.21 it is an integer

and 6.2.5 paragraph 18The manual says that using double is a better idea:

IntegerOn GNU/Linux and GNU/Hurd systems, clock_t is equivalent to long int and CLOCKS_PER_SEC is an integer value. But in other systems, both clock_t and the macro CLOCKS_PER_SEC can be either integer or floating-point types are collectively called. Casting CPU time values to double, as in the example above, makes sure that operations such as arithmetic typesand printing work properly and consistently no matter what the underlying representation is.

meaning it is not necessarily an integerIn glibc 2.

And there seems to be no analogue to intmax_t for floating point types21: How to get the largest precision floating point data type of implemenation and its printf specifier?

However, since clock, which returns a clock_t type usually has error much greater than 1 clock, and since in theory clock should return a representation of the number of ticks (which should be an integer value) it is reasonable to suppose that that the rounding error won't be noticeable when using a clock_t that comes from a clock at least.

- [sysdeps/unix/sysv/linux/clock.c](https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/clock.c;h=e568bf354316a5299ad7a3292befc38dede10fbf;hb=4e42b5b8f89f0e288e68be7ad70f9525aebc2cff#l34) calls `__clock_gettime` - [sysdeps/unix/clock_gettime.c](https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/clock_gettime.c;h=29753687dd97ab5a41572bf45343cf37eb7a485a;hb=4e42b5b8f89f0e288e68be7ad70f9525aebc2cff#l115) calls `SYSDEP_GETTIME_CPU` - [sysdeps/unix/sysv/linux/clock_gettime.c](https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/clock_gettime.c;h=57db8ee4d53cd437b3f121b7896f7eb8da0d32dd;hb=4e42b5b8f89f0e288e68be7ad70f9525aebc2cff#l55) calls `SYSCALL_GETTIME` which finally makes an inline system call `man clock_gettime`, tells us that it returns a `struct timespec` which in GCC contains `long int` fields. So the underlying implementation really returns integers. 

Although unsigned long long is currently the largest standard integer type possible:

clock_t can be a floating point type

As @Bastien Léonard mentions for POSIX, C99 N1256 draft 7.23.1 paragraph 3 also says that:

[clock_t is] arithmetic types capable of representing times

and 6.2.5 paragraph 18:

Integer and floating types are collectively called arithmetic types.

meaning it is not necessarily an integer.

And there seems to be no analogue to intmax_t for floating point types: How to get the largest precision floating point data type of implemenation and its printf specifier?

However, since clock, which returns a clock_t type usually has error much greater than 1 clock, and since in theory clock should return a representation of the number of ticks (which should be an integer value) it is reasonable to suppose that that the rounding error won't be noticeable when using a clock_t that comes from a clock at least.

There seems to be no perfect way. The root of the problem is that clock_t can be either integer or floating point.

clock_t can be a floating point type

As Bastien Léonard mentions for POSIX (go upvote him), C99 N1256 draft 7.23.1/3 also says that:

[clock_t is] arithmetic types capable of representing times

and 6.2.5/18:

Integer and floating types are collectively called arithmetic types.

and the standard defines arithmetic type as either integers or floating point types.

If you will divide by CLOCKS_PER_SEC, use long double

The return value of clock() is implementation defined, and the only way to get standard meaning out of it is to divide by CLOCKS_PER_SEC to find the number of seconds:

clock_t t0 = clock(); /* Work. */ clock_t t1 = clock(); printf("%Lf", (long double)(t1 - t0)); 

This is good enough, although not perfect, for the two following reasons:

  • there seems to be no analogue to intmax_t for floating point types: How to get the largest precision floating point data type of implemenation and its printf specifier? So if a larger floating point type comes out tomorrow, it could be used and break your implementation.

  • it clock_t is an integer, the cast to float is well defined to use the nearest float possible. You may lose precision, but it would not matter much compared to the absolute value, and would only happen for huge amounts of time, e.g. long int in x86 is the 80-bit float with 64-bit significant, which is millions of years in seconds.

Go upvote lemonad who said something similar.

If you suppose it is an integer, use %ju and uintmax_t

Although unsigned long long is currently the largest standard integer type possible:

What could go wrong if it was a double:

  • if too large to fit into the integer, undefined behavior
  • much smaller than 1, will get rounded to 0 and you won't see anything

Since those consequences are much harsher than the integer to float conversion, using float is likely a better idea.

On glibc 2.21 it is an integer

The manual says that using double is a better idea:

On GNU/Linux and GNU/Hurd systems, clock_t is equivalent to long int and CLOCKS_PER_SEC is an integer value. But in other systems, both clock_t and the macro CLOCKS_PER_SEC can be either integer or floating-point types. Casting CPU time values to double, as in the example above, makes sure that operations such as arithmetic and printing work properly and consistently no matter what the underlying representation is.

In glibc 2.21:

- [sysdeps/unix/sysv/linux/clock.c](https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/clock.c;h=e568bf354316a5299ad7a3292befc38dede10fbf;hb=4e42b5b8f89f0e288e68be7ad70f9525aebc2cff#l34) calls `__clock_gettime` - [sysdeps/unix/clock_gettime.c](https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/clock_gettime.c;h=29753687dd97ab5a41572bf45343cf37eb7a485a;hb=4e42b5b8f89f0e288e68be7ad70f9525aebc2cff#l115) calls `SYSDEP_GETTIME_CPU` - [sysdeps/unix/sysv/linux/clock_gettime.c](https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/clock_gettime.c;h=57db8ee4d53cd437b3f121b7896f7eb8da0d32dd;hb=4e42b5b8f89f0e288e68be7ad70f9525aebc2cff#l55) calls `SYSCALL_GETTIME` which finally makes an inline system call `man clock_gettime`, tells us that it returns a `struct timespec` which in GCC contains `long int` fields. So the underlying implementation really returns integers. 
added 35 characters in body
Source Link
Ciro Santilli OurBigBook.com
  • 392.5k
  • 120
  • 1.3k
  • 1.1k
Loading
deleted 74 characters in body
Source Link
Ciro Santilli OurBigBook.com
  • 392.5k
  • 120
  • 1.3k
  • 1.1k
Loading
added 168 characters in body
Source Link
Ciro Santilli OurBigBook.com
  • 392.5k
  • 120
  • 1.3k
  • 1.1k
Loading
added 211 characters in body
Source Link
Ciro Santilli OurBigBook.com
  • 392.5k
  • 120
  • 1.3k
  • 1.1k
Loading
deleted 2 characters in body
Source Link
Ciro Santilli OurBigBook.com
  • 392.5k
  • 120
  • 1.3k
  • 1.1k
Loading
added 4 characters in body
Source Link
Ciro Santilli OurBigBook.com
  • 392.5k
  • 120
  • 1.3k
  • 1.1k
Loading
Source Link
Ciro Santilli OurBigBook.com
  • 392.5k
  • 120
  • 1.3k
  • 1.1k
Loading