2013-05-02 55 views
0

然而,我在大學的C++講座卻開始了,但我得到了第一個問題。我們的任務是它實現在C++中一個自制的結構,通過IEEE 754標準浮點:在C++中創建自己的浮點結構

創建一個數據結構,它允許你存儲浮點數,閱讀它的原始字節表示和內部表示爲s,e和m。使用union和bit-field-struct的組合。 編寫一個程序,其中浮點數被分配給結構的浮點部分,並打印原始和s/e/m表示形式。對於raw和m使用十六進制輸出。

我有什麼到目前爲止是這樣的:

#include <stdio.h> 
#include <math.h> 

union { 
    struct KFloat { 
     //Using bit fields for our self made float. s sign, e exponent, m mantissa 
     //It should be unsigned because we simply use 0 and 1 
     unsigned int s : 1, e : 8, m : 23; 
    }; 
    //One bit will be wasted for our '.' 
    char internal[33]; 
}; 

float calculateRealFloat(KFloat kfloat) { 
    if(kfloat.s == 0) { 
     return (1.0+kfloat.m)*pow(2.0, (kfloat.e-127.0)); 
    } else if (kfloat.s == 1) { 
     return (-1.0)*((1.0+kfloat.m)*pow(2.0, (kfloat.e-127.0))); 
    } 
    //Error case when s is bigger 1 
    return 0.0; 
} 

int main(void) { 
    KFloat kf_pos = {0, 128, 1.5707963705062866};//This should be Pi (rounded) aka 3.1415927 
    KFloat kf_neg = {1, 128, 1.5707963705062866};//Pi negative 

    float f_pos = calculateRealFloat(kf_pos); 
    float f_neg = calculateRealFloat(kf_neg); 

    printf("The positive float is %f or ",f_pos); 
    printf("%e\n", f_pos); 

    printf("The negative float is %f or ",f_neg); 
    printf("%e", f_neg); 
    return 0; 
} 

這段代碼的第一個錯誤是明確表示,尾數是絕對錯誤的,但我不知道如何解決這個問題。

+2

你的尾數應該是一個整數。對尾數具有浮點值的IEEE的任何描述都沒有說明真相。 – john 2013-05-02 14:26:48

+0

你的要求特別要求'聯合'。 – Chad 2013-05-02 14:39:26

+0

但我該如何實施工會?我不知道什麼是原始的和內部的譴責。 – Jack 2013-05-02 14:40:42

回答

2

請重讀任務:

創建一個數據結構,它允許你存儲浮動, 讀取其原始字節表示 及其內部表示爲S,E和M。

,這並不意味着你應該存儲字符串

我會做這樣的方式如下:

union MyFloat 
{ 
    unsigned char rawByteDataRep[4]; 
    unsigned int rawDataRep; 
    float   floatRep; 
    struct{ // not checked this part just copied from you 
    unsigned s : 1; 
    unsigned e : 8; 
    unsigned m : 23; 
    }    componentesRep; 
} 

但要小心! 除了這種聯合轉換模式被廣泛使用的事實之外,如果您讀取的另一個聯合成員不是已寫入的成員,則C-Standard指出結果爲未定義的行爲

編輯: 添加UINT32代表

void testMyfloat() 
{ 
    MyFloat mf; 
    mf.floatRep = 3.14; 
    printf("The float %f is assembled from sign %i magnitude 0x%08x and exponent %i and looks in memory like that 0x%08x.\n", 
     mf.floatRep, 
     (int)mf.componentesRep.s, 
     (unsigned int)mf.componentesRep.m, 
     (int)mf.componentesRep.e, 
     mf.componentesRep.rawDataRep); 

} 
+0

我認爲指數是可以被簽署的 – 2013-05-02 15:29:41

+0

這個行爲並沒有完全由C標準定義。它規定,當訪問存儲的最後一個以外的聯合成員時,字節將被重新解釋爲新類型。顯然,這些表示有些與實現有關。如果將'unsigned int'更改爲'uint32_t',那麼在此答案中定義的聯合可能在許多實現中起作用,除了由字節順序和位字段順序造成的問題之外。 – 2013-05-02 16:28:28

+0

IEEE-754二進制數的存儲指數總是非負數。當它被轉換爲實際的指數時,它通過從存儲的值中減去127(對於一個32位的'float')而變成一個有符號的值。 – 2013-05-02 16:31:15

1

布魯斯·道森對浮點表示與算法的優秀的系列博客文章。本系列中的最新版本有很多鏈接,詳細討論此主題的前幾篇文章是here