本文目錄一覽:
java中位移操作和乘法的區別
ava中有三種移位運算符
: 左移運算符,num 1,相當於num乘以2
: 右移運算符,num 1,相當於num除以2
: 無符號右移,忽略符號位,空位都以0補齊
對於:
無符號右移,忽略符號位,空位都以0補齊
value num — num 指定要移位值value 移動的位數。
無符號右移的規則只記住一點:忽略了符號位擴展,0補最高位 無符號右移運算符 只是對32位和64位的值有意義
java 位移運算
首先要執行移位操作。。必須將byte轉換成int。。。
bt的二進位表示為1000 0001
轉換成int後二進位表示為 11111111 11111111 11111111 1000 0001
先執行b3,右移三位變為:11111111 11111111 11111111 1111 0000
再執行b3,左移三位變為: 1111111 11111111 11111111 1000 0000
bt 是byte類型。。所以再截斷。。。取1000 0000
第一位是符號位,1表示負數。。。所以結果就是-128(2的七次方)
同樣的分析方法。。。。
先表示成int的二進位反碼錶示方式。。。
11111111 11111111 11111111 1101 0000
右移三位變成:1111111 1111111 1111111 1111 1010
左移三位變成:11111111 11111111 11111111 1101 0000
截斷變成 1101 000
這個反碼錶示就是-48
希望能幫到你~!
java int怎麼位移取前幾位數字?
思路:直接用Integer類的bit運算操作。
如果想得到一個n位數的第k位,寫法如下:
(n ( 1 k )) k
內部實現就是:
1、創建一個mask,把1左移k位
int mask = 1 k;
2、然後把n右移mask位就是想要得到的結果
int masked_n = n mask;
int thebit = masked_n k。
class Tester{
public static void main (String[] args) {
String str = “2013年6月12日,XXXXXXXXXXXXX”;
String reg = “([^,,]+)[,,].*$”;
String r = str.replaceAll(reg, “$1”);
reg = “^((\\d+)年)?((\\d+)月)?((\\d+)日)?$”;
String sy = r.replaceAll(reg,”$2″);
String sm = r.replaceAll(reg,”$4″);
String sd = r.replaceAll(reg,”$6″);
int y, m, d;
try {
y = Integer.parseInt(sy);
} catch(Exception e) {
y = 0;
}
try {
m = Integer.parseInt(sm);
} catch(Exception e) {
m = 0;
}
try {
d = Integer.parseInt(sd);
} catch(Exception e) {
d = 0;
}
System.out.format(“%d, %d, %d”, y, m, d);
}
}
java中的位運算符及其用法。
位邏輯運算符有「與」(AND)、「或」(OR)、「異或(XOR)」、「非(NOT)」,分別用「」、「|」、「^」、「~」表示。
下面的例子說明了位邏輯運算符:
// Demonstrate the bitwise logical operators.
class BitLogic {
public static void main(String args[]) {
String binary[] = {
“0000”, “0001”, “0010”, “0011”, “0100”, “0101”, “0110”, “0111”,
“1000”, “1001”, “1010”, “1011”, “1100”, “1101”, “1110”, “1111”
};
int a = 3; // 0 + 2 + 1 or 0011 in binary
int b = 6; // 4 + 2 + 0 or 0110 in binary
int c = a | b;
int d = a b;
int e = a ^ b;
int f = (~a b) | (a ~b);
int g = ~a 0x0f;
System.out.println(” a = ” + binary[a]);
System.out.println(” b = ” + binary[b]);
System.out.println(” a|b = ” + binary[c]);
System.out.println(” ab = ” + binary[d]);
System.out.println(” a^b = ” + binary[e]);
System.out.println(“~ab|a~b = ” + binary[f]);
System.out.println(” ~a = ” + binary[g]);
}
}
在本例中,變數a與b對應位的組合代表了二進位數所有的 4 種組合模式:0-0,0-1,1-0,和1-1。「|」運算符和「」運算符分別對變數a與b各個對應位的運算得到了變數c和變數d的值。對變數e和f的賦值說明了「^」運算符的功能。字元串數組binary代表了0到15對應的二進位的值。在本例中,數組各元素的排列順序顯示了變數對應值的二進位代碼。數組之所以這樣構造是因為變數的值n對應的二進位代碼可以被正確的存儲在數組對應元素binary[n]中。例如變數a的值為3,則它的二進位代碼對應地存儲在數組元素binary[3]中。~a的值與數字0x0f (對應二進位為0000 1111)進行按位與運算的目的是減小~a的值,保證變數g的結果小於16。因此該程序的運行結果可以用數組binary對應的元素來表示。該程序的輸出如下:
a = 0011
b = 0110
a|b = 0111
ab = 0010
a^b = 0101
~ab|a~b = 0101
~a = 1100
左移運算符
左移運算符使指定值的所有位都左移規定的次數。它的通用格式如下所示:
value num
這裡,num指定要移位值value移動的位數。也就是,左移運算符使指定值的所有位都左移num位。每左移一個位,高階位都被移出(並且丟棄),並用0填充右邊。這意味著當左移的運算數是int類型時,每移動1位它的第31位就要被移出並且丟棄;當左移的運算數是long類型時,每移動1位它的第63位就要被移出並且丟棄。
在對byte和short類型的值進行移位運算時,你必須小心。因為你知道Java在對表達式求值時,將自動把這些類型擴大為 int型,而且,表達式的值也是int型 。對byte和short類型的值進行移位運算的結果是int型,而且如果左移不超過31位,原來對應各位的值也不會丟棄。但是,如果你對一個負的byte或者short類型的值進行移位運算,它被擴大為int型後,它的符號也被擴展。這樣,整數值結果的高位就會被1填充。因此,為了得到正確的結果,你就要捨棄得到結果的高位。這樣做的最簡單辦法是將結果轉換為byte型。下面的程序說明了這一點:
// Left shifting a byte value.
class ByteShift {
public static void main(String args[]) {
byte a = 64, b;
int i;
i = a 2;
b = (byte) (a 2);
System.out.println(“Original value of a: ” + a);
System.out.println(“i and b: ” + i + ” ” + b);
}
}
該程序產生的輸出下所示:
Original value of a: 64
i and b: 256 0
因變數a在賦值表達式中,故被擴大為int型,64(0100 0000)被左移兩次生成值256(10000 0000)被賦給變數i。然而,經過左移後,變數b中惟一的1被移出,低位全部成了0,因此b的值也變成了0。
既然每次左移都可以使原來的操作數翻倍,程序員們經常使用這個辦法來進行快速的2的乘法。但是你要小心,如果你將1移進高階位(31或63位),那麼該值將變為負值。下面的程序說明了這一點:
// Left shifting as a quick way to multiply by 2.
class MultByTwo {
public static void main(String args[]) {
int i;
int num = 0xFFFFFFE;
for(i=0; i4; i++) {
num = num 1;
System.out.println(num);
}
}
}
該程序的輸出如下所示:
536870908
1073741816
2147483632
-32
初值經過仔細選擇,以便在左移 4 位後,它會產生-32。正如你看到的,當1被移進31位時,數字被解釋為負值。
右移運算符
右移運算符使指定值的所有位都右移規定的次數。它的通用格式如下所示:
value num
這裡,num指定要移位值value移動的位數。也就是,右移運算符使指定值的所有位都右移num位。
下面的程序片段將值32右移2次,將結果8賦給變數a:
int a = 32;
a = a 2; // a now contains 8
當值中的某些位被「移出」時,這些位的值將丟棄。例如,下面的程序片段將35右移2次,它的2個低位被移出丟棄,也將結果8賦給變數a:
int a = 35;
a = a 2; // a still contains 8
用二進位表示該過程可以更清楚地看到程序的運行過程:
00100011 35
2
00001000 8
將值每右移一次,就相當於將該值除以2並且捨棄了餘數。你可以利用這個特點將一個整數進行快速的2的除法。當然,你一定要確保你不會將該數原有的任何一位移出。
右移時,被移走的最高位(最左邊的位)由原來最高位的數字補充。例如,如果要移走的值為負數,每一次右移都在左邊補1,如果要移走的值為正數,每一次右移都在左邊補0,這叫做符號位擴展(保留符號位)(sign extension),在進行右移操作時用來保持負數的符號。例如,–8 1 是–4,用二進位表示如下:
11111000 –8
1
11111100 –4
一個要注意的有趣問題是,由於符號位擴展(保留符號位)每次都會在高位補1,因此-1右移的結果總是–1。有時你不希望在右移時保留符號。例如,下面的例子將一個byte型的值轉換為用十六進位表示。注意右移後的值與0x0f進行按位與運算,這樣可以捨棄任何的符號位擴展,以便得到的值可以作為定義數組的下標,從而得到對應數組元素代表的十六進位字元。
// Masking sign extension.
class HexByte {
static public void main(String args[]) {
char hex[] = {
‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’,
‘8’, ‘9’, ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f”
};
byte b = (byte) 0xf1;
System.out.println(“b = 0x” + hex[(b 4) 0x0f] + hex[b 0x0f]);
}
}
該程序的輸出如下:
b = 0xf1
無符號右移
正如上面剛剛看到的,每一次右移,運算符總是自動地用它的先前最高位的內容補它的最高位。這樣做保留了原值的符號。但有時這並不是我們想要的。例如,如果你進行移位操作的運算數不是數字值,你就不希望進行符號位擴展(保留符號位)。當你處理像素值或圖形時,這種情況是相當普遍的。在這種情況下,不管運算數的初值是什麼,你希望移位後總是在高位(最左邊)補0。這就是人們所說的無符號移動(unsigned shift)。這時你可以使用Java的無符號右移運算符,它總是在左邊補0。下面的程序段說明了無符號右移運算符。在本例中,變數a被賦值為-1,用二進位表示就是32位全是1。這個值然後被無符號右移24位,當然它忽略了符號位擴展,在它的左邊總是補0。這樣得到的值255被賦給變數a。
int a = -1;
a = a 24;
下面用二進位形式進一步說明該操作:
11111111 11111111 11111111 11111111 int型- 1的二進位代碼
24 無符號右移24位
00000000 00000000 00000000 11111111 int型255的二進位代碼由於無符號右移運算符只是對32位和64位的值有意義,所以它並不像你想像的那樣有用。因為你要記住,在表達式中過小的值總是被自動擴大為int型。這意味著符號位擴展和移動總是發生在32位而不是8位或16位。這樣,對第7位以0開始的byte型的值進行無符號移動是不可能的,因為在實際移動運算時,是對擴大後的32位值進行操作。下面的例子說明了這一點:
// Unsigned shifting a byte value.
class ByteUShift {
static public void main(String args[]) {
char hex[] = {
‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’,
‘8’, ‘9’, ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’
};
byte b = (byte) 0xf1;
byte c = (byte) (b 4);
byte d = (byte) (b 4);
byte e = (byte) ((b 0xff) 4);
System.out.println(” b = 0x”
+ hex[(b 4) 0x0f] + hex[b 0x0f]);
System.out.println(” b 4 = 0x”
+ hex[(c 4) 0x0f] + hex[c 0x0f]);
System.out.println(” b 4 = 0x”
+ hex[(d 4) 0x0f] + hex[d 0x0f]);
System.out.println(“( b 0xff) 4 = 0x”
+ hex[(e 4) 0x0f] + hex[e 0x0f]);
}
}
該程序的輸出顯示了無符號右移運算符對byte型值處理時,實際上不是對byte型值直接操作,而是將其擴大到int型後再處理。在本例中變數b被賦為任意的負byte型值。對變數b右移4位後轉換為byte型,將得到的值賦給變數c,因為有符號位擴展,所以該值為0xff。對變數b進行無符號右移4位操作後轉換為byte型,將得到的值賦給變數d,你可能期望該值是0x0f,但實際上它是0xff,因為在移動之前變數b就被擴展為int型,已經有符號擴展位。最後一個表達式將變數b的值通過按位與運算將其變為8位,然後右移4位,然後將得到的值賦給變數e,這次得到了預想的結果0x0f。由於對變數d(它的值已經是0xff)進行按位與運算後的符號位的狀態已經明了,所以注意,對變數d再沒有進行無符號右移運算。
B = 0xf1
b 4 = 0xff
b 4 = 0xff
(b 0xff) 4 = 0x0f
位運算符賦值
所有的二進位位運算符都有一種將賦值與位運算組合在一起的簡寫形式。例如,下面兩個語句都是將變數a右移4位後賦給a:
a = a 4;
a = 4;
同樣,下面兩個語句都是將表達式a OR b運算後的結果賦給a:
a = a | b;
a |= b;
下面的程序定義了幾個int型變數,然後運用位賦值簡寫的形式將運算後的值賦給相應的變數:
class OpBitEquals {
public static void main(String args[]) {
int a = 1;
int b = 2;
int c = 3;
a |= 4;
b = 1;
c = 1;
a ^= c;
System.out.println(“a = ” + a);
System.out.println(“b = ” + b);
System.out.println(“c = ” + c);
}
}
該程序的輸出如下所示:
a = 3
b = 1
c = 6
java位移運算符有什麼意義
給你舉個例子,乘除法可以使用位運算,速度更快。很多底層的東西是用位運算去實現的,你去看看java的很多源碼,還有IO流的處理有時候會用位運算,二進位文件的讀寫解析等都需要位運算,如果你了解底層的東西,你會位運算,這回讓你的程序生涯更加精彩,望採納,謝謝
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/150542.html