带符号整数的模运算在c中的未定义行为?

带符号整数的模运算在c中的未定义行为?,c,unsigned,undefined-behavior,signed,C,Unsigned,Undefined Behavior,Signed,在阅读了中的所有答案和评论后,我仍然不确定在以下情况下该怎么办 两个远程设备在各自的位置对事件进行计数。他们定期向电脑报告计数器读数,电脑中的反馈算法以某种方式将计数器读数的差异保持在一定范围内。事件的顺序是无止境的,因此以2^n的模报告读数。对于模算术,建议使用无符号整数。然而,这种差异很可能变成负面的。在计算差分之前,将读数转换为有符号整数在我测试它的平台上运行良好(也就是说,我得到的差分模为2^n,数值很小)。在接口中将读数声明为已签名会产生优雅的代码。但是,代码应可移植。我应该认真对待英

在阅读了中的所有答案和评论后,我仍然不确定在以下情况下该怎么办

两个远程设备在各自的位置对事件进行计数。他们定期向电脑报告计数器读数,电脑中的反馈算法以某种方式将计数器读数的差异保持在一定范围内。事件的顺序是无止境的,因此以2^n的模报告读数。对于模算术,建议使用无符号整数。然而,这种差异很可能变成负面的。在计算差分之前,将读数转换为有符号整数在我测试它的平台上运行良好(也就是说,我得到的差分模为2^n,数值很小)。在接口中将读数声明为已签名会产生优雅的代码。但是,代码应可移植。我应该认真对待英国广播公司的警告吗

我应该认真对待英国广播公司的警告吗


如果您不想让编译器或CPU捉弄您,您的代码应该是UB自由的。

需要考虑的一个选项是:如果计数器的值是16位无符号数,您可以安排将它们读入32位有符号数。或者,如果它们是32位的,您可以将它们读入64位数字。然后定义差异,负数将是负数,等等。@JonathanLeffler负数将是负数,但它们的模剩余将保持未定义。@JonathanLeffler:谢谢你的想法。似乎比基于分支的解决方案更快、更清晰。@Jan:模剩余是明确的,因为我知道差异的大小很小。考虑到这两个注释,我找到了另一种解决方案:使用无符号数字计算差异,将2^(n-2)相加,转换为有符号(结果安全地在正范围内),2^(n-2)的减法。这应该是明确定义的,并且希望编译器能够对其进行优化,以便在所有现有平台上只取差。