Получить время в миллисекундах в Windows

Мне нужен способ получить время с высокой точностью (миллисекунды или микросекунды) для алгоритма PRNG, который я пишу на C (C11), поскольку time(0) недостаточно точен.

Я попытался использовать несколько других возможных решений, которые я нашел на StackOverflow, но ни одно из них не сработало для меня.

В любом случае моя проблема теперь исправлена ​​с помощью предоставленного кода @dbush

Что вы пробовали, и что из них не сработало для вас?

Scott Hunter 08.02.2023 15:59

Для Win32 вы можете использовать GetTickCount64().

i486 08.02.2023 16:01

@Scott Hunter Технически все они работали, но я всегда получал 0 в качестве разницы во времени из-за того, что моя программа работала слишком быстро.

ChaoticSomeone 08.02.2023 16:10

Обычно у вас есть время и заполнение вашего PRNG один раз в начале вашей программы, а не повторно. Или процесс останавливается и запускается несколько раз в секунду?

Ruud Helderman 08.02.2023 16:15

@Ruud Helderman Мой PRNG работает немного по-другому, так как у меня есть функция randint, которая генерирует случайное целое число на основе прошедшего времени.

ChaoticSomeone 08.02.2023 16:19

ChaoticSomeone, "в Windows" --> Это проблема компилятора, а не ОС. Какой компилятор?

chux - Reinstate Monica 08.02.2023 16:19

Пожалуйста, подумайте о том, чтобы не изобретать PRNG заново.

Seva Alekseyev 08.02.2023 16:26

Отвечает ли это на ваш вопрос? Получить текущее время (в миллисекундах) по системным часам в Windows?

van dench 08.02.2023 16:42

@van dech моя проблема уже решена. В любом случае спасибо

ChaoticSomeone 08.02.2023 16:43

@SevaAlekseyev Я подозреваю, что интерес OP к высокоточному времени заключается не в том, чтобы заново изобретать PRNG, а в том, чтобы засеять его.

chux - Reinstate Monica 08.02.2023 16:44

ChaoticSomeone, похоже, теперь у вас есть способ получить время с высокой точностью, но то, как вы используете его для PRNG, может быть сомнительным. Тем не менее, поскольку это использование не опубликовано, реальная проблема действительно не решена.

chux - Reinstate Monica 08.02.2023 16:48

Из комментария: «У меня есть функция randint, которая генерирует случайное целое число на основе прошедшего времени». Похоже, это не просто семя.

Seva Alekseyev 08.02.2023 19:13
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
12
78
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете использовать функцию GetSystemTimeAsFileTime, которая показывает текущее время с интервалом в 100 нс с 01.01.1601 UTC.

FILETIME ft;
uint64_t ts;
GetSystemTimeAsFileTime(&ft);

ts = 0;
ts |= ft.dwHighDateTime;
ts <<= 32;
ts |= ft.dwLowDateTime;

Обратите внимание, что системные часы, скорее всего, не такие точные, поэтому не ожидайте детализации 100 нс.

Другой вариант — QueryPerformanceCounter, который даст вам микросекундные интервалы от неопределенной начальной точки:

LARGE_INTEGER ticks;
QueryPerformanceCounter(&ticks);
uint64_t ts = ticks.QuadPart;

Как uint64_t тип данных? Я получаю сообщение об ошибке: Использование необъявленного идентификатора uint64_t.

ChaoticSomeone 08.02.2023 16:16

@ChaoticSomeone Вам нужно #include <stdint.h>.

dbush 08.02.2023 16:18

Теперь я не получаю ошибку, но все равно получаю те же результаты в цикле for

ChaoticSomeone 08.02.2023 16:24

@ChaoticSomeone Попробуйте оба варианта и попробуйте распечатать полученное значение, чтобы увидеть, насколько оно меняется между вызовами.

dbush 08.02.2023 16:27

какой спецификатор формата это для uint64_t?

ChaoticSomeone 08.02.2023 16:31

@ChaoticSomeone %I64u

dbush 08.02.2023 16:33

мои результаты: 133203440785961221 (вызывается перед циклом), 5219627056065 (вызывается после цикла)

ChaoticSomeone 08.02.2023 16:35

На данный момент у меня есть программа для генерации случайных чисел с использованием двух предоставленных вами фрагментов кода. Большое спасибо!

ChaoticSomeone 08.02.2023 16:41
"%"PRIu64 стандартный и портативный (от inttypes.h).
Lundin 08.02.2023 16:55

Если возможно, было бы лучше использовать GetSystemTimePreciseAsFileTime, который должен иметь большую точность (<1us в соответствии с документами ), чем GetSystemTimeAsFileTime.

Iridium 08.02.2023 17:19

Начиная с C11, вы можете использовать struct timespec и timespec_get, чтобы получить то же значение, что и time(NULL), в секундах и наносекундах:

#include <stdio.h>
#include <time.h>

int main(void)
{
    struct timespec ts;
    timespec_get(&ts, TIME_UTC);
    printf("Time since epoch: %ld seconds, %ld nanoseconds", ts.tv_sec, ts.tv_nsec);
}

Этот код просто вызывает ошибку

ChaoticSomeone 08.02.2023 16:15

@ChaoticSomeone, можете ли вы сказать, в чем именно ошибка? Я проверил, и программа, кажется, работает нормально для меня.

mediocrevegetable1 08.02.2023 16:18

Вызов необъявленной функции 'timespec_get'; ISO C99 и более поздние версии не поддерживают неявные объявления функций.

ChaoticSomeone 08.02.2023 16:19

Использование необъявленного идентификатора TIME_UTC.

ChaoticSomeone 08.02.2023 16:20

@ChaoticSomeone единственное объяснение, которое я могу придумать, это то, что ваш компилятор не полностью соответствует C11. Можете ли вы сказать, какой компилятор вы используете и его версию?

mediocrevegetable1 08.02.2023 16:24

Не знаю, какой компилятор я использую, я даже не знаю, где это узнать, но в моих CMakeLists указано, что версия 3.23

ChaoticSomeone 08.02.2023 16:28

@ChaoticSomeone, вы используете Visual Studio? Если нет, то я предполагаю, что вы используете MinGW.

mediocrevegetable1 08.02.2023 16:31

Я использую CLion в качестве IDE

ChaoticSomeone 08.02.2023 16:32

@ChaoticSomeone Я уверен, что CLion лишь частично поддерживает C11, и, насколько я могу судить, это не включает утилиты времени C11. Если вы хотите использовать C11 полностью и правильно, вы можете переключиться.

mediocrevegetable1 08.02.2023 16:35

Я рассмотрю возможность перехода на другую IDE

ChaoticSomeone 08.02.2023 16:38

Другие вопросы по теме