在this blog post中,作者提出了以下错误修复建议:
int mid = (low + high) >>> 1;
有谁知道这是什么>>>运营商?当然它不在以下运营商参考清单上:
它是什么以及如何解决溢出问题?
答案 0 :(得分:8)
>>>
不是C ++的一部分。该博客包含Java代码。
查看关于按位移位运算符的Java在线教程here。它说
无符号右移运算符“>>>”将零移动到最左边的位置,而在“>>”之后的最左边的位置移动取决于符号扩展。
答案 1 :(得分:3)
>>>
运算符位于 Java 代码段中,它是无符号右移运算符。它在处理有符号值时与>>
运算符不同:>>
运算符在移位期间应用sign extension,而>>>
运算符只在位位置插入零转移时“清空”。
可悲的是,在C ++中没有保持符号和无符号右移的功能,我们只有>>
运算符,它在负符号值上的行为是实现定义的。要模仿>>>
之类的行为,您必须在应用班次之前对unsigned int
执行一些演员表(如紧接在您发布的代码段后的代码段中所示)。
答案 2 :(得分:2)
答案 3 :(得分:2)
>>>
是 Java 中的logical right shift运算符。
它在左边移动零而不是保留符号位。博客文章的作者甚至提供了C ++实现:
mid = ((unsigned int)low + (unsigned int)high)) >> 1;
...如果右移无符号数,保留符号位没有任何意义(因为 没有符号位),所以编译器显然使用逻辑移位而不是算术移位
以上代码利用MSB(假设32位整数为32位):添加low
和high
,它们都是非负整数并因此适合31位 never 溢出全部32位,但它会扩展到MSB。通过将其向右移位,32位数有效地除以2,并且第32位再次被清零,因此结果为正。
事实是Java中的>>>
运算符只是一种解决方法,因为该语言不提供unsigned
数据类型。
答案 4 :(得分:1)
它是一个java运算符,与C ++无关。
然而,所有博客作者所做的是将除法改为2,并采用逐位右移(即将值右移1
类似于除以2 ^ 1
)。
相同的功能,不同的机器代码输出(在大多数架构上,位移操作几乎总是比乘法/除法更快)。
答案 5 :(得分:1)
Java表达式x >>> y
或多或少等同于C ++表达式unsigned(x) >> y
。