位运算

在数学领域123属于整数、实数、正数等等,而在计算机领域123属于十进制数,即以10为基数的n次方的数制,当然面向对象是人类,那么对于计算机底层逻辑来讲,怎么存储123 这个数字呢?我们认知的正数、负数在计算机中是如何进行存储的呢?又是如何进行运算的呢?

123是如何在计算机中进行存储的

答:用0,1表示的二进制进行存储的。

这里默认大家都知道java中的int类型数和long类型数,我们都知道java中的int类型数是32位,long类型是64位,那这32位是什么呢?没错,就是32个0,1组成的数制。
先给答案,int类型数 123 在计算机中的存储:

00000000000000000000000001111011

如上就是123在计算机中的存储形式。那么怎么和十进制进行转换的呢?我们都知道二进制就是以2为基数的数制,逢二进一,和十进制进行转换即以2为基n的次方计算求得,其中n表示的就是哪一位上非0,从右向左分别为0,1,2...以此类推。
那么上面的可以进行计算为:

2^0 + 2^1 +  2^3 + 2^4 + 2^5 + 2^6 = 123

那么从二进制转换为十进制数如此,十进制转换为二进制即为相反的过程,此处不在赘述。

正数、负数在计算机中如何存储

答:最高位0表示正数,1表示负数

举个例子

10000000000000000000000001111011 最左边的1表示此数是一个负数
00000000000000000000000001111011 最左边的0表示此数是一个正数

在计算机中数字是如何进行计算的

此处先讲一下简单的加法运算,后续再讲复杂的运算。加法运算和我们在十进制数是一样的,两数相加,“逢二进一”。

与C语言不同,Java中没有无符号整数

  • 无符号数顾名思义就是没有正负之说,它的范围是0~2^32-1,并且它最高
    位的0或者1没有意义,表示数值。
  • 有符号数是区分正数和负数的,范围是-2^31~ 2^31 -1 ,最高位上的0表示正数,1表示负数

举个例子

  • 正数的表示和转换为十进制数上述有例子,此处进行展示,不做详细(123)
00000000000000000000000001111011

计算方式

2^0 + 2^1 +  2^3 + 2^4 + 2^5 + 2^6 = 123
  • 负数的表示和转换为十进制数(-123)
11111111111111111111111110000101

计算方式

便于计算机的快速性,也为了解决有无符号的一个通用性,使计算机底层对于任何数都是同一个计算方式,此处对于负数的计算有一个巧思:“取反加一”

~+1(取反加一)
第一步取反:
1 0000000000000000000000001111010 // 最高位的1不在计算数值中,表示负号(-)
第二步+1
1 0000000000000000000000001111011 
-(2^0 + 2^1 +  2^3 + 2^4 + 2^5 + 2^6) = -123

总结一下:-123在计算机中存储是

11111111111111111111111110000101

它转换为十进制数时最高位表示负号不计数,后面的31位进行“取反加一”的操作后通过基底转换即可得到十进制数-123。

数讲完了,那什么是位运算呢?

位运算是程序设计中对位模式按位或二进制数的一元和二元操作。
古老的架构中,位运算是略快于加减法运算,比乘除法运算要快很多
现代的架构中,位元算和加法运算速度是相同的,但仍快于乘除法运算

位运算符

~ 取反
& 按位与
| 按位或
^ 按位异或
<< 左移
>> 带符号右移
>>> 不带符号右移

取反

一元运算,具有右结合性
例:~(1001) 取反后得---> 0110

按位与

二元运算,都是1即为1,其余均是0。
例:1 & 1 = 1,1 & 0 = 0,0 & 1 = 0,0 &0 = 0

按位或

二元运算,有1即为1。
例:1 | 1 = 1,1 | 0 = 1,0 | 1 = 1, 0 | 0 = 0

按位异或

二元运算,相同为0,不同为1(相异为1)
例:1^1 = 0,1^0 = 1,0^1 = 1,0^0 = 0

左移

二元运算,左移n位就是乘以2的n次方,高位丢弃,低位补0。
例:1左移1位,1<<1 = 2; 简单用8位数表示 00000001 << 1 == 00000010
⚠️ 当左移的数值超过int类型的边界,会出现溢出的情况

int num = Integer.MAX_VALUE;
print(num);
print(num << 1);
System.out.println(num<<1);

//输出结果
01111111111111111111111111111111
11111111111111111111111111111110
-2


int num = Integer.MIN_VALUE;
print(num);
print(num << 1);
System.out.println(num<<1);

//输出结果
10000000000000000000000000000000
00000000000000000000000000000000
0

带符号右移(有符号数)

二元运算,右移n位表示除以2的n次方。
带符号右移的意思是,当最高位是1右移时高位空出位置补1,当最高位是0右移时高位空出位置补0。同理,当右移后的数值大于int类型的边界,则会溢出。

 int numRight = Integer.MIN_VALUE;
 print(numRight);
 print(numRight >> 1); //带符号右移,依然表示负数
 System.out.println(numRight >> 1);

//输出结果
10000000000000000000000000000000
11000000000000000000000000000000
-1073741824

不带符号右移(无符号数)

二元运算,右移n位表示除以2的n次方,。最高位不管是0还是1,空出的高位均补0。

 int numRight = Integer.MIN_VALUE;
 print(numRight);
 print(numRight >>> 1); //不带符号右移,表示正数
 System.out.println(numRight >>> 1);

//输出结果
10000000000000000000000000000000
01000000000000000000000000000000
1073741824

此处可以看出来,当不带符号右移时,负数会变成正数。

再补充一下相反数,a的相反数是-a,-a的相反数是a
它的表述方式:-a 和 ~a + 1(“取反加一” 也表示相反数)a 为任何数
⚠️0的相反数是0,可通过“取反加一”观察,-2^31相反数是本身,也可通过“取反加一”计算出来。

 int num = 0;
 int numFan = -num;
 int numFan1 = ~num + 1;

 print(num);
 print(numFan);
 print(numFan1);

//输出结果
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000




  int num = Integer.MIN_VALUE;
  int numFan = -num;
  int numFan1 = ~num + 1;

  print(num);
  print(numFan);
  print(numFan1);

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

推荐阅读更多精彩内容