在网站上阅读一些问题时,我遇到了问题需要调试的问题
unsigned int a, b, c;
/* a and b are assume to have some values */
c = (a + b) / 2; // <- There is a bug in this st
What is the bug? and how you debug it?
Run Code Online (Sandbox Code Playgroud)
一些答案说它可能导致溢出(c =(a + b)/ 2).但真的没有得到它如何导致溢出?
a+b可能溢出如果总和a和b大于UINT_MAX,对于一个最大值unsigned int.例如,
unsigned a = 1;
unsigned b = UINT_MAX;
printf("%u\n", (a+b)/2);
Run Code Online (Sandbox Code Playgroud)
打印0.
如果你想找到unsigned int没有溢出的两个s 的平均值,那么
c = a/2 + b/2 + (a % 2 & b % 2);
Run Code Online (Sandbox Code Playgroud)
(或(a%2 + b%2)/2,或(a%2 && b%2),或((a&1) & (b&1))等)
如果a和/或b非常大,那么a + b可能会超过一个无符号整数的最大尺寸(见MAX_UINT中limits.h的文件).这会导致溢出,因此结果是错误的.例如,如果a和b都等于0x80000000,则结果在32位算术中为0,而不是预期的结果0x80000000.
要解决它,你可以使用这样的东西:
c = a/2 + b/2 + (a % 2 == 1 && b % 2 == 1);
Run Code Online (Sandbox Code Playgroud)
如果你知道它b大于a那么你可以使用这个稍微简单的版本:
c = a + (b - a) / 2;
Run Code Online (Sandbox Code Playgroud)
阅读这篇文章,了解有关这个错误如何在可能流行的语言中出现在二进制搜索算法中的信息(尽管它讨论的signed int不是unsigned int):