JavaSE-位操作

[TOC]

基础概念

  • 也称比特,记为bit(binary digit的缩写)或小写b
  • 这是最小的信息单位,是用0或1来表示的1个二进制数位

字节

  • 记为Byte或大写B,这是计算机的最小存储单元
  • PC机中由8个二进制位构成一个字节,从最小的00000000到最大的11111111,即一个字节可有256个值。
  • 一个字节也可以表示由8个二进制位构成的其它信息。
  • 一个字节可存放一个半角英文字符的编码( ASCII码)。
  • 两个字节可存放一个汉字编码。1个汉字至少需要两个字节或两个字符来表示。这里所说的字符是指ASCII码字符,即半角下的英文字母、数字或其它符号。

  • 记为word或小写w,是计算机信息交换、加工、存储的基本单元。
  • 用二进制代码表示,一个字由一个字节或若干字节构成(不同机器的字长不同)。
  • 它可以代表数据代码、字符代码、 操作码和地址码或它们的组合。计算机的“字”用来表示数据或信息长度。

单位转换

K (KiloBytes,千) 字节  1KB = 1024 byte =2^10 byte
M(MegaBytes,兆)字节    1MB = 1024 K =2^20 byte
G(GigaBytes,吉)字节    1GB = 1024 M =2^30 byte
T(TeraBytes,太)字节    1TB = 1024 G =2^40 byte
P(PetaBytes,拍)字节    1PB = 1024 T =2^50 byte

数字的表示

计算机数字有原码、反码、补码三种存储格式,通常都是补码。

  • 正数的补码和原码相同
    • 正数的原码、反码、补码都相同
  • 负数的补码
    • 符号位为1
    • 其余各位是对原码取反
    • 然后整个数加1

比如:

  • +7的补码: 0000 0111

  • -7的补码

1(000 0111) //符号位为1
1111 1000 //对原码取反
1111 1001 //加1

注意,以下所示的 基本规则 中的0和1表示的都是 二进制位

与(&)

基本规则

同时为1得1,否则为0

0 & 0 == 0
0 & 1 == 0
1 & 0 == 0
1 & 1 == 1

常用技巧

  • 用0 "遮盖" 掉不需要的位
    • x & 0 == 0

或(|)

基本规则

同时为零得0,否则为1

0 | 0 == 0
0 | 1 == 1
1 | 0 == 1
1 | 1 == 1

非(~)

基本规则

按位取反,0变1,1变0

异或(^)

基本规则

相同得0,不同得1

0 ^ 0 == 0
0 ^ 1 == 1
1 ^ 0 == 1
1 ^ 1 == 0

常用技巧

  • 开关位
1 ^ 1 == 0
1 ^ 1 ^ 1 == 1
1 ^ 1 ^ 1 ^ 1 == 0
1 ^ 1 ^ 1 ^ 1 ^ 1 == 1
1 ^ 1 ^ 1 ^ 1 ^ 1 ^ 1 == 0
  • x ^ y ^ y == x

  • x ^ x == 0

    • x可以是任意整数
    • 所以可用来比较两个数否是相等

移位

左移

基本规则

  • 左移后空出来的低位补零
  • 最高位由于挪动可能导致0/1更替使得数字符号位发生改变
  • 左移一位相当于乘2

例子

6 << 2 == 24

00000000 00000000 00000000 00000110 (6)
00000000 00000000 00000000 00011000 (6 << 2)

常用技巧

对于正数和负数,在数字没有溢出的前提下:

  • m<<1:左移1位相当于m乘以2的1次方,即乘以2.
  • m<<n:左移n位相当于m乘以2的n次方.

右移

基本规则

  • 右移后的高位
    • 正数补0
    • 负数补1
  • 移动的时候考虑符号位,所以又称带符号右移
  • 正数右移一位相当于除以2

例子

6 >> 2 == 1

00000000 00000000 00000000 00000110 (6)
00000000 00000000 00000000 00000001 (6 >> 2)

-3 >> 1 == -2
11111111 11111111 11111111 11111101 (-3-----补码)
11111111 11111111 11111111 11111110 (-2-----补码)

常用技巧

m >> n:即相当于m除以2的n次方

  • 得到的为整数时,即为结果
  • 得到的为小数时
    • 如果m为正数,得到的商会舍弃小数位
    • 如果m为负数,舍弃小数部分,然后把整数部分加+1得到位移后的值

无符号右移

和右移的区别是:无论正负数,都在高位补0

例子:

-3 >>> 1 ==2147483646

11111111 11111111 11111111 11111101(-3-----补码)
01111111 11111111 11111111 11111110(右移1位高位补0而不是1)

应用

正负数切换

由原码反码补码的知识很容易得到如下结论:

~x + 1 == -x

求绝对值

  • 正数===>符号位为0===>zishen
  • 负数===>符号位为1===>相反数

问题就在如何获取符号位了:

x >> (size-1) ==========> 最左边的符号位,size为数字总的位长度,java的int为32个bit
public int abs(int x) {
    return x >> (Integer.SIZE - 1) == 0 ? x : ~x + 1;
}

判断奇偶数

通常我们判断一个数是奇数还是偶数都是用取模运算,但是这个效率有点底下了。
本人在一次面试的时候就遇到面试题让我写出最快的判断奇数偶数的方法。
计算机里最快的无非是位运算了。

(x & 1) == 1 则x是奇数
(x & 1) == 0 则x是偶数

原理:

奇数偶数的奇偶,关键就看最后一位了.
所以考虑只保留最后一位,其余的位都和0相与而“遮盖”掉.

例如:

00011010 (26)
00000001 (1)
-------------
00000000 (0)===>偶数


00011001 (25)
00000001 (1)
------------
00000001 (1)===>奇数

大小写转换

对于同一个字母而言,其对应的ASCII码的差值的绝对值刚好是32。
所以,我们常规的转换也就是对其对应的ASCII码加上或者减去32,即可得到其对应的大写或者小写字母了。

恰好这个差值32是2^5==0b100000==0x20,或许当初ASCII定制的时候就考虑到这点了吧。

// 这里的c和C代表a-zA-Z中的任意一个字符。
c ^ 0x20 == C
C ^ 0x20 == c

例如:

'a'====>97====>01100001
'A'====>65====>01000001
        32====>00100000

就差倒数第六位的1====>0b100000===>0x20。

原理

大小和小写字母的ASCII码之间就差倒数第六位的1或0
所以转换大小写只需考虑将倒数第六位取反即可。其余位不变。

所以可以用异或的特性来做开关位切换倒数第六位的0或者1。

交换两个数

平常我们的做法就是找第三个数作为临时的交换空间,有一次遇到了有人用这个方式交换的。

int a = 9;
int b = 10;
a = a ^ b;
b = a ^ b;
a = a ^ b;
System.out.println(a); //10
System.out.println(b); //9

十进制整数转为二进制字符串

尽量不适用任何内置库函数和内置类,只使用最基本的操作完成整数到二进制字符串的转换。

// i>=0 && i<Integer.SIZE

// 1. 倒数第i位后跟i个0
//比如i为3时可能为1000(倒数第三位为1)或0000(倒数第三位为0)
x & (1<<i) 

// 2.倒数第i位
(x & (1<<i)) >> i 
public String toBinaryString(int x) {
    char bts[] = new char[Integer.SIZE];
    //或者可以将循环倒过来处理
    for (int i = 0; i < Integer.SIZE; i++) {
        bts[Integer.SIZE - 1 - i] = (x & (1 << i)) >> i == 0 ? '0' : '1';
    }
    return new String(bts);
}

字符串和十六进制字符串互转

java字符串和十六进制字符串互转

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容