хроно с разными периодами времени?

В настоящее время я использую boost::rational<std::uint64> отслеживать в моем приложении.

В основном у меня есть часы, которые работают в течение очень длительного периода времени и будут зависать от разных компонентов с разным временным разрешением, например, 1/50 с, 1/30 с, 1001/30000 с и т. Д … Я хочу поддерживать идеальную точность, то есть без плавающей запятой. boost::rational хорошо работает для этой цели, однако я думаю, что будет лучше использовать дизайн std::chrono::duration за это.

Моя проблема, хотя, как я могу использовать std::chrono::duration Вот? Поскольку он использует период времени компиляции, я не совсем понимаю, как я могу использовать его в моем сценарии, где мне нужно поддерживать точность?

1

Решение

Вам разрешено установить период 1 и использовать тип с плавающей запятой для Rep,

я подозреваемый что вы можете сделать то же самое с boost::rational, но вам придется присмотреться std::chronoчто я не сделал. смотреть на treat_as_floating_point а также duration_values, Также попытайтесь выяснить, что означает стандарт под «арифметическим типом или классом, эмулирующим арифметический тип».

Можно разумно утверждать, что если boost::rational не эмулирует арифметический тип, тогда он не выполняет свою работу. Но это не так обязательно следите за тем, что он действительно делает все std::chrono::duration надеется.

1

Другие решения

Если я понимаю ваш вопрос, и если вы знаете все разные временные разрешения во время компиляции, тогда следующее будет делать то, что вы хотите. Вы можете определить правильный период тиков, используя common_type на всех ваших разных временных разрешениях, как показано ниже:

#include <cstdint>
#include <chrono>

struct clock
{
typedef std::uint64_t                      rep;
typedef std::common_type
<
std::chrono::duration<rep, std::ratio<1, 50>>,
std::chrono::duration<rep, std::ratio<1, 30>>,
std::chrono::duration<rep, std::ratio<1001, 30000>>
>::type                                    duration;
typedef duration::period                   period;
typedef std::chrono::time_point<clock>     time_point;
static const bool is_steady =              true;

static time_point now()
{
// just as an example
using namespace std::chrono;
return time_point(duration_cast<duration>(steady_clock::now().time_since_epoch()));
}
};

Это вычислит во время компиляции самый большой тиковый период, который будет точно представлять каждое из указанных вами разрешений. Например, с этими часами можно точно представить:

  • 1/50 с 600 тиками.
  • 1/30 с 1000 тиков.
  • 1001/30000 с 1001 тиков.

Код ниже осуществляет это clock и использует описанную функцию «chrono_io» Вот чтобы распечатать не только количество тактов ваших часов, но и единицы времени вашего такта:

#include <iostream>
#include <thread>
#include "chrono_io"
int main()
{
auto t0 = clock::now();
std::this_thread::sleep_for(std::chrono::milliseconds(20));
auto t1 = clock::now();
std::cout << (t1-t0) << '\n';
}

Для меня это распечатывает:

633 [1/30000]seconds

Значение: было 633 такта между вызовами now() и единица измерения каждого тика составляет 1/30000 секунды. Если вы не хотите быть привязанным к «chrono_io», вы можете проверить единицы ваших часов с помощью clock::period::num а также clock::period::den,

Если ваши разные временные разрешения не являются информацией времени компиляции, тогда ваше текущее решение с boost::rational наверное лучше.

2

По вопросам рекламы [email protected]