C 比较可能溢出的时间

jde*_*ere 2 time arduino overflow

我需要检测unsigned long.

该变量保存设备运行以来的毫秒数(它是 Arduino)。这样做sizeof(unsigned long),我发现它确实是一个 32 位数字。现在,由于它每毫秒递增一次,这意味着设备将运行大约 49 天,然后该值就会溢出。

由于它是用于家庭系统,因此并不建议这样做。现在我使用这个数字的目的是比较当前时间是否大于前一个时间加上去抖动量。

if(timeChanged + amountOfMs < currentTime){ ... }
Run Code Online (Sandbox Code Playgroud)

不用说,一旦发生溢出,这将不再起作用。有什么有效的方法可以解决这个问题?我考虑过也有一个第二计时器来检查毫秒是否溢出,但最终我会遇到同样的问题。

Edg*_*net 7

这个翻转问题似乎引起了相当大的混乱......

\n

millis()正确的答案是,只要计算得当,您不必担心展期问题。

\n

这不好:

\n\n
if (timeChanged + amountOfMs < currentTime) { ... }\n
Run Code Online (Sandbox Code Playgroud)\n

这很好(翻转安全):

\n
if (currentTime - timeChanged > amountOfMs) { ... }\n
Run Code Online (Sandbox Code Playgroud)\n

它起作用的原因是,使用无符号整数(在您的情况下为 unsigned long )的算术可以可靠地以 max+1 为模(ULONG_MAX+1为 2 32)。因此,currentTimetimeChanged它们的差值始终具有正确的值,模 2 32。只要您每 49\xc2\xa0 天测试一次按钮以上(这很可能),差异将在 an 范围内unsigned long,并且您的测试将是正确的。

\n

换句话说:如果在和millis()之间滚动,则差值为负。但由于差异实际上是用无符号数计算的,因此它会下溢并翻转到正确的结果。但我不喜欢这个解释,因为这听起来像是一个错误补偿另一个错误。事实是:如果您根据模算术来考虑无符号数,那么任何地方都不会出现错误。timeChangedcurrentTimecurrentTime - timeChanged

\n