博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
有意思的按位操作
阅读量:5918 次
发布时间:2019-06-19

本文共 2696 字,大约阅读时间需要 8 分钟。

hot3.png

看到几个有意思的按位操作的写法。

1.大概改动了下为了方便理解,参数是int型且大于等于65536,返回这个int型的十位和个位。

public static int getTenAndOne(int value){        if (value < 0) {            throw new RuntimeException("不管负数了");        }        int q = value / 100;        int result = value - ((q << 6) + (q << 5) + (q << 2));        return result;    }
通常我们计算一个数的后两位时,都是用 int result = value%100,但这里不是这样玩的。我记得看过一本书讲JAVA在%运算符的时候,实际是int result = value-value/100*100。看看上面那个方法里其实跟这个很像。这么看来
((q << 6) + (q << 5) + (q << 2))

这个操作其实就是 (a/100)*100的操作,可是移位是怎么变成*100的呢,曾经的基础书中这么讲过,向左移移动一位表示*2,所以对上面的表达式进行整理就是 q*2^6+q*2^5+q*2^2=q*(2^6+2^5+2^2)=q*100。呃……。其实当我想明白这个的时候,又一次感叹,无处不在的数学啊。

2.这个是计算出一个小于65536的整数的,个位数是多少。

pulic static int getOne(int value){	if(value<0||value>=65536){		throw new RuntimeException("就是不管负数和超限的数");	}	int q = (value * 52429) >>> 19;	int result = value - ((q << 3) + (q << 1));	return result;}
根据例1里面的经验,可以很容易看出,其实这个例子就是result=value-value/10*10;

特别是

int result = value - ((q << 3) + (q << 1));

非常好理解就是 value-(q*2^3+q*^2)=value-q*(8+2)=value-q*10 ,那么上面那句话其实就是value/10的意思了,可是简单的value/10,怎会冒出来乘以52429然后再无符号右移19位呢。我google出来的解释,也算学习了一下。

(i * 52429) >> 19 = i / 10
原理: 52429 / 2 ^19 = 0.10000038146972656 所以(i * 52429) >> 19 = i * 0.1
注意:     2^10=1024, 103/1024=0.1005859375
              2^11=2048, 205/2048=0.10009765625
              2^12=4096, 410/4096=0.10009765625
              2^13=8192, 820/8192=0.10009765625
              2^14=16384, 1639/16384=0.10003662109375
              2^15=32768, 3277/32768=0.100006103515625
              2^16=65536, 6554/65536=0.100006103515625
              2^17=131072, 13108/131072=0.100006103515625
              2^18=262144, 26215/262144=0.10000228881835938
              2^19=524288, 52429/524288=0.10000038146972656 
精度19最高,超过20 * i 就溢出了
然后: (i + (i << 2) + (i << 3) + (i << 6) + (i << 7) + (i << 10) + (i << 11) + (i<<14) + (i<<15)) >> 19 = i / 10

  以上两个例子是在jedis代码中看到的,同时在JDK里的Integer类中的 static void getChars(int i, int index, char[] buf)里也有。看来jedis作者对JDK源码有认真阅读啊。

3.求一个离一个正整数向上最近的2的次方。

public static int nextPowerOfTwo (int value) {	if (value == 0) {		return 1;	}	value--;	value |= value >> 1;	value |= value >> 2;	value |= value >> 4;	value |= value >> 8;	value |= value >> 16;	return value + 1;}
其实求一个整数向上最近的2的次方就是这个整数左数第一个1以下所有位全部变为1再加1

比如232用二进制表示就是

00000000000000000000000011101000 它的向上最近二进制数就是

00000000000000000000000011111111+1

依据上面的理论,这个代码其实就是再逐步的把这个数都变成1,然后再+1

还是以232为例子,就不写成4个字节的形式了

232 = 11101000

1)

1110 1000>>1 //等于0111 0100 就肯定把最高1位的下一位变成了1 
1110 1000 | 0111 0100 //等于 1111 1100 就把最高两位就变成1了

2)

1111 1100>>2 //等于0011 1111 就等于把标红两位变成1
1111 1100 | 0011 1111 //等于 1111 1111 相当于把最高四位变成1

3)

1111 1111 >>4 //等于 0000 1111 就等于把标红四位变成1

1111 1111 | 0000 1111 //等于 1111 1111 相当于把最高位的1个字节变成1

4)其实就把最高的两个字节变成1

5)把整个int四个字节全部变成1

如上过程,整个int型数的最高的1位以下全部变成了1,最后再加上1 就完成了整个技巧,并返回结果。

转载于:https://my.oschina.net/u/944165/blog/105907

你可能感兴趣的文章
检测到有潜在危险的 Request.Form 值
查看>>
解决 ubuntu 14.04.1 下一个sublime text3 3065 中国输入的问题
查看>>
Swift实战-QQ在线音乐(AppleWatch版)
查看>>
黄聪:MYSQL提交一批ID,查询数据库中不存在的ID并返回
查看>>
burp suite中国乱码的解决方案
查看>>
zerglurker的c语言教程006——第一功能
查看>>
Robberies
查看>>
CircularSeekBar
查看>>
pageContext对象
查看>>
Android -- ViewDragHelper
查看>>
【BZOJ】2938: [Poi2000]病毒
查看>>
Magicodes.WeiChat——发送模板消息
查看>>
Nginx/LVS/HAProxy负载均衡软件的优缺点详解
查看>>
flask表单提交的两种方式
查看>>
【NOIP2002】矩形覆盖 DFS
查看>>
Android群英传》读书笔记 (4) 第八章 Activity和Activity调用栈分析 + 第九章 系统信息与安全机制 + 第十章 性能优化...
查看>>
Objective C (iOS) for Qt C++ Developers(iOS开发,Qt开发人员需要了解什么?)
查看>>
Android中获取应用程序(包)的信息-----PackageManager的使用
查看>>
深入理解JavaScript中创建对象模式的演变(原型)
查看>>
Android 判断SD卡是否存在及容量查询
查看>>