我正在研究以下问题:
给定正整数n,您可以执行以下操作:
- 如果n为偶数,则用n / 2替换n。
- 如果n为奇数,则可以用n + 1或n - 1替换n。
n成为1所需的最小替换次数是多少?
以下是我提出的代码:
#include <fenv.h>
int main() {
float a = 1.0f;
fedisableexcept(FE_DIVBYZERO); // disable div by zero catching
// generates an inf that **won't be** catched
float c = a / 0.0f;
feenableexcept(FE_DIVBYZERO); // enable div by zero catching
// generates an inf that **will be** catched
float d = a / 2.0f;
return 0
}
当输入为2147483647时,我的代码错误输出33而不是正确的答案,32。为什么我的代码在这里给出了错误的答案?
答案 0 :(得分:4)
我怀疑这是整数溢出。您列出的数字(2,147,483,647)是可以容纳int
的最大可能值,假设您使用的是带符号的32位整数,因此如果您添加一个,则溢出到{{ 1}},即-2,147,483,648。从那里开始,你得到错误的答案就不足为奇了,因为这个价值不是你想要得到的。
计算
时特别发生溢出INT_MIN
所以你需要修复这种情况来计算(n + 1)/ 2而不会溢出。这是一个非常极端的边缘情况,所以我对代码绊倒它并不感到惊讶。
这样做的一种方法是注意,如果n是奇数,则(n + 1)/ 2等于(n / 2)+ 1(具有整数除法)。所以也许你可以把它重写为
integerReplacement((n+1)/2)
计算相同的值,但没有溢出。