如何测试n / 2 * 3 + n%2 * 2是否会溢出?

时间:2013-10-26 21:14:44

标签: c overflow

如何重写此测试以使测试本身不会溢出?我可以使用(size_t) -1是奇数(2减去1的幂)的事实吗?

size_t size;
...
if ((size * 3U + 1U) / 2U > (size_t) -1) {
    /* out of address space */
}

编辑:抱歉,我的问题标题错了。我不想检查(n * 3 + 1) / 2是否会溢出,但是n / 2 * 3 + n % 2 * 2是否会溢出。我改变了标题。感谢您对错误问题的正确回复。

1 个答案:

答案 0 :(得分:2)

以下是这个精确公式的解决方案,其背后的推理不适用于一般情况,但对于给定的一个,以及许多其他情况,它确实如此。

size*3 + 1无法表示时,溢出恰好发生,无符号整数除法永远不会溢出。所以,你的情况应该是size*3 + 1 > max_value。这里,max_value是设置了所有位的无符号值,使用(size_t)-1生成。

+1可以简单地移动到右侧而不调用溢出,因为max_value肯定大于1,所以我们到达size*3 > max_value - 1。同样,可以在不调用溢出的情况下移动*3。所以你需要检查的是size > (max_value - 1)/3


请注意,与我原先所说的相反(mea culpa),size > max_value/3不起作用,因为当整数类型为无符号时,max_value 是3的倍数(条件是有一个偶数位可用于正数)。因此,当大小为0x5555时,我们会得到3*size = 0xffff3*size + 1 = 0x0000。很抱歉混淆了。