1

如何重写此测试以使测试本身不会溢出?我可以使用(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会。我改了标题。感谢您对一个不好的问题的正确答复。

4

1 回答 1

2

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

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

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


请注意,与我最初所说的(mea culpa)相反,size > max_value/3它不起作用,因为当整数类型为无符号时 max_value3 的倍数(条件是有偶数位可用于正数)。所以,当 size 为 时0x5555,我们得到3*size = 0xffff3*size + 1 = 0x0000。很抱歉把它弄混了。

于 2013-10-26T22:05:29.397 回答