同位運演算法
⑴ c語言位運算問題
位運算是指按二進制進行的運算。在系統軟體中,常常需要處理二進制位的問題。C語言提供了6個位操作
運算符。這些運算符只能用於整型操作數,即只能用於帶符號或無符號的char,short,int與long類型。
C語言提供的位運算符列表:
運算符 含義 描述
& 按位與 如果兩個相應的二進制位都為1,則該位的結果值為1,否則為0
| 按位或 兩個相應的二進制位中只要有一個為1,該位的結果值為1
^ 按位異或 若參加運算的兩個二進制位值相同則為0,否則為1
~ 取反 ~是一元運算符,用來對一個二進制數按位取反,即將0變1,將1變0
<< 左移 用來將一個數的各二進制位全部左移N位,右補0
>> 右移 將一個數的各二進制位右移N位,移到右端的低位被舍棄,對於無符號數,高位補0
1、「按位與」運算符(&)
按位與是指:參加運算的兩個數據,按二進制位進行「與」運算。如果兩個相應的二進制位都為1,
則該位的結果值為1;否則為0。這里的1可以理解為邏輯中的true,0可以理解為邏輯中的false。按位與其
實與邏輯上「與」的運算規則一致。邏輯上的「與」,要求運算數全真,結果才為真。若,
A=true,B=true,則A∩B=true 例如:3&5 3的二進制編碼是11(2)。(為了區分十進制和其他進制,本文規
定,凡是非十進制的數據均在數據後面加上括弧,括弧中註明其進制,二進制則標記為2)內存儲存數據
的基本單位是位元組(Byte),一個位元組由8個位(bit)所組成。位是用以描述電腦數據量的最小單位。
⑵ c語言中a^b和a&b分別是啥意思啊
a^b是位運算中異或的意思,相同為0不同為1
a&b是且運算,也是位運算,相同為1不同為0
⑶ pascal中位運算符有哪些是什麼意思
有shr,shl,and,or,xor.
shr是將一個數在二進制上右位移,如7 shr 1= 3,即 111 右移 1 位,得11,為十進制的3.
shl是將一個數在二進制上左位移,如7 shl 1= 14,即 111 左移 1 位,得1110,為十進制的14.
and是將兩個數用二進制的方法計算,如5 and 6=4,即 101 and 110 =4
11取1,10取0,00取0,所以101 and 110 = 100 ,為十進制的4.
or是將兩個數用二進制的方法計算,如5 and 6=8,即 101 and 110 =8
11取1,10取1,00取0,所以101 or 110 = 111 ,為十進制的8.
xor是將兩個數用二進制的方法計算,如5 and 6=3,即 101 and 110 =3
10取1,01取1,00取0,11取0, 所以101 and 110 = 011 ,為十進制的3.
換一種方法理解,1代表True,0代表False,同位運算,即是 and 必須是 True and True 才成立,為True(1),否則為False(0),如110 和101從右數第一位1,0取0,第二位0,1取0,第三位1,1取1,即為100,等於4.
其他的也是,or就是「或」,and是「與」,xor是「異或」,即True and False exit True else exit False。
這就是位運算。
⑷ 演算法:使用位運算判斷兩個數是否同為正,或同為負
示例沒有錯,如果符號相反,那麼異或之後所得數字元號為肯定為1,其他的非符號為取值可為0,可為1,那麼此時得出的相異或的結果肯定是一個小於0的數據(最大為-1),反之如果符號相同,則符號為為0,最小為0,比較結果返回布爾值。示例代碼沒錯的
⑸ 位運算符的問題,&不能進行int,float運算。為什麼
位運算符 只用於 整型。float 要轉為 整型, 否則 編譯 不能通過。
int x=2,z;
float y = 2.0;
z = x & (int) y; // 這樣才能通過編譯。不會自動轉換。否則有「illegal「 操作數錯誤。
printf("%x",z);
⑹ 怎麼理解位運算
運算規則:0假1真
同真為真是為與,同假為假是為或。
黑白顛倒說是非,陰陽交融真異或。
⑺ C語言位運算
按位與 | 按位或 ^
按位異或 ~ 取反 <<
左移 >> 右移<<
1. 按位與運算。按位與運算符"&"是雙目運算符。其功能是參與運算的兩數各對應的二進位相與。只有對應的兩個二進位均為1時,結果位才為1 ,否則為0。參與運算的數以補碼方式出現。
2. 按位或運算。按位或運算符「|」是雙目運算符。其功能是參與運算的兩數各對應的二進位相或。只要對應的二個二進位有一個為1時,結果位就為1。參與運算的兩個數均以補碼出現。 例如:9|5可寫算式如下: 00001001|00000101 00001101 (十進制為13)可見9|5=13 main(){ int a=9,b=5,c; c=a|b; printf("a=%d/nb=%d/nc=%d/n",a,b,c); }
3. 按位異或運算。按位異或運算符「^」是雙目運算符。其功能是參與運算的兩數各對應的二進位相異或,當兩對應的二進位相異時,結果為1。參與運算數仍以補碼出現,例如9^5可寫成算式如下: 00001001^00000101 00001100 (十進制為12) main(){ int a=9; a=a^15; printf("a=%d/n",a); }。
5. 左移運算。左移運算符「<<」是雙目運算符。其功能把「<< 」左邊的運算數的各二進位全部左移若干位,由「<<」右邊的數指定移動的位數, 高位丟棄,低位補0。例如: a<<4 指把a的各二進位向左移動4位。如a=00000011(十進制3),左移4位後為00110000(十進制48)。
⑻ 我不太懂位運算!!
位運算
在很多系統程序中常要求在位(bit)一級進行運算或處理。C語言提供了位運算的功能, 這使得C語言也能像匯編語言一樣用來編寫系統程序。
一、位運算符C語言提供了六種位運算符:
& 按位與
| 按位或
^ 按位異或
~ 取反
<< 左移
>> 右移
1. 按位與運算 按位與運算符"&"是雙目運算符。其功能是參與運算的兩數各對應的二進位相與。只有對應的兩個二進位均為1時,結果位才為1 ,否則為0。參與運算的數以補碼方式出現。
例如:9&5可寫算式如下: 00001001 (9的二進制補碼)&00000101 (5的二進制補碼) 00000001 (1的二進制補碼)可見9&5=1。
按位與運算通常用來對某些位清0或保留某些位。例如把a 的高八位清 0 , 保留低八位, 可作 a&255 運算 ( 255 的二進制數為0000000011111111)。
main(){
int a=9,b=5,c;
c=a&b;
printf("a=%d\nb=%d\nc=%d\n",a,b,c);
}
2. 按位或運算 按位或運算符「|」是雙目運算符。其功能是參與運算的兩數各對應的二進位相或。只要對應的二個二進位有一個為1時,結果位就為1。參與運算的兩個數均以補碼出現。
例如:9|5可寫算式如下: 00001001|00000101
00001101 (十進制為13)可見9|5=13
main(){
int a=9,b=5,c;
c=a|b;
printf("a=%d\nb=%d\nc=%d\n",a,b,c);
}
3. 按位異或運算 按位異或運算符「^」是雙目運算符。其功能是參與運算的兩數各對應的二進位相異或,當兩對應的二進位相異時,結果為1。參與運算數仍以補碼出現,例如9^5可寫成算式如下: 00001001^00000101 00001100 (十進制為12)
main(){
int a=9;
a=a^15;
printf("a=%d\n",a);
}
4. 求反運算 求反運算符~為單目運算符,具有右結合性。 其功能是對參與運算的數的各二進位按位求反。例如~9的運算為: ~(0000000000001001)結果為:1111111111110110
5. 左移運算 左移運算符「<<」是雙目運算符。其功能把「<< 」左邊的運算數的各二進位全部左移若干位,由「<<」右邊的數指定移動的位數,
高位丟棄,低位補0。例如: a<<4 指把a的各二進位向左移動4位。如a=00000011(十進制3),左移4位後為00110000(十進制48)。6. 右移運算 右移運算符「>>」是雙目運算符。其功能是把「>> 」左邊的運算數的各二進位全部右移若干位,「>>」右邊的數指定移動的位數。
例如:設 a=15,a>>2 表示把000001111右移為00000011(十進制3)。 應該說明的是,對於有符號數,在右移時,符號位將隨同移動。當為正數時, 最高位補0,而為負數時,符號位為1,最高位是補0或是補1 取決於編譯系統的規定。Turbo C和很多系統規定為補1。
main(){
unsigned a,b;
printf("input a number: ");
scanf("%d",&a);
b=a>>5;
b=b&15;
printf("a=%d\tb=%d\n",a,b);
}
請再看一例!
main(){
char a='a',b='b';
int p,c,d;
p=a;
p=(p<<8)|b;
d=p&0xff;
c=(p&0xff00)>>8;
printf("a=%d\nb=%d\nc=%d\nd=%d\n",a,b,c,d);
}
位域
有些信息在存儲時,並不需要佔用一個完整的位元組, 而只需占幾個或一個二進制位。例如在存放一個開關量時,只有0和1 兩種狀態, 用一位二進位即可。為了節省存儲空間,並使處理簡便,C語言又提供了一種數據結構,稱為「位域」或「位段」。所謂「位域」是把一個位元組中的二進位劃分為幾個不同的區域, 並說明每個區域的位數。每個域有一個域名,允許在程序中按域名進行操作。 這樣就可以把幾個不同的對象用一個位元組的二進制位域來表示。一、位域的定義和位域變數的說明位域定義與結構定義相仿,其形式為:
struct 位域結構名
{ 位域列表 };
其中位域列表的形式為: 類型說明符 位域名:位域長度
例如:
struct bs
{
int a:8;
int b:2;
int c:6;
};
位域變數的說明與結構變數說明的方式相同。 可採用先定義後說明,同時定義說明或者直接說明這三種方式。例如:
struct bs
{
int a:8;
int b:2;
int c:6;
}data;
說明data為bs變數,共占兩個位元組。其中位域a佔8位,位域b佔2位,位域c佔6位。對於位域的定義尚有以下幾點說明:
1. 一個位域必須存儲在同一個位元組中,不能跨兩個位元組。如一個位元組所剩空間不夠存放另一位域時,應從下一單元起存放該位域。也可以有意使某位域從下一單元開始。例如:
struct bs
{
unsigned a:4
unsigned :0 /*空域*/
unsigned b:4 /*從下一單元開始存放*/
unsigned c:4
}
在這個位域定義中,a占第一位元組的4位,後4位填0表示不使用,b從第二位元組開始,佔用4位,c佔用4位。
2. 由於位域不允許跨兩個位元組,因此位域的長度不能大於一個位元組的長度,也就是說不能超過8位二進位。
3. 位域可以無位域名,這時它只用來作填充或調整位置。無名的位域是不能使用的。例如:
struct k
{
int a:1
int :2 /*該2位不能使用*/
int b:3
int c:2
};
從以上分析可以看出,位域在本質上就是一種結構類型, 不過其成員是按二進位分配的。
二、位域的使用位域的使用和結構成員的使用相同,其一般形式為: 位域變數名·位域名 位域允許用各種格式輸出。
main(){
struct bs
{
unsigned a:1;
unsigned b:3;
unsigned c:4;
} bit,*pbit;
bit.a=1;
bit.b=7;
bit.c=15;
printf("%d,%d,%d\n",bit.a,bit.b,bit.c);
pbit=&bit;
pbit->a=0;
pbit->b&=3;
pbit->c|=1;
printf("%d,%d,%d\n",pbit->a,pbit->b,pbit->c);
}
上常式序中定義了位域結構bs,三個位域為a,b,c。說明了bs類型的變數bit和指向bs類型的指針變數pbit。這表示位域也是可以使用指針的。
程序的9、10、11三行分別給三個位域賦值。( 應注意賦值不能超過該位域的允許范圍)程序第12行以整型量格式輸出三個域的內容。第13行把位域變數bit的地址送給指針變數pbit。第14行用指針方式給位域a重新賦值,賦為0。第15行使用了復合的位運算符"&=", 該行相當於: pbit->b=pbit->b&3位域b中原有值為7,與3作按位與運算的結果為3(111&011=011,十進制值為3)。同樣,程序第16行中使用了復合位運算"|=", 相當於: pbit->c=pbit->c|1其結果為15。程序第17行用指針方式輸出了這三個域的值。
類型定義符typedef
C語言不僅提供了豐富的數據類型,而且還允許由用戶自己定義類型說明符,也就是說允許由用戶為數據類型取「別名」。 類型定義符typedef即可用來完成此功能。例如,有整型量a,b,其說明如下: int aa,b; 其中int是整型變數的類型說明符。int的完整寫法為integer,
為了增加程序的可讀性,可把整型說明符用typedef定義為: typedef int INTEGER 這以後就可用INTEGER來代替int作整型變數的類型說明了。 例如: INTEGER a,b;它等效於: int a,b; 用typedef定義數組、指針、結構等類型將帶來很大的方便,不僅使程序書寫簡單而且使意義更為明確,因而增強了可讀性。例如:
typedef char NAME[20]; 表示NAME是字元數組類型,數組長度為20。
然後可用NAME 說明變數,如: NAME a1,a2,s1,s2;完全等效於: char a1[20],a2[20],s1[20],s2[20]
又如:
typedef struct stu{ char name[20];
int age;
char sex;
} STU;
定義STU表示stu的結構類型,然後可用STU來說明結構變數: STU body1,body2;
typedef定義的一般形式為: typedef 原類型名 新類型名 其中原類型名中含有定義部分,新類型名一般用大寫表示, 以
便於區別。在有時也可用宏定義來代替typedef的功能,但是宏定義是由預處理完成的,而typedef則是在編譯時完成的,後者更為靈活方便。
⑼ 位運算符的C語言的六種位運算符
&按位與|按位或^按位異或~取反<<左移>>右移 按位與運算符&是雙目運算符。 其功能是參與運算的兩數各對應的二進位相與。只有對應的兩個二進位均為1時,結果位才為1 ,否則為0。參與運算的數以補碼方式出現。
例如:9&5可寫算式如下: 00001001 (9的二進制補碼)&00000101 (5的二進制補碼) 00000001 (1的二進制補碼)可見9&5=1。 按位與運算通常用來對某些位清0或保留某些位。例如把a 的高八位清 0 , 保留低八位, 可作 a&255 運算 ( 255 的二進制數為11111111)。 main(){inta=9,b=5,c;c=a&b;printf(a=%d
b=%d
c=%d
,a,b,c);} 按位或運算符「|」是雙目運算符。 其功能是參與運算的兩數各對應的二進位相或。只要對應的二個二進位有一個為1時,結果位就為1。參與運算的兩個數均以補碼出現。
例如: 9|5可寫算式如下: 00001001|00000101=00001101(十進制為13)可見9|5=13 main(){inta=9,b=5,c;c=a|b;printf(a=%d
b=%d
c=%d
,a,b,c);} 按位異或運算符「^」是雙目運算符。 其功能是參與運算的兩數各對應的二進位相異或,當兩對應的二進位相異時,結果為1。
參與運算數仍以補碼出現。
例如 9^5可寫成算式如下: 00001001^00000101=00001100(十進制為12) main(){inta=9;a=a^15;printf(a=%d
,a);} 求反運算符~為單目運算符,具有右結合性。 其功能是對參與運算的數的各二進位按位求反。
例如 ~9的求反運算為: ~(1001)結果為: 0110 左移運算符「<<」是雙目運算符。左移n位就是乘以2的n次方。 其功能把「<<」左邊的運算數的各二進位全部左移若干位,由「<<」右邊的數指定移動的位數,高位丟棄,低位補0。
1)例: a<<4 指把a的各二進位向左移動4位。如a=00000011(十進制3),左移4位後為00110000(十進制48)。
2)例: int i = 1; i = i << 2; //把i里的值左移2位 也就是說,1的2進制是000...0001(這里1前面0的個數和int的位數有關,32位機器,gcc里有31個0),左移2位之後變成 000...0100,也就是10進制的4,所以說左移1位相當於乘以2,那麼左移n位就是乘以2的n次方了(有符號數不完全適用,因為左移有可能導致符號變化,下面解釋原因)
需要注意的一個問題是:int類型最左端的符號位和移位移出去的情況. 我們知道,int是有符號的整形數,最左端的1位是符號位,即0正1負,那麼移位的時候就會出現溢出, 例如: int i = 0x40000000; //16進制的40000000,為2進制的01000000...0000 i = i << 1; 那麼,i在左移1位之後就會變成0x80000000,也就是2進制的100000...0000,符號位被置1,其他位全是0,變成了int類型所能表示的最小值,32位的int這個值是,溢出.如果再接著把i左移1位會出現什麼情況呢?
在C語言中採用了丟棄最高位的處理方法,丟棄了1之後,i的值變成了0. 左移里一個比較特殊的情況是當左移的位數超過該數值類型的最大位數時,編譯器會用左移的位數去模類型的最大位數,然後按余數進行移位,如: int i = 1, j = 0x80000000; //設int為32位 i = i << 33; // 33 % 32 = 1 左移1位,i變成2 j = j << 33; // 33 % 32 = 1 左移1位,j變成0,最高位被丟棄 在用gcc編譯這段程序的時候編譯器會給出一個warning,說左移位數>=類型長度.那麼實際上i,j移動的就是1位,也就是33%32後的余數.在gcc下是這個規則,不同編譯器可能會不完全相同.
總之左移就是: 丟棄最高位,0補最低位 右移運算符「>>」是雙目運算符。右移n位就是除以2的n次方
其功能是把「>>」左邊的運算數的各二進位全部右移若干位,「>>」右邊的數指定移動的位數。
例如:設 a=15,a>>2 表示把00001111右移為00000011(十進制3)。 應該說明的是,對於有符號數,在右移時,符號位將隨同移動。當為正數時, 最高位補0,而為負數時,符號位為1,最高位是補0或是補1 取決於編譯系統的規定。Turbo C和很多系統規定為補1。
右移對符號位的處理和左移不同: 對於有符號整數來說,比如int類型,右移會保持符號位不變,
例如: int i = 0x80000000; i = i >> 1; //i的值不會變成0x40000000,而會變成0xc0000000 就是說,對於有符號數, 符號位向右移動後,正數的話補0,負數補1, 對於有符號數,在右移時,符號位將隨同移動: 當為正數時, 最高位補0, 而為負數時,符號位為1, 也就是匯編語言中的算術右移.同樣當移動的位數超過類型的長度時,會取余數,然後移動余數個位. 最高位是補0或是補1 取決於編譯系統的規定。Turbo C和很多系統規定為補1。 負數10100110 >>5(假設字長為8位),則得到的是 11111101 總之,在C中,左移是邏輯/算術左移(兩者完全相同),右移是算術右移,會保持符號位不變.實際應用中可以根據情況用左/右移做快速的乘/除運算,這樣會比循環效
率高很多. x>>1;//相當於x/=2x<<1;//相當於x*=2x>>2;//x/=4x<<2;//x*=4x>>3;//x/=8x<<3;//x*=8以此類推. 無符號: main(){unsigneda,b;printf(inputanumber:);scanf(%d,&a);b=a>>5;b=b&15;printf(a=%d b=%d
,a,b);}請再看一例! main(){chara='a',b='b';intp,c,d;p=a;p=(p<<8)|b;d=p&0xff;c=(p&0xff00)>>8;printf(a=%d
b=%d
c=%d
d=%d
,a,b,c,d);} 1. 使特定位翻轉 要使哪幾位翻轉就將與其進行∧運算的該幾位置為1即可。
2 與0相∧,保留原值.
3.交換兩個值,不用臨時變數. 我們可以在不用引入其他變數就可以實現變數值的交換 用異或操作可以實現: a = a^b; //
(1) b = a^b; //
(2) a = a^b; //
(3) 異或操作滿足結合律和交換律,且由異或操作的性質知道,對於任意一個整數a^a=0; 證:(第(2)步中的a) a = a^b =(將第(1)步中的b代入b) a^(a^b) = b; (第(3)步中的b)b =a^b = (將第(1)步中的b代入b,將第(2)步中的a代入a) a^b^a^a^b = a^a^a^b^b = a; 清零 A數中為1的位,B中相應位為0。然後使二者進行&運算,即可達到對A清零目的。
取一個數中某些指定位 取數A的某些位,把數B的某些位置1,就把數A的某些位與1按位與即可。
保留一位的方法 數A與數B進行&運算,數B在數A要保留的位1,其餘位為零。
判斷奇偶性 將變數 a的奇偶性。a與1做位與運算,若結果是1,則 a是奇數;將 a與1做位與運算,若結果是0,則 a是偶數。 判斷int型變數a是奇數還是偶數 a&1 = 0 偶數 a&1 = 1 奇數
取int型變數a的第k位 (k=0,1,2……sizeof(int)),即a>>k&1
將int型變數a的第k位清0,即a=a&~(1<<k)
將int型變數a的第k位置1, 即a=a|(1<<k)
int型變數循環左移k次,即a=a<<k|a>>16-k (設sizeof(int)=16)
int型變數a循環右移k次,即a=a>>k|a<<16-k (設sizeof(int)=16)
整數的平均值
對於兩個整數x,y,如果用 (x+y)/2 求平均值,會產生溢出,因為 x+y 可能會大於INT_MAX,但是我們知道它們的平均值是肯定不會緋齙模?頤怯萌縵濾惴ǎ?/DIV> int average(int x, int y) //返回X,Y 的平均值 { return (x&y)+((x^y)>>1); }
判斷一個整數是不是2的冪,對於一個數 x >= 0,判斷他是不是2的冪 boolean power2(int x) { return ((x&(x-1))==0)&&(x!=0); }
不用temp交換兩個整數 void swap(int x , int y) { x ^= y; y ^= x; x ^= y; } php: $a ='dd'; $b = 'bb'; $a = $a ^ $b; $b = $a ^ $b;
$a = $a ^ $b; echo $a,' ', $b; 10 計算絕對值 int abs( int x ) { int y ; y = x >> 31 ; return (x^y)-y ; //or: (x+y)^y }
取模運算轉化成位運算 (在不產生溢出的情況下) a % (2^n) 等價於 a & (2^n - 1) 12 乘法運算轉化成位運算 (在不產生溢出的情況下) a * (2^n) 等價於 a<< n 13. 除法運算轉化成位運算 (在不產生溢出的情況下) a / (2^n) 等價於 a>> n 例: 12/8 == 12>>3 14 . a % 2 等價於 a & 1 15 if (x == a) x= b; else x= a; 等價於 x= a ^ b ^ x;
16 x 的 相反數 表示為 (~x+1)abc