Frage

Ich bin derzeit eine explizite Umwandlung verwenden zu unsigned long long und %llu verwenden, es zu drucken, aber da size_t den %z Spezifizierer, warum clock_t kein Konto habe?

Es gibt nicht einmal ein Makro dafür. Vielleicht kann ich das auf einem x64-System (OS und CPU) übernehmen size_t ist 8 Byte lang (und auch in diesem Fall haben sie %z zur Verfügung gestellt), aber was ist clock_t?

War es hilfreich?

Lösung

Es scheint kein perfekter Weg zu sein. Die Wurzel des Problems ist, dass clock_t entweder Ganzzahl- oder Gleitkomma- sein kann.

clock_t kann einen Gleitkomma-Typ sein

Wie Bastien Léonard erwähnt für POSIX (ihn gehen upvote), C99 N1256 Entwurf 7.23.1 / 3 sagt auch, dass:

  

[clock_t ist] arithmetischer Typ fähig Zeiten darstellen

und 6.2.5 / 18:

  

Integer- und Fließ-Typen werden gemeinsam arithmetische Typen genannt.

und der Standard definiert arithmetischen Typen entweder als ganze Zahlen oder die Gleitkommaeinheit-Typen.

Wenn Sie mit dem CLOCKS_PER_SEC teilen werden, verwenden Sie lange doppelte

Der Rückgabewert von clock() ist Implementierung definiert, und die einzige Möglichkeit, Standardbedeutung, um aus der es durch CLOCKS_PER_SEC zu teilen ist die Anzahl der Sekunden zu finden:

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

Das ist gut genug, wenn auch nicht perfekt, für die beiden folgenden Gründe:

  • es scheint kein Analogon zu sein für Gleitkomma-Typen intmax_t: Wie die größte precision floating point Datentyp Implemenation und seine printf Spezifizierer zu bekommen? Also, wenn ein größerer Gleitkommatyps aus morgen kommt, könnte es sein, gebraucht und brechen Sie Ihre Implementierung.

  • Wenn clock_t eine ganze Zahl ist, wird der Guss zu schweben gut definiert, um den nächsten Schwimmer möglich zu nutzen. Sie können Präzision verlieren, aber es wäre viel im Vergleich zu dem absoluten Wert keine Rolle, und nur für große Mengen an Zeit passieren würden, z.B. long int in x86 sind die 80-Bit-Float mit 64-Bit signifikant, was Millionen von Jahren in Sekunden.

  • ist

Go upvote Lemonad , der sagte etwas ähnliches.

Wenn Sie annehmen, es eine ganze Zahl ist, verwenden% ju und uintmax_t

Obwohl unsigned long long ist derzeit der größte Standard-Integer-Typ möglich:

so ist es am besten zu dem größten unsigned Integer-Typ typisieren möglich:

#include <stdint.h>

printf("%ju", (uintmax_t)(clock_t)1);

uintmax_t garantiert die Größe der größten möglichen ganzzahligen Größe auf der Maschine haben.

uintmax_t und seine printf Spezifizierer %ju wurden in c99 und gcc zum Beispiel setzt sie eingeführt wird.

Als Bonus löst dies ein für alle Mal die Frage, wie zuverlässig printf Integer-Typen (die leider nicht das unbedingt der Fall für clock_t).

Was schief gehen könnte, wenn es war eine doppelte:

  • , wenn sie zu groß sind, um in die ganze Zahl, nicht definiertes Verhalten
  • viel kleiner als 1 ist, wird auf 0 erhalten gerundet und Sie werden nichts sehen

Da diese Folgen viel härter sind als die ganze Zahl Umwandlung zu schweben, schwimmen mit wahrscheinlich eine bessere Idee.

Auf glibc 2.21 ist eine ganze Zahl

Das Handbuch sagt, dass double verwendet, ist eine bessere Idee:

  

Auf GNU / Linux und GNU / Hurd-Systemen ist clock_t entspricht long int und CLOCKS_PER_SEC ist ein Integer-Wert. Aber auch in anderen Systemen, sowohl clock_t und das Makro CLOCKS_PER_SEC können entweder integer oder Gleitkommatypen sein. Casting CPU-Zeit-Werte zu verdoppeln, wie im Beispiel oben, sorgt dafür, dass Operationen wie arithmetische und Druckarbeiten ordnungsgemäß und consistently egal, was die zugrundeliegende Repräsentation ist.

In glibc 2.21:

Siehe auch

Andere Tipps

Soweit ich weiß, wie du tust ist die beste. Abgesehen davon, dass clock_t ein echter Typ sein kann:

  

time_t und clock_t sollen seine integer oder real-Floating-Typen.

http://www.opengroup.org/onlinepubs/ 009695399 / basedefs / sys / types.h.html

Es ist wahrscheinlich, weil Uhr tickt ist keine sehr gut definierte Einheit. Sie können es auf Sekunden konvertieren und es als Doppel drucken:

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

Die CLOCKS_PER_SEC Makro wird auf einen Ausdruck der Anzahl von Takt darstellt Zecken in einer Sekunde.

Der C-Standard verfügt über eine Vielzahl von Architekturen zu empfangen, was es unmöglich macht beiseite weitere Garantien machen von der Tatsache, dass der interne Takt Typ Arithmetik ist.

In den meisten Fällen sind Sie in Zeitintervallen interessiert, so würde ich den Unterschied konvertieren in Takt zu Millisekunden Zecken. Ein unsigned long ist groß genug, ein Intervall von fast 50 Tagen, auch wenn sein 32-Bit darstellen, so sollte es für die meisten Fälle groß genug sein:

clock_t start;
clock_t end;
unsigned long millis = (end - start) * 1000 / CLOCKS_PER_SEC;

Eine Möglichkeit besteht darin, die gettimeofday Funktion. Man kann den Unterschied mit dieser Funktion finden:

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;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top