无符号整数溢出由C和C++标准很好地定义.例如,C99标准(§6.2.5/9)声明
涉及无符号操作数的计算永远不会过度流动,因为无法用结果无符号整数类型表示的结果将以比结果类型可以表示的最大值大1的数量为模.
但是,这两个标准都声明有符号整数溢出是未定义的行为.再次,从C99标准(§3.4.3/1)
未定义行为的一个示例是整数流上的行为
这种差异是否存在历史或(甚至更好!)技术原因?
我正在寻找一些用于签名饱和64位加法的C代码,它使用gcc优化器编译为高效的X86-64代码.便携式代码是理想的,尽管如果需要可以使用asm解决方案.
static const int64 kint64max = 0x7fffffffffffffffll;
static const int64 kint64min = 0x8000000000000000ll;
int64 signed_saturated_add(int64 x, int64 y) {
bool x_is_negative = (x & kint64min) != 0;
bool y_is_negative = (y & kint64min) != 0;
int64 sum = x+y;
bool sum_is_negative = (sum & kint64min) != 0;
if (x_is_negative != y_is_negative) return sum; // can't overflow
if (x_is_negative && !sum_is_negative) return kint64min;
if (!x_is_negative && sum_is_negative) return kint64max;
return sum;
}
Run Code Online (Sandbox Code Playgroud)
写入的函数产生具有多个分支的相当长的汇编输出.有关优化的提示吗?看起来它应该只用一个带有一些CMOV指令的ADD来实现,但我对这些东西有点生疏.
有符号 2 的补码 32 位整数的问题:
\n\n\n\n
satMul2- 乘以 2,饱和Tmin或Tmax溢出。
\n示例:satMul2(0x30000000) = 0x60000000
\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0satMul2(0x40000000) = 0x7FFFFFFF(饱和到TMax)
\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0satMul2(0x60000000) = 0x80000000(饱和到TMin)
\n合法操作:!~&^|+<<>>
\n最大操作:20
\n评级:3
我想实现一个类似的功能
\nif (a) return b;\nelse return c;\nRun Code Online (Sandbox Code Playgroud)\n这是我的解决方案(10 次操作):
\nint satMul2(int x) {\n int rval = x << 1;\n int sign = rval ^ x;\n int minn = 1 << 31;\n …Run Code Online (Sandbox Code Playgroud) c bit-manipulation bitwise-operators micro-optimization saturation-arithmetic