您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

如何检测无符号整数乘法溢出?

如何检测无符号整数乘法溢出?

Clang 3.4+和GCC 5+提供了经过检查的算术内置函数。它们提供了一个非常快速解决方案,特别是与位测试安全检查相比。

对于OP问题中的示例,它将像这样工作:

unsigned long b, c, c_test;
if (__builtin_umull_overflow(b, c, &c_test))
{
    // Returned non-zero: there has been an overflow
}
else
{
    // Return zero: there hasn't been an overflow
}

Clang文档没有指定c_test如果发生溢出是否包含溢出结果,但是GCC文档说确实包含。鉴于这两个都喜欢__builtin兼容,因此可以安全地假设这也是Clang的工作方式。

一个__builtin对每个运算,可以溢出(加法,减法,乘法),用符号和无符号的变体,对于int尺寸,长尺寸,以及长长的大小。名称的语法为__builtin_[us](operation)(l?l?)_overflow

因此,对于一个选中的带符号长整数加法运算,它将为__builtin_saddl_overflow。完整列表可在Clang文档页面上找到。

GCC 5+和锵3.8+还提供通用内建的工作,而无需指定值的类型:__builtin_add_overflow,__builtin_sub_overflow__builtin_mul_overflow。这些也适用于小于的类型int。

内建工具降低到最适合该平台的水平。在x86上,它们检查进位,溢出和符号标志。

Visual Studiocl.exe没有直接等效项。对于无符号的加法和减法,包括 将允许您使用 `addcarry_uNNsubborrow_uNN(其中NN是位数,例如 addcarry_u8或`subborrow_u64)。他们的签名有点晦涩:

unsigned char _addcarry_u32(unsigned char c_in, unsigned int src1, unsigned int src2, unsigned int *sum);
unsigned char _subborrow_u32(unsigned char b_in, unsigned int src1, unsigned int src2, unsigned int *diff);

c_in/b_in是输入上的进位/借位标志,返回值是输出上的进位/借位。它似乎没有等效的有符号运算或乘法。

否则,适用于Windows的Clang现在可以投入生产了(对于Chrome来说已经足够了),因此也可以选择。

其他 2022/1/1 18:14:25 有490人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶