我遇到了一个问题,我不得不在两种不同的持续时间类型之间进行转换,如下所示:
using MyType_T = duration<long long, ratio<1, 4294967296LL>>;
using OtherType_T = duration<long long, ratio<1, 10000000>>;
当我使用:: boost :: chrono :: duration_cast&lt;&gt; (或std :: chrono :: duration_cast&lt;&gt;,就此问题而言),从MyType_T转到OtherType_T,反之亦然,我发现当源值超过某个限制时,这些类型的转换会产生错误的结果。
仅调用duration_cast(tm)存在问题的原因是两个分母的LCM完全以56位表示。在这种情况下,通过将tm中的值除以分母的LCM,并将其作为公共因子类型传递到OtherType_T持续时间的构造中来完成转换。这将执行乘法以获得正确的值。
正如您所看到的,如果值足够大(在这种情况下为64或更大),这意味着除法可以将所有内容都移到零,并且您什么也得不到。
除了执行以下操作之外,有没有办法在不失去所有精度的情况下进行此转换?
typedef typename common_type<MyType_T, OtherType_T>::type CommonDuration;
auto highbits = duration_cast<duration<CommonDuration::rep, ratio<CommonDuration::num>>>(tm);
auto lowbits = tm - highbits;
auto result = highbits + duration_cast<OtherType_T>(lowbits);
答案 0 :(得分:1)
我会使用浮点类型作为临时类型:
using MyType_T = duration<long long, ratio<1, 4294967296LL>>;
using OtherType_T = duration<long long, ratio<1, 10000000>>;
using OtherType_F = duration<long double, OtherType_T::period>;
MyType_T x{0x7FFFFFFFFFFF};
auto y = duration_cast<OtherType_T>(OtherType_F{x});
语法更容易,逻辑也不那么复杂。请注意,如果结果不适合OtherType_T
,您仍会溢出。