离逢

      工作之后,与一些朋友认识,熟悉,分离,笑着说再见。

      最初一个点头,一个微笑,略显怯生;随后的交往还是有些谨慎,举手投足流露出小心;渐渐地,笑容变得熟悉,声音变得可亲,肢体挥洒着默契;而终会有一天,他轻轻来到你身边,又或许是一封E-mail出现在众人面前:抱歉,他要别离。

      有时候啊,心想这真是很可怕的事情。这个人,或许今生你们都不会再相遇。几多感概,几多忧郁。

      然而,人生却也会有意外。说不准某年某月某天某地,突然某人拍打你的肩膀,一扭头,他“唿”地出现在你眼里。惊诧、兴奋、狂喜,那感觉,“天涯何处不逢君”!

dwater 2003-11-26

寻找最近的2次幂((代码请基于jdk8’联网解析每一步) (请详细解析相关概念和描述,联网解析,中文解析)) 在定义elements变量时说,其长度总是2的次幂,但用户传入的参数并不一定符合规则,所以就需要根据用户的输入,找到比它大的最近的2次幂。比如用户输入13,就把它调整为16,输入31,就调整为32,等等。考虑下,我们有什么方法可以实现呢? 来看下ArrayDeque是怎么做的吧: private void allocateElements(int numElements) { int initialCapacity = MIN_INITIAL_CAPACITY; // Find the best power of two to hold elements. // Tests "<=" because arrays aren't kept full. if (numElements >= initialCapacity) { initialCapacity = numElements; initialCapacity |= (initialCapacity >>> 1); initialCapacity |= (initialCapacity >>> 2); initialCapacity |= (initialCapacity >>> 4); initialCapacity |= (initialCapacity >>> 8); initialCapacity |= (initialCapacity >>> 16); initialCapacity++; if (initialCapacity < 0) // Too many elements, must back off initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements } elements = new Object[initialCapacity]; } 看到这段迷之代码了吗?在HashMap中也有一段类似的实现。但要读懂它,我们需要先掌握以下几个概念: 在java中,int的长度是32位,有符号int可以表示的值范围是 (-2)31 到 231-1,其中最高位是符号位,0表示正数,1表示负数。 >>>:无符号右移,忽略符号位,空位都以0补齐。 |:位或运算,按位进行或操作,1为1。 我们知道,计算机存储任何数据都是采用二进制形式,所以一个int值为80的数在内存中可能是这样的: 0000 0000 0000 0000 0000 0000 0101 0000 比80大的最近的2次幂是128,其值是这样的: 0000 0000 0000 0000 0000 0000 1000 0000 我们多找几组数据就可以发现规律: 每个2的次幂用二进制表示时,只有一位为 1,其余位均为 0(不包含符合位) 要找到比一个数大的2的次幂(在正数范围内),只需要将其最高位左移一位(从左往右第一个 1 出现的位置),其余位置 0 即可。 但从实践上讲,没有可行的方法能够进行以上操作,即使通过&操作符可以将某一位置 0 或置 1,也无法确认最高位出现的位置,也就是基于最高位进行操作不可行。 但还有一个很整齐的数字可以被我们利用,那就是 2n-1,我们看下128-1=127的表示形式: 0000 0000 0000 0000 0000 0000 0111 1111 把它和80对比一下: 0000 0000 0000 0000 0000 0000 0101 0000 //80 0000 0000 0000 0000 0000 0000 0111 1111 //127 可以发现,我们只要把80从最高位起每一位全置为1,就可以得到离它最近且比它大的 2n-1,最后再执行一次+1操作即可。具体操作步骤为(为了演示,这里使用了很大的数字): 原值: 0011 0000 0000 0000 0000 0000 0000 0010 无符号右移1位 0001 1000 0000 0000 0000 0000 0000 0001 与原值|操作: 0011 1000 0000 0000 0000 0000 0000 0011 可以看到最高2位都是1了,也仅能保证前两位为1,这时就可以直接移动两位 无符号右移2位 0000 1110 0000 0000 0000 0000 000
最新发布
04-01
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值