C - время до uint64_t - PullRequest
       11

C - время до uint64_t

4 голосов
/ 21 апреля 2020

Утро!

Я пытаюсь получить наносекундную метку времени (uint64_t) из структуры timeval.

    struct timeval t;
    // initialized so that ....
    print("t sec: %ld, micro sec: %ld", t.tv_sec, t.tv_usec);
    // .... prints "t sec: 4, micro sec: 130728"

    long int sec = (long int) t.tv_sec;
    // just did that because I thought that using time_t in calculations may cause errors
    // print("%ld", sec) -> 4, so this seems to work as expected    

    uint64_t t_int = (sec * 1000000 + t.tv_usec) * 1000; // should be nanoseconds
    print("t_int (uint64_t) %llu", t_int);
    // prints "t_int (uint64_t) 18446744073545312320"

Мои временные интервалы обязательно должны соответствовать uint64_t. Кроме того, приведение к long int из time_t работает, поэтому все, что я делаю, это простой расчет с двумя длинными целыми числами, помещая результат в uint64_t, поэтому я не уверен, почему я получаю явно неправильное значение. Любые идеи? Это просто неправильный способ форматирования (с% llu)?

Ответы [ 2 ]

3 голосов
/ 21 апреля 2020

Либо:

uint64_t t_int = ((uint64_t)t.tv_sec * 1000000 + t.tv_usec) * 1000;

, либо:

uint64_t t_int = (t.tv_sec * 1000000ULL + t.tv_usec) * 1000;

Последний пропускает актерский состав и вместо этого выполняет повышение, поскольку правый операнд * уже будет введите как минимум 64-битный код (вместо того, чтобы приводить левую часть до единицы). Либо работает; вопрос в том, какой стиль вы предпочитаете.

Не go используйте временную переменную типа long, как вы это сделали. long может быть 32-битным типом и не будет соответствовать временам после января 2038 года. Если вам нужен временный переменный, сделайте его time_t или int64_t или аналогичным. Но это не нужно.

Также вы можете рассмотреть возможность использования int64_t (и изменение ULL на LL) вместо uint64_t, чтобы вы могли представлять время до 1970 года.

2 голосов
/ 21 апреля 2020

Вы рассчитываете с long int шириной. Из-за переполнения происходит неопределенное поведение, и uint64_t присваивается некоторое отрицательное значение, что приводит к большому положительному значению (в вашей архитектуре). Рассчитать с точностью uint64_t или unsigned long long. Чтобы быть педанти c, приведите все значения:

uint64_t t_int = ((uint64_t)sec * 1000000ull + (uint64_t)t.tv_usec) * 1000ull; 

Но из-за повышений, скорее всего, достаточно просто привести одно значение к uint64_t:

uint64_t t_int = ((uint64_t)sec * 1000000 + t.tv_usec) * 1000;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...