【问题标题】:Modulo arithmetic with signed integers undefined behavior in c?c中带符号整数未定义行为的模算术?
【发布时间】:2013-04-14 01:52:34
【问题描述】:

阅读了Should you always use 'int' for numbers in C, even if they are non-negative?中的所有答案和cmets,我仍然不确定在以下情况下该怎么办。

两个远程设备在各自位置计算事件。他们定期向 PC 报告计数器读数,其中反馈算法以某种方式将计数器读数的差异保持在范围内。事件序列是无止境的,因此读数以 2^n 为模报告。对于模运算,建议使用无符号整数。然而,差异很可能会变成负数。在计算差异之前将读数转换为有符号整数在我测试它的平台上工作正常(也就是说,我得到了模 2^n 的差异,值的幅度很小)。在界面中将读数声明为已签名会产生优雅的代码。但是,代码应该是可移植的。我要不要去 U.B.严重警告?

【问题讨论】:

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

标签: c unsigned undefined-behavior signed


【解决方案1】:

我应该选择 U.B.严重警告?

如果您不希望您的编译器或 CPU 欺骗您,您的代码应该是无 UB 的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-17
    • 1970-01-01
    • 2011-04-29
    • 1970-01-01
    • 2014-04-01
    相关资源
    最近更新 更多