如何将表示时间(单位为 usec)的 32 位 int 转换为表示时间(以秒为单位的二进制分数)的 32 位 int?
POSIX 使用 struct timeval 来表示时间间隔。
struct timeval
{
time_t tv_sec;
unsigned tv_usec;
};
GHS 完整性按以下方式表示时间
,
struct Time
{
time_t Seconds;
unsigned Fraction;
};
例如,0.5 秒表示为0x80000000
,0.25 秒表示为0x40000000
。
从 timeval
转换为 Time
的最佳方法是什么?
(ps 答案是不要将 POSIX 库链接到 Integrity 并使用 POSIX 调用。)
POSIX uses struct timeval
to represent time intervals.
struct timeval
{
time_t tv_sec;
unsigned tv_usec;
};
GHS Integrity represents Time
in the following manner,
struct Time
{
time_t Seconds;
unsigned Fraction;
};
For example, 0.5sec is represented as 0x80000000
and 0.25sec is represented as 0x40000000
.
What is the best way to convert from timeval
to Time
?
(p.s. The answer is not to link the POSIX library into Integrity and use POSIX calls.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是一种不寻常的时间表示方式。
不管怎样,如果你有 64 位整数或浮点数(前者更可能在嵌入式系统上),有两种简单的方法可以做到这一点:
显然,两者都只是整数近似值,因为一个比例中的大多数值都无法表示作为另一个尺度的整数。 在一个方向上,您可能会失去一些精度,因为
Fraction
形式可以表示更精细的时间 -Fraction
形式的一个增量小于 0.00024 微秒。 但这前提是您的计时器实际上可以测量那些不太可能的值 - 大多数计时器甚至无法以微秒为单位进行测量,并且您在 tv_usec 中看到的值通常是四舍五入的。如果 64 位整数和浮点数均不可用,您可以使用额外的变量进行迭代。 我在想是否有一种更简单(并且更便宜,考虑到这是定时代码)的方法来进行这种缩放,而不是用两个 32 位整数进行迭代 64 位乘法和除法。 在我想到的两个想法中,其中一个不会进行精确的均匀缩放,并且可能会产生最多 9 位偏差的结果,而补偿这一点的想法结果并不便宜。 如果我想到了新的东西,我会将其发布在这里,但这是一个有趣的挑战。 还有其他人有好的算法或片段吗? 也许借助一个小的预先计算表?
This is an unusual way to represent time.
Anyway, there are two easy ways to do it either way if you have 64-bit integers or floating points (the former are more likely on an embedded system):
Obviously both are only integer approximations, because most values in one scale cannot be represented as integers in the other scale. And in one direction you may be losing some precision because the
Fraction
form can represent much finer times - one increment of theFraction
form is less than 0.00024 microseconds. But that is only if your timer can actually measure those values which is not very likely - most timers cannot even measure at the scale of microseconds, and the value you see intv_usec
is often rounded.If neither 64-bit integers nor floating points are available an option, you could do it iteratively with an extra variable. I was thinking if there is a simpler (and less expensive, considering that this is timing code) way to do such scaling than doing the equivalent of iterative 64-bit multiplication and division with two 32-bit integers. Of the two ideas that came to my mind, one would not do exact even scaling and may produce results that are by up to 9 bits off, and the one that compensates for that turns out not to be any cheaper. If something new comes up in my mind I will post it here, but this is an interesting challenge. Does anyone else have a good algorithm or snippet? Perhaps with the aid of a small precomputed table?
您可能想阅读浮点表示形式,因为分数似乎是有效数的第一位。
这是 foobar,但它确实有效...您需要 64 位整数和双浮点数。
You might wanna read up on floating-point representation as Fraction seems to be the first bits of the significand.
This is foobar but it really works... you'll need 64-bit integers and double floating-point.
我已经实现了 @Tom Alsberg 的建议(
double
变体)。 有一些警告(比较 frac_t == uint32_t 和 frac_t == uint64_t 的输出)。输出(
frac_t == uint32_t
):输出(
frac_t == uint64_t
):I've implemented @Tom Alsberg's suggestion (
double
variant). There are caveats (compare output forfrac_t == uint32_t
andfrac_t == uint64_t
).Output (
frac_t == uint32_t
):Output (
frac_t == uint64_t
):