当前位置: 首页 > 面试题库 >

为什么在Java中(high + low)/ 2是错误的,但是(high + low)>>> 1不是吗?

夏弘文
2023-03-14
问题内容

我知道>>>解决了溢出问题:将两个大的正长添加在一起时,您可能最终得到一个负数。有人可以解释这种按位移位如何神奇地解决溢出问题吗?和它有什么不同>>

我的怀疑:我认为这与Java使用两个补码的事实有关,因此,如果我们有额外的空间,则溢出是正确的数字,但是因为我们没有,所以它变为负数。因此,当您移位并以零进行划桨时,由于两个补全,它神奇地得到了固定。但是我可能是错的,大脑有点位的人必须确认。:)


问题答案:

简而言之,这(high + low) >>> 1是一个使用未使用的符号位对非负数进行平均的技巧。

highlow均为非负的假设下,我们可以肯定地知道最高位(符号位)为零。

因此,highlow实际上都是31位整数。

high = 0100 0000 0000 0000 0000 0000 0000 0000 = 1073741824
low  = 0100 0000 0000 0000 0000 0000 0000 0000 = 1073741824

将它们加在一起时,它们可能会“溢出”到最高位。

high + low =       1000 0000 0000 0000 0000 0000 0000 0000
           =  2147483648 as unsigned 32-bit integer
           = -2147483648 as signed   32-bit integer

(high + low) / 2   = 1100 0000 0000 0000 0000 0000 0000 0000 = -1073741824
(high + low) >>> 1 = 0100 0000 0000 0000 0000 0000 0000 0000 = 1073741824
  • 作为一个有符号的32位整数,它溢出并且反转为负。因此(high + low) / 2是错误的,因为high + low可能是负面的。

  • 作为无符号的32位整数,和是正确的。所有需要的是将其除以2。

当然,Java不支持无符号整数,因此我们必须除以2(作为无符号整数)的最好方法是逻辑右移>>>

在具有无符号整数的语言(例如C和C ++)中,由于您的输入可以是完整的32位整数,因此变得更加棘手。一种解决方案是:low + ((high - low) / 2)

最后枚举之间的差异>>>>>以及/

  • >>>是逻辑上的右移。它用零填充高位。
  • >>是算术右移。它用原始顶位的副本填充鞋帮。
  • / 是分裂。

数学上:

  • x >>> 1将其x视为无符号整数并将其除以二。四舍五入。
  • x >> 1将其x视为有符号整数并将其除以二。向负无穷大舍入。
  • x / 2将其x视为有符号整数并将其除以二。舍入为零。


 类似资料:
  • 我正在进入一个实现IBM MQ侦听Spring JMS应用程序的项目,我很难理解DefaultMessageListenerContainer中的“receiveTimeout”。 与来自互联网的消息相比,我认为我的项目有点特别,我们使用了一个非常高的值30秒作为“receiveTimeout”参数,我不知道这实际上意味着什么。 我已经试图弄清楚“receiveTimeout”参数的含义,在Spr

  • 问题内容: 所以我在推特上看到了这两个 问题。语法错误怎么回事,但不是吗? 问题答案: 我猜想,如果可能的话,贪婪地将其解析为数字的一部分,使其成为 ,而不是方法调用的一部分。 小数点附近不能有空格,但是在方法调用中,您可以在空格前后添加空格。如果数字后跟一个空格,则该数字的解析将终止,因此无歧义。 让我们看一下不同的情况及其解析方式:

  • 低级客户端的功能: 最小依赖 负载均衡 故障转移 故障连接策略 (是否重新连接故障节点取决于连续失败多少次;失败次数越多,在再次尝试同一个节点之前,客户端等待的时间越长) 持久化连接 跟踪记录请求和响应 自动发现集群节点

  • 问题内容: 我尝试在两种情况下执行T-SQL查询(我使用Win7,python 3.2,MS SQL Server Express 2008,适用于python 3.2的pyodbc): -情况1: 使用MS SQL Server Management Studio,我尝试执行查询: 返回成功结果 情况2: 但是运行代码后,我收到错误消息 如果我没有运行代码 我没有收到任何错误。但为什么? 问题答

  • 这是个小型库,可以允许从一个正在运行的 Elasticsearch 集群上自动发现节点并将节点列表更新到已经存在的 RestClient 实例上。 它默认使用 Nodes Info api 检索属于集群的节点,并使用jackson解析获取的json响应。 与Elasticsearch 2.x及以上兼容。

  • 问题内容: 即使int的最大值是2 31 -1,为什么Java HashMap的最大容量是1 << 30而不是1 << 31 ?最大容量初始化为 问题答案: Java使用带符号的整数,这意味着第一位用于存储数字的符号(正/负)。 一个四字节整数具有32位,其中数字部分由于有符号位而只能跨越31位。这将数字范围限制为 2 ^ 31-1 (由于包含0)到 -(2 ^ 31) 。