根据单个持续时间和比率计算两个持续时间的正确方法
Correct way to calculate two durations from a single duration and ratio
我已经实现了一种方法,使用std::chrono::duration
值和占空比float
给定的周期来计算开启和关闭时间的周期行为。这显示在下面的代码块中。持续时间和占空比的值只在运行时提供,所以我认为使用std::ratio是不可能的。有人能建议一种更清洁的方式来实现这一点吗?
PeriodicPulse(const Period period, const float duty): mRunning(false)
{
if (duty < 0 || duty > 1) {
throw std::runtime_error("Duty value should be between 0-1.");
}
auto tempTime = std::chrono::duration<float, decltype(period)::period>(period.count() * duty);
mOnTime = std::chrono::duration_cast<decltype(mOnTime)>(tempTime);
tempTime = std::chrono::duration<float, decltype(period)::period>(period.count() * (1 - duty));
mOffTime = std::chrono::duration_cast<decltype(mOffTime)>(tempTime);
}
您的代码对我来说很好,尤其是当您的测试显示它正在做您想要的事情时。下面我提供了一些风格上的清理,并将构造函数放在PeriodicPulse
:的上下文中
struct PeriodicPulse
{
using Duration = std::chrono::milliseconds;
bool mRunning;
Duration mOnTime;
Duration mOffTime;
template <class Rep, class Period>
PeriodicPulse(const std::chrono::duration<Rep, Period> period, const float duty)
: mRunning(false)
{
if (duty < 0 || duty > 1) {
throw std::runtime_error("Duty value should be between 0-1.");
}
using namespace std::chrono;
duration<float, Period> tempTime = period * duty;
mOnTime = duration_cast<Duration>(tempTime);
tempTime = period * (1 - duty);
mOffTime = duration_cast<Duration>(tempTime);
}
};
我已经将
Period
重命名为std::chrono::duration<Rep, Period>
,以表明它实际上应该具有类型duration,但使用变量名period
来描述持续时间的功能。这也限制了(我假设的)过于通用的模板参数。(我的假设可能不正确)当在函数范围内时,我发现重复使用
std::chrono::
过于冗长且难以阅读。我更喜欢using namespace std::chrono;
本地函数。你可能会有不同的感受。我替换了:
auto tempTime = std::chrono::duration<float, decltype(period)::period>(period.count() * duty);
带有:
duration<float, Period> tempTime = period * duty;
这将重用重写参数类型中的Period
,并避免不必要地使用.count()
成员函数。
对于
mOnTime
和mOffTime
的分配,我创建了一个Duration
别名,这样就不必说decltype(mOnTime)
了。decltype(mOnTime)
没有错,我只是觉得Duration
在这种情况下可读性更强,而且我仍然可以在一个地方更改这些成员的类型。当给
tempTime
第二个值时,duration_cast
是不必要的,因为存在到基于浮点的持续时间的隐式转换。我再次避免了.count()
成员功能,以便保持在<chrono>
型系统的类型安全保护范围内。
我这样测试:
#include "date/date.h"
#include <chrono>
#include <iostream>
int
main()
{
using date::operator<<;
using namespace std;
using namespace std::chrono;
using P = duration<int, ratio<1, 30>>;
PeriodicPulse p{P{3}, .2};
cout << p.mOnTime << 'n';
cout << p.mOffTime << 'n';
}
输出:
20ms
80ms
这和我用你的原始代码得到的答案是一样的。
不需要使用"date/date.h"
。这只是我懒洋洋地流p.mOnTime
和p.mOffTime
。
- 我可以创建一个包含两个变量的 for 循环,但时间复杂度仍然为 O(n) 吗?
- 如何检查两个 std::向量在小于 O(n) 的时间复杂度内是否相等
- 计算两个代码块的时间复杂度
- 如何使用发送数据包所花费的时间计算两个节点之间的距离?
- Levenshtein 两个文件的距离花费了太多时间
- 以天C++为单位的两个时间戳之间的差异
- 如何找到两个日期之间的时间差异(以秒和纳秒为单位)?
- 为什么具有静态存储持续时间的同一内联变量在包含在 VS2017 编译的两个翻译单元中时会构造和销毁两次
- 与操作员比较两个计时时间点
- 如何获取两个时间点之间的时间
- 图问题:找出两个节点是否在每个节点的O(1)时间和O(2)存储中共享同一分支
- 两个嵌套循环的运行时间复杂性:二次型还是线性
- 使计时器在C++进程中的特定时间关闭,以便同步两个进程
- 给定的两个代码有什么区别.一个在 ideone 上运行时超出时间限制,另一个工作正常
- 如何比较两个经过的时间?
- 添加两个时间值存储为数据库中的字符串
- 根据单个持续时间和比率计算两个持续时间的正确方法
- 两个事件之间的计时持续时间
- 在时间::持续时间类型之间转换,其中两个分母的LCM都很大
- 比较具有相同持续时间的两个std::chrono::time_points失败