浮點數、位與操作符、移位操作符


  最近開始復習基礎知識,發現才看到浮點數就一大堆疑問,上網搜了一大堆不是這個錯就是那個錯,上機一驗證發現都有問題,干脆自己整理整理這方面知識,因為是用代碼驗證的,所以又涉及到與位操作符和移位操作符的內容。

  Visual C++中,float的32位這樣分: 符號位(S):1位  階碼(E):8位  尾數(M):23位

  其中符號位就是正負號(float和double都是不能和unsigned合用的,所以一定有正負)。

  先介紹尾數,尾數是一個1.MMMMMMM……(23個M),所以尾數是一個>=1&&<=2的數的小數部分,翻譯成尾數還是很恰當的。

  我們可以把小數看成 V=+/-  1.MMMMMMM……(23個M) * (2^E’) 這種形式,那階碼的意義就出來了,是2的冪次,因為有8位,所以能夠表示[0,255],為了表示負數,這里采用移碼方式(而不是整數中的補碼方式,理由還沒想清楚),即實際的2^E’的E’是階碼E-127,即范圍變成[-127,128](很多資料上說[-128,127]是錯誤的),直觀的說E'表示1.MMMMMMM……小數點的移位,正數則小數點向右移,負數小數點向左移。

  用一段輸出float內存值的代碼來驗證下:

#include <iostream>
#include <string>
using namespace std;

int main(){
	float f = -3.0f;
	unsigned int* pa = (unsigned int*)(&f); 
	for(int i = 31;i >= 0;i--)
		cout << (*pa>>i &  0x01) << (i==31||i==23? "- ": "  "); 
	cout << "\n ";

	return 0;
}

 -3.0=- 1.1000000(一共22個0) * (2^1) (1.1在十進制中表示1.5,E'=1 得到E=128=10000000)

 

  寫這段驗證代碼的時候順便復習了下位與操作符(&)和移位操作符(<<  >>),以前完全沒注意啊啊啊啊啊啊啊啊

(1)float、double、long double等類型不允許直接進行位與操作符啊,可用間接的方法變通,如float取地址(也是&符號)轉換為unsigned int類型,再用取值操作符(*),這樣編譯器會以為是unsigned int類型。

(2)使用int、short、long移位時最好加上unsigned,這樣就是匯編中邏輯移位(即全部移位),如果不加unsigned情況就較為復雜,正數全是邏輯移位,負數左移時保持符號位為1、右邊補0,負數右移時保持符號位為1,左邊補1,所以-1不管怎么右移都是-1。

(3)位與操作符就是將兩個數進行與操作,&0x01就相當於掩碼取出最后一位,其他位置成0

(4)位與操作符&的操作優先級小於移位操作符,但移位操作符小於取地址操作符&(取值操作符*),所以上面代碼不會出錯


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM