无符号序列号溢出问题

在系统实现中,经常需要用到序列号来记录操作执行的顺序或者打印时间戳等。因为序列号等我们只取正值,所以一般都使用无符号数以表示更大的范围。虽然一般的32位或者64位无符号数表示的范围很大,甚至可以确保在系统的生命周期内都不会用完,但是作为一个健壮的系统还是需要考虑无符号数达到最大后,重新归零的溢出问题。


此时有一个比较简单的转换可以用来规避该问题。在比较两个序列号的大小时,使用以下 before 内联函数即可,如果 seq1 小于 seq2 将返回正数,如果 seq1 大于等于 seq2 将返回负数。

static inline int before(uint32_t seq1, uint32_t seq2)
{
    return (int32_t)(seq1 - seq2) < 0;
}

乍一看,将两个 uint32_t 相减的结果转换为 int32_t 之后会有溢出的问题,因为一个很大的32位无符号整数减去一个很小的32位无符号整数,在转换后会变成负数。而这正是解决无符号数溢出问题的关键。此处隐含了一个默认的前提,即在使用 before 函数判断序列号时,需要保证进行判断的序列号是相邻出现的,至少其差异不会跨越整个无符号数表示范围的一半,这也常常是符合我们使用序列号的习惯的。这样即使无符号数溢出真的发生了,我们通过 before 函数进行序列号比较时,就仍能得到正确的结果。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值