2017-08-08 184 views
1

我想在IEEE 754雙精度的C++中從十六進制轉換爲float64。 這是我第一次玩點東西,所以也許我的代碼不夠乾淨。 我不知道爲什麼我的尾數給我奇怪的結果,但我認爲我做錯了什麼。十六進制浮點數IEEE 754雙精度C++

long int raw = 0x40000F0000000001; 
int sign = raw >> 63; 
long int mantissa = (raw & 0xFFFFFFFFFFFFF); 
mantissa +=1; 
double exp = ((raw >> 52) & 0x7FF) - 1023; 
double result = pow(-1., sign) * mantissa * pow(2.0, exp); 
cout << "MANTISSA: " << mantissa << " EXP: " << exp << endl; 
cout << "RESULT: " << result << endl; 

,輸出是:

MANTISSA: 16492674416642 EXP: 1 
RESULT: 3.29853e+13 

任何人都知道該怎麼辦呢?

謝謝

回答

2
long int raw = 0x40000F0000000001; 

是實現指定long是否足夠長的時間來保存多少位(通常在Windows上沒有,在Linux上,如果你編譯一個64位程序是,但不是32位。)

int sign = raw >> 63; 

此行有實現定義的行爲,如果符號位設置。 (似是而非的結果是1和-1,但沒有什麼可以阻止指定「42」的實現。)你會好得多定義rawuint64_t

long int mantissa = (raw & 0xFFFFFFFFFFFFF); 
mantissa +=1; 

這是你的問題。缺少的'1'位在所有位的前面處。您需要添加0x1000000000000代替(或更好,定義一個常量const uint64_t MantissaOffset = 1uLL << 52;和另一const uint64_t MantissaMask = MantissaOffset-1; - 這樣你就不必指望所有這些F S和0 S)

然後,您將有一個尾數是2 * * 52太大(所以你需要考慮在計算指數時。

double exp = ((raw >> 52) & 0x7FF) - 1023; 
double result = pow(-1., sign) * mantissa * pow(2.0, exp); 

...當然,這沒有考慮非正規數,NaN和INF中。

cout << "MANTISSA: " << mantissa << " EXP: " << exp << endl; 
cout << "RESULT: " << result << endl; 
1

這似乎眉,你的尾數是幾乎確定。對於0x40000F0000000001分數是0xF0000000001(至少52位),這正好是16492674416641。說實話,我不知道你爲什麼加1。

如果你想要一個很好的例子,你可以玩它,你可以看到this維基百科頁面。在本章的最後有一個如何取得雙從它的64位原始表示一步一步一個非常好的例子:

Given the hexadecimal representation 3FD5 5555 5555 5555(16), 
    Sign = 0 
    Exponent = 3FD(16) = 1021 
    Exponent Bias = 1023 (constant value; see above) 
    Fraction = 5 5555 5555 5555(16) 
    Value = 2^(Exponent - Exponent Bias) × 1.Fraction – Note that Fraction must not be converted to decimal here 
     = 2^-2 × (15 5555 5555 5555(16) × 2^-52) 
     = 2^-54 × 15 5555 5555 5555(16) 
     = 0.333333333333333314829616256247390992939472198486328125 
     ˜ 1/3 

此外,請注意:當你處理64位值是更安全的使用uint64_t類型,保證是64位大小。您可以通過包含<stdint.h>標題來使用它。

+0

他加入 '1',因爲你的示例代碼顯示了'1.Fraction'。並提取了大量的5,然後使用'15 ...' - 這是他正在嘗試添加的領先1。 –

+0

@MartinBonner好吧,那麼它肯定不是'+ = 1',因爲你已經在你的答案中提到了。 –

相關問題