在 C 中实现/执行环绕算法
Implementing / enforcing wraparound arithmetic in C
C 标准说算术溢出是未定义的。
我想知道如何以性能友好的方式实现环绕算法。这意味着像 here 这样的溢出检查解决方案不是一个选项(因为它们使操作减慢了大约一个数量级)。
我假设解决方案涉及编写一个汇编例程来执行此操作。是否有可用的库来执行此操作(最好用于多体系结构,尽管 x86 是必须的)?
或者,是否有编译器标志(用于 gcc 和 clang)使编译器对整数运算强制执行环绕语义?
Signed 溢出未定义。未签名的溢出换行。实现带符号环绕算法主要是在无符号数学中完成所有事情。不过有几点需要注意:
unsigned short
和 unsigned char
算术首先将操作数转换为 int
或 unsigned int
。通常 int
,除非你在一个奇怪的设置中 int
没有足够的范围来存储所有 unsigned short
值。这意味着将 short
或 char
转换为 unsigned short
或 unsigned char
进行算术运算仍然会产生有符号整数溢出和 UB。您需要在 unsigned int
或更大范围内进行计算以避免这种情况。
- unsigned->signed 转换在技术上是实现定义的,当原始值超出结果类型的范围时。这在大多数编译器和架构上应该不是问题。
或者,如果您想走编译器标志路线,-fwrapv
对 GCC 和 Clang 的加法、减法和乘法进行带符号的溢出包装。不过,它对 INT_MIN / -1
没有任何作用。
C 标准说算术溢出是未定义的。
我想知道如何以性能友好的方式实现环绕算法。这意味着像 here 这样的溢出检查解决方案不是一个选项(因为它们使操作减慢了大约一个数量级)。
我假设解决方案涉及编写一个汇编例程来执行此操作。是否有可用的库来执行此操作(最好用于多体系结构,尽管 x86 是必须的)?
或者,是否有编译器标志(用于 gcc 和 clang)使编译器对整数运算强制执行环绕语义?
Signed 溢出未定义。未签名的溢出换行。实现带符号环绕算法主要是在无符号数学中完成所有事情。不过有几点需要注意:
unsigned short
和unsigned char
算术首先将操作数转换为int
或unsigned int
。通常int
,除非你在一个奇怪的设置中int
没有足够的范围来存储所有unsigned short
值。这意味着将short
或char
转换为unsigned short
或unsigned char
进行算术运算仍然会产生有符号整数溢出和 UB。您需要在unsigned int
或更大范围内进行计算以避免这种情况。- unsigned->signed 转换在技术上是实现定义的,当原始值超出结果类型的范围时。这在大多数编译器和架构上应该不是问题。
或者,如果您想走编译器标志路线,-fwrapv
对 GCC 和 Clang 的加法、减法和乘法进行带符号的溢出包装。不过,它对 INT_MIN / -1
没有任何作用。