程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C語言中的移位運算

C語言中的移位運算

編輯:關於C語言

我曾經寫過一個顯示int類型數據二進制表示(補碼)的小程序,代碼如下:
  #include <limits.h> #include <stdio.h>
  int main(void) { int i = 0;int value = -128; // 0xffffff80 int shift = INT_MIN; // 0x80000000
  printf("The decimal value is: %d\n\n", value);
  printf("*      *       *       *\n");// print marks
  for (i = 0; i < 32; ++i) { if (shift & value) { printf("1");} else { printf("0");}
  shift = shift >> 1; // right shift 1 bit } // print bits
  return 0;}預期的輸出如下:
  The decimal value is: -128
  *       *       *       * 11111111111111111111111110000000然而實際的輸出如下:
  The decimal value is: -128
  *       *       *       * 11111111111111111111111111111111追蹤變量shift的值,發現其最高位(MSB)始終為1,我恍然大悟:這貨是算術右移,也就是說會保留符號位。於是,將shift改為(unsigned int)類型,果然解決了這個bug.說明,對於無符號數,進行的是邏輯右移,在移走的位上填0.
  下面我們自然會聯想到,是不是無符號數的左移為邏輯左移,而有符號數的左移為算術左移(即保留符號位)呢?答案是非也,事實上邏輯左移與算術左移是相同的,都不會保留符號位。
  右移運算的結果是不會超出表示范圍的。對於有符號數,右移一位後符號位空出,則必須保留原符號位的值;對於無符號數,沒有符號位,自然采取邏輯右移。
  左移運算則不同,它是有可能超出表示范圍的,也就是溢出。對於MSB位為0、MSB-1位為1的有符號正數,及MSB位為1、MSB-1位為0的有符號負數,左移必將益出(以int類型為例,其表示范圍是-2^31~2^31-1,對於大於等於2^30和小於等於-2^30-1的值左移1位,也就是乘以2,必然超出了表示范圍),且只有在這些情況下符號位才發生變化。既然已經溢出了,保留原符號位還有什麼意義?
  綜上,C語言中可以進行位運算的char/short/int/long (int)/long long (int)類型是有符號的,加上unsigned前綴則是無符號的,兩者在右移運算上是有區別的。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved