神奇地撤消fprintf格式的错误

时间:2016-11-09 09:49:21

标签: c

我有一些代码从设备中记录数据,并以系统时间(以毫秒为单位)为数据加上时间戳。

我使用uint64_t来存储时间戳,其创建方式如下:


struct timespec request;
clock_gettime(CLOCK_REALTIME, &request);
uint64_t stamp0 = (uint64_t)((uint64_t)request.tv_sec * 1000 + (uint64_t)request.tv_nsec / 1000000);

然后我将时间戳写入文件(不经过考虑),如下所示:


fprintf(ptr,"%ld\n",(long)stamp0);

现在我的文件中的时间戳不正确,看起来像1130802699,但应该看起来像1478599582064

我有什么办法可以解决我的错误吗?

1 个答案:

答案 0 :(得分:5)

我猜测时间戳1130802699应该更像1478599552523而不是1478599582064

如果是这样,您可以通过添加1 <&lt; 32的正确倍数来恢复时间戳(我假设您的long是32位并且截断的值不是&#39;转到负范围)。在这种情况下,这需要344次,或1477468749824添加到每个值。

您的32位值将每6周左右滚动一次,因此如果您的文件范围较长,您可能需要做一些更聪明的事情。

如果您想知道我是如何想出这个价值的话,我们应该倒退。

我们知道我们将uint64_t截断为(大致)int32_t,如果我们做出一些合理的假设(例如2&#3的补码算术),则意味着使用0xffffffff屏蔽:

stamp0 & 0xffffffff

相当于减去

stamp0 - (stamp0 & 0xffffffff00000000)

这个差异在大范围的值上是恒定的,并且大约等于实际值和期望值之间的差异。

1478599582064 - 1130802699是1477468779365,或者0x15800007365。

所以我认为重新添加的偏移实际上是0x15800000000。