我想知道如何将64 bit long
数据类型转换为任何16 bit
数据类型。以太网应用程序需要此功能才能包含时间戳。只有2 个字节(16 位)可用于包含时间戳。但是我们从 中获取64 bit long
时间戳值Win API
。所以从 64 位数据类型到 16 位数据类型的转换是必不可少的。
4 回答
嗯,你不能在不丢失一些信息的情况下将 64 位信息放入 16 位存储中。
因此,如何量化或截断时间戳取决于您。例如,假设您获得了纳秒精度的时间戳,但您只需要以秒精度存储它。在这种情况下,您将 64 位数除以 1000000000,剩下的就是秒数。然后它可能适合 16 位或不适合(16 位最多只能存储 65535 秒)。
如果它不适合,那么您将定期环绕时间戳。同样,这可能是您的问题,也可能不是问题。
在任何情况下,如果您需要连接需要时间戳的现有库 - 找出它在该时间戳中需要什么(时钟滴答声?秒?年?)。然后找出您正在使用的 Windows 时间函数返回什么。然后将 Windows 时间单位转换为您使用的库时间单位。
16 位可能不够,也可能不够,这取决于您需要时间戳的用途。对于大多数用途来说,它太小或至少不方便。但是这可能会起作用的一些示例可能是:超时,测量数据包的往返时间,粗略测量时间间隔(这可能适用于向用户显示时间信息)等等。
另一方面,它可能对重新排序数据包没用。如果是这种情况,我建议您用序列计数器替换时间戳。根据流中数据包的典型数量,您甚至可以减少一些位并将它们用于其他目的,因为序列计数器可以更轻松地处理包装。
正如其他人所说,第一个问题是决定正确的缩放比例。你必须平衡你的分辨率和你想要的最大范围。考虑它的一种方法是确定您想要的每比特多少秒。每比特 1 秒,您可以表示从 1 秒到 65536 秒或约 1000 分钟的值。每比特 1 毫秒可让您从 0.001 秒提高到 65.5 秒
这是进行转换的一种方法。
#define seconds_per_bit .0001 <--YOUR VALUE HERE.
#define bits_per_second (1/seconds_per_bit);
int16 timestamp()
{
Int64 counts_per_second,counts;
QueryPerformanceFrequency(&counts_per_sec);
QueryPerformanceCounter(&counts);
return (UInt16)(counts * bits_per_second / counts_per_second);
}
这完全取决于您使用时间戳的目的。你提到了以太网,所以我可以想象的一个明显的用途是订购数据包。在这种情况下,您真正需要的只是一个计数器。而不是你的时间戳说“这个数据包是在 5 月 14 日下午 14:35 发送的”,它可以简单地说“这是第 4023 个数据包”。
如果你需要它来记录实际的时钟时间,你只需要选择它的哪些部分是相关的。16 位给你 65536 个值来玩。你想让那些代表秒吗?然后您的时间戳将每 18 小时循环一次。
或者他们可以是分钟。然后在他们结束之前将是 45 天。或几天,或微秒,这一切都取决于你需要什么。
但是,将 64 位值转换为 16 位值的唯一方法是删除 48 位数据。你选择哪些