2017-08-04 214 views
2

我有Sign Bit,Exponent和Mantissa(如下面的代码所示)。我试图把这个价值变成浮动。这样做的目的是让59.98(它会读作59.9799995将符号位,指数和尾数转换为浮点数?

uint32_t FullBinaryValue = (Converted[0] << 24) | (Converted[1] << 16) | 
          (Converted[2] << 8) | (Converted[3]); 

unsigned int sign_bit = (FullBinaryValue & 0x80000000); 
unsigned int exponent = (FullBinaryValue & 0x7F800000) >> 23; 
unsigned int mantissa = (FullBinaryValue & 0x7FFFFF); 

我本来想这样做只是把他们的点点滴滴,他们应该像这样:

float number = (sign_bit << 32) | (exponent << 24) | (mantissa);

但是这给了我2.22192742e+009.

我当时要使用的公式:1.mantissa + 2^(exponent-127),但你不能把一个小数位二进制数。

然后我尝试了(指数,特征,后期尾数)抓住每个单独的值和我

Characteristic: 0x3B (Decimal: 59) 
Mantissa: 0x6FEB85 (Decimal: 7334789) 
Exponent: 0x5 (Decimal: 5) This is after subtracting it from 127 

然后我要带这些数字,只是改造成一个printf。但我不知道如何将Mantissa十六进制转换为它应该是的(向负指数供电)。

关于如何将这三个变量(符号位,指数和尾数)转换为浮点数的任何想法?

编辑PAULř 以下是在最少的,完整和Verifable格式的代码。 我在那里添加uint8_t Converted[4]只是因为它是我结束的值,它使它可以运行。

#include <stdio.h> 
#include <stdint.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 

int main(int argc, char *argv[]) 
{ 
    uint8_t Converted[4]; 
    Converted[0] = 0x42; 
    Converted[1] = 0x6f; 
    Converted[2] = 0xEB; 
    Converted[3] = 0x85; 

    uint32_t FullBinaryValue = (Converted[0] << 24) | (Converted[1] << 16) | 
           (Converted[2] << 8) | (Converted[3]); 

    unsigned int sign_bit = (FullBinaryValue & 0x80000000); 
    unsigned int exponent = (FullBinaryValue & 0x7F800000) >> 23; 
    unsigned int mantissa = (FullBinaryValue & 0x7FFFFF); 

    float number = (sign_bit) | (exponent << 23) | (mantissa); 

    return 0; 
} 
+1

你的变化是关闭的一个 - 尝试:'uint32_t的数量=(sign_bit << 31)| (指数<< 23)| (尾数);'然后使用联合或其他任何方法将其转换为'float'。 –

+0

如果您打算假设'double'是根据IEEE 754实现的,那么使用['std :: numeric_limits :: is_iec559'](http://en.cppreference)来验证您的假设可能是一个好主意。 COM/W/CPP /类型/ numeric_limits/is_iec559)。 –

+0

@PaulR感谢您的快速回复。当我这样做的时候,当它应该是'59.9799995'时,我得到'1.11463104e + 009'' – Rayaarito

回答

3

的问题是,第一表达float number = (sign_bit << 32) | (exponent << 24) | (mantissa);计算一个unsigned int然后投射该值float。基本类型之间的转换将保留值而不是内存表示。你试图做的是重新解释内存表示为一种不同的类型。您可以使用reinterpret_cast

试试这个:

uint32_t FullBinaryValue = (Converted[0] << 24) | (Converted[1] << 16) | 
          (Converted[2] << 8) | (Converted[3]); 


float number = reinterpret_cast<float&>(FullBinaryValue); 
+0

这工作。很高兴知道我不需要做所有这些工作。总有一种更简单的方式,呃?现在该研究一下reinterpret_cast的功能了。非常感谢你。为什么你在''末尾加上'&'? – Rayaarito

+0

'reinterpret_cast '是一个很好的老式'(浮动)'演员穿着花哨的C++说话。 – pm100

+1

@Dave'reinterpret_cast'用于将内存解释为特定类型,无论类型系统可能需要说明什么。因此,它只能有意义地产生指针和引用。它不会转换值,它会产生内存位置,就像它是给定类型一样。 'reinterpret_cast '会引用你传递给它的任何东西,并假装它是一个对float的引用(因此'&')。你也可以'reinterpret_cast (&FullBinaryValue);'。但是你不能用它直接在值类型之间转换,比如'reinterpret_cast (FullBinaryValue);'。 –