gpt4 book ai didi

c++ - 如何在C语言中检测环绕计数器和大负值之间的区别

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:39:40 26 4
gpt4 key购买 nike

为我的愚蠢道歉,因为这是我在这个论坛上的第一篇文章。我试图在以下代码的帮助下检测环绕无符号 32 位计数器和大型负跳转之间的区别,但编译器给我错误:

错误:由于数据类型的范围有限,比较始终为真 [-Werror=type-limits]

这是我的代码片段:

#define MAX_BACKWARD_JUMP -4294959295 //UINT_MAX - 8000
#define MIN_BACKWARD_JUMP -3600
#define MAX_FORWARD_JUMP 4800000

signed int rtpDelta; //Signed 32-bit
unsigned int currRTPTs, prevRTPTs; //unsigned 32-bit

rtpDelta = currRTPTs - prevRTPTs;

if ((rtpDelta > MAX_BACKWARD_JUMP && rtpDelta < MIN_BACKWARD_JUMP)
|| (rtpDelta > MAX_FORWARD_JUMP))
{
printf("Delta in Timestamps too large\n",rtpDelta);
}

这里的想法是在 RTP 时间戳中捕获无效的大增量。我们有一个当前时间戳和一个从对等 RTP 客户端接收的先前时间戳。 RTP 时间戳无效值的边界限制为 -4294959295 < rtpDelta < -3600,如果 Delta 小于 -3600 且大于 -4294959295,则应抛出错误,因为接近 UMAX_INT 的值将被视为翻转.我在这里做错了什么?

最佳答案

一般来说,如果你有两个无符号计数器 ab,其值介于 0 和 LIMIT-1 之间,包括这两个值,并且能够表示 2*LIMIT-1 的数据类型,您可以使用中间分割点的模运算:

difference = (a + LIMIT - b) % LIMIT;
if (difference <= LIMIT/2) {
/* a = b + difference */
} else {
/* b = a + (LIMIT - difference) */
}

通常 LIMIT 是 2 的幂,在这种情况下,模运算符 (% LIMIT) 可以替换为二进制 AND ( & (LIMIT-1)),这在当前处理器上要快得多。

对于 C,无符号整数类型在标准中被定义为具有模运算(C99、C11 6.2.5p9),因此 a - b 使用任何无符号整数类型作为 ab 将产生正确的结果,其中 LIMIT"limits.h" Utype_MAX 宏头文件。例如,

const unsigned int  d = (unsigned int)a - (unsigned int)b;
if (d <= UINT_MAX/2)
/* a >= b, a = b + d */
else
/* a < b, b = a + UINT_MAX - (d - 1) */

关于c++ - 如何在C语言中检测环绕计数器和大负值之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21810258/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com