Мне нужен способ получить время с высокой точностью (миллисекунды или микросекунды) для алгоритма PRNG, который я пишу на C (C11), поскольку time(0)
недостаточно точен.
Я попытался использовать несколько других возможных решений, которые я нашел на StackOverflow, но ни одно из них не сработало для меня.
В любом случае моя проблема теперь исправлена с помощью предоставленного кода @dbush
Для Win32 вы можете использовать GetTickCount64()
.
@Scott Hunter Технически все они работали, но я всегда получал 0 в качестве разницы во времени из-за того, что моя программа работала слишком быстро.
Обычно у вас есть время и заполнение вашего PRNG один раз в начале вашей программы, а не повторно. Или процесс останавливается и запускается несколько раз в секунду?
@Ruud Helderman Мой PRNG работает немного по-другому, так как у меня есть функция randint
, которая генерирует случайное целое число на основе прошедшего времени.
ChaoticSomeone, "в Windows" --> Это проблема компилятора, а не ОС. Какой компилятор?
Пожалуйста, подумайте о том, чтобы не изобретать PRNG заново.
Отвечает ли это на ваш вопрос? Получить текущее время (в миллисекундах) по системным часам в Windows?
@van dech моя проблема уже решена. В любом случае спасибо
@SevaAlekseyev Я подозреваю, что интерес OP к высокоточному времени заключается не в том, чтобы заново изобретать PRNG, а в том, чтобы засеять его.
ChaoticSomeone, похоже, теперь у вас есть способ получить время с высокой точностью, но то, как вы используете его для PRNG, может быть сомнительным. Тем не менее, поскольку это использование не опубликовано, реальная проблема действительно не решена.
Из комментария: «У меня есть функция randint, которая генерирует случайное целое число на основе прошедшего времени». Похоже, это не просто семя.
Вы можете использовать функцию 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 Вам нужно #include <stdint.h>
.
Теперь я не получаю ошибку, но все равно получаю те же результаты в цикле for
@ChaoticSomeone Попробуйте оба варианта и попробуйте распечатать полученное значение, чтобы увидеть, насколько оно меняется между вызовами.
какой спецификатор формата это для uint64_t
?
@ChaoticSomeone %I64u
мои результаты: 133203440785961221 (вызывается перед циклом), 5219627056065 (вызывается после цикла)
На данный момент у меня есть программа для генерации случайных чисел с использованием двух предоставленных вами фрагментов кода. Большое спасибо!
"%"PRIu64
стандартный и портативный (от inttypes.h
).
Если возможно, было бы лучше использовать GetSystemTimePreciseAsFileTime
, который должен иметь большую точность (<1us в соответствии с документами ), чем GetSystemTimeAsFileTime
.
Начиная с 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, можете ли вы сказать, в чем именно ошибка? Я проверил, и программа, кажется, работает нормально для меня.
Вызов необъявленной функции 'timespec_get'; ISO C99 и более поздние версии не поддерживают неявные объявления функций.
Использование необъявленного идентификатора TIME_UTC.
@ChaoticSomeone единственное объяснение, которое я могу придумать, это то, что ваш компилятор не полностью соответствует C11. Можете ли вы сказать, какой компилятор вы используете и его версию?
Не знаю, какой компилятор я использую, я даже не знаю, где это узнать, но в моих CMakeLists указано, что версия 3.23
@ChaoticSomeone, вы используете Visual Studio? Если нет, то я предполагаю, что вы используете MinGW.
Я использую CLion в качестве IDE
@ChaoticSomeone Я уверен, что CLion лишь частично поддерживает C11, и, насколько я могу судить, это не включает утилиты времени C11. Если вы хотите использовать C11 полностью и правильно, вы можете переключиться.
Я рассмотрю возможность перехода на другую IDE
Что вы пробовали, и что из них не сработало для вас?