天天看點

int,float,double型轉換深析

int整型: .net中特指Int32為32位長度符号整型變量

float:單精度浮點數32位長度1位符号位8位指數位與23位資料位 .net中又稱為Single

double:64位長度雙精度浮點數1位符号位11位指數位52位資料位

它們互相關系就:int可以穩式轉換成float和double,float隻能強制轉換成int但可以隐式轉換成double,double隻能強制轉換成float和int

  廢話說完這就出現了幾個困難而且比較意思困難

  1 int i = Int32.MaxValue;

  2 float f = i;

  3 int j = (int)f;

  4 bool b = i == j;

  這裡b=false。剛才這個操作,如果我們把float換成long,第一次進行隐式轉換,第二次進行強制轉換結果将會true。乍一看float.MaxValue比int.MaxValue大了不知道多少倍,然而這個隐式轉換中卻造成了資料丢失。int.MaxValue這個值等于2^31-1,寫成二進制補碼形式就01111…(31個1)。這個數表示成float計數科學計數法時候将會寫成+0.1111…(23個1)*2^31。對于那31個1裡面最後8個被float無情抛棄了。是以再将這個float強制轉換回int時候,對應int二進制補碼表示已經變成了0111…(23個1)00000000。這個數與最初那個int相差了255,是以造成了不相等。

  那麼提出另一個困難,嘛樣int變成float再變回來和從前值相等呢?這個困難其實完全出那23位float資料位上了。對于一個int把它寫成二進制形式之後成為了個一32個長度0、1排列對于這個排列隻要第一個1與最後一個1之前間距不超過23,那麼它轉換成float再轉換回來兩個值就會相等。這個困難與大小無關而且這個集合int這個全集下并不連續。

  1 double d = 0.6;

  2 float f = (float)d;

  3 double d2 = f;

  4 bool b = d == d2;

  這裡b也false。剛才這個操作如果開始另d等于0.5結果就将會true。乍一看0.6這個數這麼短,double和float都肯定能夠表示那麼轉換過去,再轉換回來結果理應相等。其實這因為我們用十進制思考困難太久了。如果我們0.6化成二進制小數,可以發現得到結果0.10011001……(1001循環)這一個無限循環小數。是以不管float還double它存儲0.6時候都無法完全儲存它精确值(計算機不懂分數呵呵)。這樣話由于float儲存23位,而double儲存52位,就造成了double轉化成float時候丢失掉了一定資料,再轉換回去時候那些丢掉值被補成了0。是以這個後來double和從前double值已經不再一樣了。

  這樣就又産生了一個困難,嘛樣double轉換成float再轉換回來兩個值相等呢?其實這個困難與剛才int那個困難驚人相似(廢話都和float打交道能不相似麼)隻不過我們還需要考慮double比float多了3位指數位,太大數double能表示但float不行。

  還一個算數學上困難嘛樣十進制小數表示成二進制不無限小數呢?這個困難可以說完全成為數學範疇内困難了,但比較簡單,答案也很明顯。對于所最後一位以5結尾十進制限小數都可以化成二進制限小數(雖然這個小數可能長到沒譜)。

  最後一個意思困難,剛才說過0.6表示成為二進制小數之後0.1001并且以1001為循環節無限循環小數,那麼我們将它存成浮點數時候一定會某個位置将它截斷(比如float23位和double52位)。那麼真正存記憶體裡這個二進制數轉化回十進制到底比原先十進制數大呢還小呢?答案It depends。人計算十進制時候四舍五入,計算機再計算二進制小數也挺簡單就0舍1入。對于float要截斷成為23位,假如卡24位上1那麼就會造成進位,這樣話存起來值就比真正十進制值大了。如果0就舍去,那麼存起來值就比真正十進制值小了。是以這可以合了解釋一個困難,就0.6d轉換成float再轉換回double,它值0.60000002384185791這個值比0.6大,解釋就0.6二進制科學計數法表示第24位1造成了進位

  到了這裡仍然一事不解,就對于浮點數硬體雖然給予了計算上支援但它與十進制之間互相轉換到底怎麼樣做到呢。又誰做呢(彙編器還編譯器)這個東西突出展現存記憶體裡數明顯實際與0.6不等但無論哪種語言都能夠Debug以及輸入時候将它正确顯示成0.6提供給使用者(源代碼員)。最好執行個體就double和ToString辦法如果我寫double d=0.59999999999999999999999999999d.ToString()給我0.6。誠然對于double來說,我寫那個N長數與0.6記憶體裡存東西一樣,但計算機又如果處理方案了,将一個實際與0.6不相等數變回0.6并顯示給我呢?關于這個困難歡迎大家讨論并請高手指教一二?

c++

繼續閱讀