我的问题涉及IEEE 754单精度数字。 假设我有一个结构:
typedef struct __ieee754
{
int sign;
int exponent;
int mantissa;
} IEEE754,*pIEEE754;
我可以将其转换为单精度(1-8-23浮点数)吗?我正在使用C.
答案 0 :(得分:4)
假设您的实现使用float
的IEEE 754单精度数字,这样的事情应该可行
struct __ieee754 f;
/* set f to something valid */
float x = f.sign * f.mantissa * pow(2, f.exponent);
答案 1 :(得分:3)
假设32位unsigned int
和IEEE-754单精度float
类型:
union bla {
unsigned int a;
float b;
};
union bla num = {
(((unsigned int) f.sign & 1) << 31)
| (((unsigned int) f.exponent & 0xFF) << 23)
| ( (unsigned int) f.mantissa & 0x7FFFFF);
};
printf("%f\n", num.b)
答案 2 :(得分:3)
前两个答案中的一个必须是错误的 - 因为问题未明确。我们需要知道结构是否包含IEEE float组件的二进制表示,或者它是否包含数字定义。
基于它们是整数的事实,第一个更有可能:-4.2将表示为{1,0x81,0x066666}
或0xC0866666
。在这种情况下,@ ouah的答案是正确的,@ pmg将给出2.85e44。
另一方面,为了使@pmg的代码正确,-4.2的结构必须存储为{-1,-21,0x433333}
。然后应用@ ouah算法给出0xF5C33333
,当解释为IEEE浮点数时为-4.9489e32。
如果我们假设您使用的是第一个表示形式,那么就有一个非便携式处理器技巧可以简化您的代码。将结构重新定义为联合,如下所示。
union flt {
struct ieee754 {
unsigned int mantissa:23;
unsigned int exponent:8;
unsigned int sign:1;
} raw;
float f;
}
(您可能需要根据您的处理程序颠倒参数的顺序 - 并确保打包是正确的 - 这是非便携式部分)
现在你的代码可以作为位直接写入内存并将其作为浮点数读回:
union flt num;
num.raw.sign = 1;
num.raw.exponent = 129;
num.raw.mantissa = 0x66666;
printf("%f", num.f); //prints 4.2