(題目2)本身實現浮點數轉換爲整數

咱們在寫程序時,老是會自覺或不自覺地頻繁用到類型轉換,好比將整數轉換爲浮點數或反之。函數

今天的題目主要討論基本類型的轉換(但和普通的類型轉換有所不一樣哦,詳見後文),考考你是否真的理解了類型轉換的本質。在面向對象系統中還會涉及類和接口的類型轉換,但它們和基本類型的轉換仍是有區別的,今天暫時不考慮。spa

(本人博客中全部題目都是我原創的,僅此一家,不買也來看看啊)指針

 

開始了,請聽題。code

 

題目很簡單,本身編寫一個模擬double到long的強制類型轉換實現。即實現以下效果但不能使用語言提供的強制類型轉換功能:對象

long a_long = (long) a_double;blog

考慮到語言之間的差別,下面分別說明一下題目的詳細要求。接口

 

1. 喜歡C語言的看這裏ip

請編寫一個函數get_int_from_float,其原型以下:

long get_int_from_double(double *)

該函數接受一個double指針類型的參數並返回其整數部分。

例如調用get_int_from_float(
5.2),返回5。

注意,對於很是大的數,例如1.5E100,其實際的整數部分(實際上它就是一個整數)應該是15後面跟99個0這個數,但這個數太大,即便是long型也表示不了。此時不得不對結果進行截斷(沒辦法,客觀上被限制了)。 已知條件:各種型的長度肯定,int和float都是32位,long和double都是64位。其餘已知條件見後文。 要求:見後文

 

 

2. Java或C#版get

請編寫一個方法或函數:getIntFromFloat,它具備一個double類型的參數,返回的是浮點數的整數部分。
其原型爲:

long getIntFromFloat(double)

注意事項見C語言版。

已知條件:參數始終是有效的浮點數,不考慮NaN等狀況。其餘見後文
要求:見後文

 

3. 喜歡Javascript或其餘腳本語言的看這裏:原型

請編寫一個函數getIntFromFloat,它接受一個浮點數,並返回該浮點數的整數部分。例如調用getIntFromFloat(5.2)則返回5

其原型爲:

function getIntFromFloat(f)

注意事項見C語言版。
已知條件:參數始終是有效的浮點數,不考慮NaN、非數字類型等狀況。其餘見後文 要求:見後文

 

 

共同的已知條件:

1. 浮點數的儲存格式(同時也是一個IEEE754浮點數的簡介哦,對題目不感興趣的也能夠看看這個)

(1) 題目裏的浮點數都是64位IEEE754雙精度浮點數,它們具備以下位模式(由低位到高位):

第0~51位,共52位:小數位,或尾數位
第52~62,共11位:指數部分
第63位:符號位,0爲正1爲負

(2) 尾數的規範化:

與咱們熟悉的十進制科學計數法相似,浮點數的小數不能隨便寫,必須是規範形式。規範形式就是整數部分爲1的小數,例如1.1、1.01等,非規範形式的尾數必須先轉成規範形式。

(下面都以2進制舉例)

例如101.11須要先轉成規範形式1.0111(至關於小數點左移了2位,即縮小了4倍)

規範化的好處是小數點位置固定了,不須要再額外花一些位來記錄小數點在哪裏了。

另外一個衍生出來的好處是整數部分的1是徹底固定的,因此能夠不要,使其變成隱藏的默認位。即只要存儲後面的0111便可,計算時,再將前面的1和.補上。

(3) 指數部分

指數部分也有講究。

首先是尾數轉成規範化之後須要調整指數部分的值,使得規範化先後整個數的值不變。

例如原來的101.11至關於101.11×2^0,尾數規範化爲1.0111後,指數部分須要補上2才行,即1.0111×2^2

這跟十進制是同樣的。例如123.45轉成科學計數法後是1.2345×10^2。

另一點是,指數部分不是直接存儲的,實際存儲的是原值減去一個「修正值」後的結果,對double來講,修正值是1023。計算時,將存儲的值加上1023計算出真正的指數大小(計算結果按11位有符號數來對待)。

這一點會讓不少人迷惑:爲何要這麼規定這不是蛋疼嗎!要說尾數規範化能夠簡化實現並節約一個實實在在的位出來,那指數的這個規定是爲了什麼呢?表示範圍沒有變大,也沒有節省位數,更是增長了一步額外的計算,真是出力不討好啊!

關於這一點,這裏先賣個關子,我後面再另開一篇博文詳細討論浮點數的時候再來解釋吧,嘿嘿。

---------------------------

好了,總結一下:

要將一個以位模式存儲的double轉換爲咱們能看懂的二進制科學計數法,須要先提取出符號位、指數和尾數部分,而後就能夠將其寫爲下面的形式:

(+-) 1.尾數 × 2^(指數+1023)

關於浮點數的詳細解釋可參考維基百科(英文的。沒辦法,中文的寫的太渣了)
http://en.wikipedia.org/wiki/Floating_point

 

2. 取得double的位模式

假設已有以下的實現,你在程序中可使用它們來獲取一個double的位模式:

long getDoubleBitPattern(double) // Java或C#

function getDoubleBitPattern(d) // JS等

long get_double_bit_pattern(double *) // C 注意:該方法或函數返回的long和原double具備相同的位模式(所以它們表示的是徹底不一樣的2個值)

 

 

共同的要求:

不能使用任何系統或語言提供的類型轉換功能,包括隱式轉換。

 

 

---------------------------

呼~~~好了,have fun!

相關文章
相關標籤/搜索