@@ -85,7 +85,81 @@ public static void main(String[] args) {
8585 System .out .println ("位运算分为俩种:逻辑操作和位移操作:" );
8686 System .out .println ("逻辑操作就是一下几种: java运算符: &按位与,|按位或,^按位异域,~按位取反" );
8787 System .out .println ("位移操作就是一下几种: java运算符: <<左移, >>右移, >>>无符号右移" );
88-
88+ /*
89+ * 移位运算
90+ 在计算机中,整数总是以二进制的形式表示。例如,int类型的整数7使用4字节表示的二进制如下:
91+ 00000000 0000000 0000000 00000111
92+ 可以对整数进行移位运算。对整数7左移1位将得到整数14,左移两位将得到整数28:
93+ */
94+ int n = 7 ; // 00000000 00000000 00000000 00000111 = 7
95+ int a = n << 1 ; // 00000000 00000000 00000000 00001110 = 14
96+ int b = n << 2 ; // 00000000 00000000 00000000 00011100 = 28
97+ int c = n << 28 ; // 01110000 00000000 00000000 00000000 = 1879048192
98+ int d = n << 29 ; // 11100000 00000000 00000000 00000000 = -536870912, 左移29位时,由于最高位变成1,因此结果变成了负数。
99+
100+ /*
101+ * 类似的,对整数28进行右移,结果如下:
102+ */
103+ int nn = 7 ; // 00000000 00000000 00000000 00000111 = 7
104+ int aa = nn >> 1 ; // 00000000 00000000 00000000 00000011 = 3
105+ int bb = nn >> 2 ; // 00000000 00000000 00000000 00000001 = 1
106+ int cc = nn >> 3 ; // 00000000 00000000 00000000 00000000 = 0
107+ /**
108+ * 如果对一个负数进行右移,最高位的1不动,结果仍然是一个负数:
109+ * 有符号的右移应该前面是补1,所以这里是不是写错了?
110+ * 应该是写错了,查阅了一些资料,而且自己验证了一下,廖老师解释的不通。
111+ * 右移前面不是补1,第一位的0或1表示的是正负,使用>>的时候第一位是正负是不会移动的。不论左移还是右移空出来的位置都是补0.
112+ * 应该是写错了,试了一下10111000 00000000 00000000 00000000的结果并不是-134217728,11111000 00000000 00000000 00000000的结果才是
113+ * https://www.liaoxuefeng.com/wiki/1252599548343744/1255888634635520
114+ */
115+ int nbb = -536870912 ;
116+ int abb = nbb >> 1 ; // 11110000 00000000 00000000 00000000 = -268435456
117+ int bbb = nbb >> 2 ; // 11111000 00000000 00000000 00000000 = -134217728
118+ int ccc = nbb >> 28 ; // 11111111 11111111 11111111 11111110 = -2
119+ int dcc = nbb >> 29 ; // 11111111 11111111 11111111 11111111 = -1
120+
121+ /*
122+ *还有一种不带符号的右移运算,使用>>>,它的特点是符号位跟着动,因此,对一个负数进行>>>右移,它会变成正数,原因是最高位的1变成了0:
123+ */
124+ int ndd = -536870912 ;
125+ int add = ndd >>> 1 ; // 01110000 00000000 00000000 00000000 = 1879048192
126+ int bdd = ndd >>> 2 ; // 00111000 00000000 00000000 00000000 = 939524096
127+ int cdd = ndd >>> 29 ; // 00000000 00000000 00000000 00000111 = 7
128+ int ddd = ndd >>> 31 ; // 00000000 00000000 00000000 00000001 = 1
129+ //对byte和short类型进行移位时,会首先转换为int再进行位移。
130+ //仔细观察可发现,左移实际上就是不断地×2,右移实际上就是不断地÷2。
131+
132+ //对两个整数进行位运算,实际上就是按位对齐,然后依次对每一位进行运算。例如:
133+ int i = 167776589 ; // 00001010 00000000 00010001 01001101
134+ int nb = 167776512 ; // 00001010 00000000 00010001 00000000
135+ System .out .println (i & nb ); // 167776512
136+ //上述按位与运算实际上可以看作两个整数表示的IP地址10.0.17.77和10.0.17.0,通过与运算,可以快速判断一个IP是否在给定的网段内。
137+ //牛客网练习题https://www.nowcoder.com/questionTerminal/34a597ee15eb4fa2b956f4c595f03218?f=discussion
138+ //码云 https://gitee.com/
139+ /*
140+ * 在Java的计算表达式中,运算优先级从高到低依次是:
141+ ()
142+ ! ~ ++ --
143+ * / %
144+ + -
145+ << >> >>>
146+ &
147+ |
148+ += -= *= /=
149+ 记不住也没关系,只需要加括号就可以保证运算的优先级正确。
150+ 类型自动提升与强制转型
151+ 在运算过程中,如果参与运算的两个数类型不一致,那么计算结果为较大类型的整型。例如,short和int计算,结果总是int,原因是short首先自动被转型为int:
152+ */
153+ //也可以将结果强制转型,即将大范围的整数转型为小范围的整数。强制转型使用(类型),例如,将int强制转型为short:
154+ //要注意,超出范围的强制转型会得到错误的结果,原因是转型时,int的两个高位字节直接被扔掉,仅保留了低位的两个字节:因此,强制转型的结果很可能是错的。
155+ int i1 = 1234567 ;//整数运算的结果永远是精确的
156+ short s1 = (short ) i1 ; // -10617
157+ System .out .println (s1 );
158+ int i2 = 12345678 ;
159+ short s2 = (short ) i2 ; // 24910
160+ System .out .println (s2 );
161+
162+
89163 System .out .println ("按位与运算:&,定义:参加运算的俩个数据,按二进制位进行‘于’运算,与运算:俩个数都为 1,则结果为1" );
90164 System .out .println ("&位与运算:1&1 = 1, 1&0 = 0, 0&1 =0, 0&0 = 0 " );
91165 System .out .println ("示例:14&3即0000 1110 & 0000 0011 = 0000 0010 = 整数2,因此14&3=2,特点:①清零特定位②获取特定位" );
0 commit comments