1. 程式人生 > >C語言中的位移運算

C語言中的位移運算

位移運算

1.左移

//C左移表示式
x<<k;

  對於一個n位的運算元x,x<<k操作會生成一個值:x向左移動k位,丟棄最高的k位,並在右端補k個0。位移量應該是一個0~n-1之間的值。
  位移運算是從左至右可結合的,所以x<<j<<k等價於(x<<j)<<k。

2.右移

//C右移表示式
x>>k;

  一般而言,機器支援兩種形式的右移:邏輯右移和算術右移。邏輯右移在左端補k個0;算術右移是在左端補k個最高有效位。

3.一個例子

Tables Cool
引數x [01100011]  [10010101]
x << 4 [00110000]  [01010000]
x >> 4 (邏輯右移) [00000110]  [00001001]
x >> 4 (算術右移) [11110110]  [11111001]


  C語言並沒有明確定義應該使用哪種型別的右移。

  • 對於無符號資料(unsigned宣告的整形物件),右移必須是邏輯的;
  • 對於有符號資料(預設的宣告的整型物件),算術的或者邏輯的右移都可以。然而實際上,幾乎所有的編譯器/機器組合都對有符號資料使用算術右移,且許多程式設計師也都假設機器會使用這種右移。

  另一方面,Java對於如何進行右移有明確的定義。表示式x>>k會將x算術右移k個位置,而x>>>k會對x做邏輯右移。

位移操作的注意事項

1.位移k位,k很大

問題:對於一個由w位組成的資料型別,如果要移動k(k>>w)位會得到什麼結果呢?
  例如在一個32位的機器上計算下面的表示式會得到什麼結果:

int      lval = 0xFEDCBA98 << 32;
int      aval = 0xFEDCBA98 >> 46;
unsigned uval = 0xFEDCBA98 << 40;

  C 語言標準很小心地規避了說明在這種情況下該如何做。在許多機器上,當移動一個w位的值,移位指令只考慮位移量的低log2w位,因此實際上位移量就是通過計算k mod w得到的。在一臺32位的機器上,上面三個位移運算分別是移動0、4和8位,得到結果:

lval 0xFEDCBA98
aval 0xFFEDCBA9
uval 0x00FEDCBA

  不過這種行為對於C程式來說是沒有保障的,所以位移數量應該保持小於字長。

2.與位移有關的操作符優先順序問題

1<<2+3<<4

  在C語言中,加法(和減法)的優先順序比位移運算要高,然後按照從左至右結合性規則,上述表示式應該這樣解釋:

(1<<(2+3))<<4

參考資料

《深入理解計算機系統》 第2章 資訊的表示和處理

相關推薦

C語言運算異或“∧”的作用

1.概念 異或運算子”∧”也稱XOR運算子。它的規則是若參加運算的兩個二進位同號,則結果為0(假);異號則為1(真)。即 0∧0=0,0∧1=1, 1^0=1,1∧1=0。 運算 說明 0^0=0,0^1=1 0異或任何數,其結果

一招教你學會C語言運算

程式中的所有數在計算機記憶體中都是以二進位制的形式儲存的。位運算說穿了,就是直接對整數在記憶體中的二進位制位進行操作。注意,位運算只針對於整數進行操作。 運算子號 運算規則 1、&與運算:對應兩個二進位均為1時,結果位才為1,否則為0。(

C語言位移運算

位移運算 1.左移 //C左移表示式 x<<k;   對於一個n位的運算元x,x<<k操作會生成一個值:x向左移動k位,丟棄最高的k位,並在右端補k個0。位移量應該是一個0~n-1之間的值。   位移運算是從左至右可結合的,所以x

C#語言數據的運算

double int 運算 數字運算 double類型 數據 數字 語言 字符 1、數字運算:數字與數字的運算 支持運算:加(+)、減(-)、乘(*)、除(/)、求余(%) 返回運算:與運算類型相同 (1)int類型的數據與int類型的數據運算,返回運算是int類型; (2

常見位操作及運算應用舉例:1,C語言位運算子異或“∧”的作用2,異或運算的作用3,&(與運算)、|(或運算)、^(異或運算

  1 C語言中位運算子異或“∧”的作用: 異或運算子∧也稱XOR運算子。它的規則是若參加運算的兩個二進位同號,則結果為0(假);異號則為1(真)。即0∧0=0,0∧1=1,1∧1=0。如: 即071∧052,結果為023(八進位制數)。 “異或”的意思是判斷兩個相應的位值是否為“

C語言的模運算-hdu6124(打表,找規律)

題目連結:https://vjudge.net/problem/HDU-6124 題目描述: 題目大意就是給你一個數,判斷這個數 % 其它數後共有幾種結果。 這題對我來說最大的難點是我不太知道每個數 餘 其他的數應該得出什麼結果,後來參考了別人的部落格,才弄清楚了。現在我就舉一些例子來說明一下:

C語言異或運算在程式設計的妙用

異或運算子^也稱XOR運算子。它的規則是若參加運算的兩個二進位同號,則結果為0(假);異號則為1(真)。即0 ^ 0=0,0 ^ 1=1,1 ^ 1=0。 性質: (1) 一個數與1異或會翻轉 (2) 一個數與0異或保持不變 (3) 一個數異或它本身等於0

C語言關於指標的資料型別和指標運算的小結

有關指標的資料型別小結 記憶訣竅: 容易混淆的幾個int *p[n] 、int (*p)[n],其中int *p[n]是一個數組,陣列的元素是指標;int (*p)[n]是個指標,是一個指向二維陣列的

C語言補碼的整數運算特性

前言 本篇部落格以“SSD6-Exercise2-Data Lab: Manipulating Bits”為例,分析在對C語言中的整數採用補碼(two’s-complement)編碼的機器上,其整數運算的特性。 補碼 定義 最常見的有符

C語言的自增運算

main(){ int i=5,j=5,p,q; p=(i++)+(i++)+(i++); q=(++j)+(++j)+(++j); printf("%d,%d,%d,%d",p,q,i,j); } 請問各位P=多少 q=多少 它們為什麼會=於你們說的多少呢? c語言對於這

C語言指標初始化和常規運算

1. 指標初始化注意須知 <1>指標變數和普通變數一樣,外部或者靜態指標變數若未初始化,則被自動初始化為NULL,它的值為0(ASCII字元NULL的程式碼)。 <2>可以

c語言不同型別資料間的混合運算

      在程式中經常會遇到不同型別的資料進行運算,如果一個運算子兩側的資料型別不同,則會先自動進行資料型別轉換,使運算子兩側的資料型別相同,然後再進行運算,因此整型、實型、字元型資料間都可以進行混合運算     規律為:       (1)+、-、*、/、運算子兩側中有一

c語言浮點運算的inf和nan錯誤

============================================ 作者:yuanlulu http://blog.csdn.net/yuanlulu 版權沒有,但是轉載請保留此段宣告 ===============================

C語言的位運算

        在很多系統程式中常要求在位(bit)一級進行運算或處理。C語言提供了位運算的功能, 這使得C語言也能像組合語言一樣用來編寫系統程式。━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 操作符 作用 ────────────────────────────

C語言的取模(%)運算

C語言中規定,%運算子的兩個運算元必須同為整數型別,這個很好理解,平時用%也是這麼運算的,問題是如果這兩個運算元異號,那麼最後的計算結果該以哪個運算元的符號為準呢?C99標準中規定,若有a,b兩個整型資料作取模運算,則它們必須滿足以下等式的成立: (a / b) * b +

C語言字符、字符串、字符數組

文件 getc order 知識點 技術 ima 數組 c語言 align char a = ‘h‘; memory h char a[] = "Hello"; memory H e l l o ‘\0‘ stri

c語言一種典型的排列組合算法

scan .com nbsp 方法 can main else const 組合數 c語言中的全排列算法和組合數算法在實際問題中應用非常之廣,但算法有許許多多,而我個人認為方法不必記太多,最好只記熟一種即可,一招鮮亦可吃遍天 全排列: #include<stdio.h

c語言對字段寬度的理解?

style lib include creat span 演示 file code pre 1 /************************************************************************* 2 >

C語言求字符串的長度

類型 char 計算 語言 col pan har 字符 str1 在C語言中求字符串的長度,可以使用sizeof()函數和strlen()函數,後者需要引入string.h (#include <string.h>) 因為C語言字符串是以 \0 結尾表示結束的

sqlite學習筆記7:C語言使用sqlite之打開數據庫

實例 clas details code 返回 pri san filename stdlib.h 數據庫的基本內容前面都已經說得差點兒相同了。接下看看如何在C語言中使用sqlite。 一 接口 sqlite3_open(const char *filename, s