神奇地撤消fprintf格式的错误

Jam*_*mes 2 c

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

我用a 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.

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

Tob*_*ght 5

我猜测,时间戳1130802699应该更像14785995525231478599582064.

如果是这样,您可以通过添加1 << 32的适当倍数来恢复时间戳(我假设您的long是32位且截断的值不会翻转到负范围内).在这种情况下,这是344次,或1477468749824添加到每个值.

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


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

我们知道我们截断了uint64_t(粗略地)int32_t,如果我们做出一些合理的假设(例如2的补码算术),那意味着用0xffffffff屏蔽:

stamp0 & 0xffffffff
Run Code Online (Sandbox Code Playgroud)

这相当于减去

stamp0 - (stamp0 & 0xffffffff00000000)
Run Code Online (Sandbox Code Playgroud)

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

1478599582064 - 1130802699是1477468779365,或者0x15800007365.

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