问题描述
我有2个时间戳,表示最后一分钟的毫秒数。想象一下节点之间没有同步问题。
接收方必须区分哪个是第一个生成的消息。不幸的是,在59秒后变量重新启动,然后如何比较这两个变量?
备注:假设计时器之间存在最大延迟,即10秒。否则,这是无法解决此问题的方法。
我的解决方案在下面发布。
解决方法
下面的代码中的注释:
#include <limits.h>
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
bool millis_in_last_minute_is_valid(int time) {
// represented as milliseconds in the last minute
// after 59 seconds the variables restart
static_assert(INT_MAX > 59999,"Use long and not int to represent numbers greater then 2^16. int has __at least__ 16 bits,it may have 16 bits,in which case INT_MAX is around 32000,which will be lower then 59999 and not able to represent your timestamp");
return 0 <= time && time <= 59999;
}
/**
* @return true if time1 is happened before time2,false otherwise.
*/
bool timestamp_millis_in_last_minute_happened_before(int time1,int time2) {
assert(millis_in_last_minute_is_valid(time1));
assert(millis_in_last_minute_is_valid(time2));
const int diff = abs(time2 - time1);
// imagine there is a max delay between the timers,i.e. 10 seconds
/**
There are 4 cases:
0---------time---------->60000
[---------T1--T2-------->
[---------T2--T1-------->
[-T2-----------------T1->
[-T1-----------------T2->
If the difference is smaller then 10 seconds,it's
one of two first cases,if it's grater then 10 seconds,it's one of the latter. If the latter,the comparison
needs to just be inverted.
*/
// assert the difference between timestamps is max 10 seconds
assert(
// First two cases
(0 <= diff && diff <= 10000) ||
// Latter two cases
(50000 <= diff && diff < 60000));
return diff <= 10000 ? time1 < time2 : time2 < time1;
}
int main() {
// simple test cases with assert
// 0 is not lower then 0 |T1T2-------> T1 happened with T2
assert(timestamp_millis_in_last_minute_happened_before(0,0) == 0);
// 1 is not lower then 0 |T2-T1------> T1 happened after T2
assert(timestamp_millis_in_last_minute_happened_before(1,0) == 0);
// 0 is lower then 1 |T1-T2------> T1 happened before T2
assert(timestamp_millis_in_last_minute_happened_before(0,1) == 1);
// 59 second happens before 1 |T2------T1-> T1 happened before T2
assert(timestamp_millis_in_last_minute_happened_before(59000,1) == 1);
// 1 happens before 59 second |T1------T2-> T1 happened before T2
assert(timestamp_millis_in_last_minute_happened_before(1,59000) == 0);
}
,
这是我的解决方案:
int compare_timestamp_millis_in_last_minute(int time1,int time2)
{
if(time1 == time2) return 0;
int millisInLastMinute = get_time_in_millis() % MAXMILLISINMINUTE;
if((time1 - millisInLastMinute % MAXMILLISINMINUTE) > (time2 - millisInLastMinute % MAXMILLISINMINUTE))
return 1;
else
return -1;
}
MAXMILLISINMINUTE = 65535
解决方案背后的想法:time1和time 2始终小于比较时的时间。然后减去一个之后的时间,将把时间1和时间2变量移至左象限(均小于或等于59 s)。
有人有不同的解决方案吗?