在C中实现/执行环绕算术

时间:2016-11-21 23:50:49

标签: c integer-overflow integer-arithmetic

C标准说算术中的溢出是未定义的。

我想知道如何以性能友好的方式实现环绕算法。这意味着像here这样的溢出检查解决方案不是一个选项(因为它们会使操作减慢大约一个数量级)。

我认为解决方案将涉及编写程序集例程来执行此操作。是否有可用的库(最好是多个架构,虽然x86是必须的)?

或者,是否有编译器标志(对于gcc和amp; clang)使编译器强制执行整数运算的环绕语义?

1 个答案:

答案 0 :(得分:3)

签名溢出未定义。无符号溢出包装。实现签名的环绕算法主要是在无符号数学中执行所有操作。但有几点需要注意:

  1. unsigned shortunsigned char算术通过将操作数首先转换为intunsigned int来实现。通常为int,除非您处于奇怪的设置,int没有足够的范围来存储所有unsigned short值。这意味着将shortchar转换为unsigned shortunsigned char进行算术仍然可以产生有符号整数溢出和UB。您需要在unsigned int或更大的数学中进行数学计算以避免这种情况。
  2. 当原始值超出结果类型的范围时,
  3. unsigned->签名转换在技术上是实现定义的。这在大多数编译器和体系结构中都不应该成为问题。
  4. 或者,如果你想进入编译器标志路由,-fwrapv在GCC和Clang上进行加法,减法和乘法的带符号溢出换行。但是,它对INT_MIN / -1没有任何作用。