Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 获取浮点数的符号、尾数和指数_C_Floating Point_Unions - Fatal编程技术网

C 获取浮点数的符号、尾数和指数

C 获取浮点数的符号、尾数和指数,c,floating-point,unions,C,Floating Point,Unions,我找到了这个密码 #include <stdio.h> union foo { struct float_guts { unsigned int fraction : 23; unsigned int exponent : 8; unsigned int sign : 1; } fg; float f; }; void print_float(float f) { union foo

我找到了这个密码

#include <stdio.h>

union foo
{
    struct float_guts
    {
        unsigned int fraction : 23;
        unsigned int exponent : 8;
        unsigned int sign     : 1;
    } fg;
    float f;
};

void print_float(float f)
{
    union foo ff;
    ff.f = f;
    printf("%f: %d 0x%X 0x%X\n", f, ff.fg.sign, ff.fg.exponent, ff.fg.fraction);
}

int main(void)
{
    print_float(0.25);
    return 0;
}
我试图理解为提取符号、尾数和指数,但至今不明白如何理解


有人能给我解释一下吗?

联合使结构和浮点共享相同的内存空间。 代码写入浮点成员,然后读取联合的另一个成员。它假设浮点有一个23位尾数,一个8位指数和一个符号位,然后打印它们

NB联合用于节省内存空间,写入一个成员和读取另一个成员是未定义的行为-它可能在某些系统上工作,也可能在其他系统上不工作。浮点映射也不是很好移植

获取浮点数的符号、尾数和指数

使用一个并集取决于知道浮点的格式和尾数,C.OP的方法中没有定义的东西可能会起作用,但可能不会。如果使用OPs方法,则会受到指数偏差、次正态数等因素的影响

获得标志

#include <stdbool.h>
#include <math.h>
bool sign = signbit(x);
#包括
#包括
布尔符号=符号位(x);
将浮点数分解为标准分数和 2的积分幂:

#include <math.h>
int exponent;
float fraction; // [0.5f to 1.0)
fraction = frexpf(x, &exponent);
#包括
整数指数;
浮点数;//[0.5f至1.0)
分数=frexpf(x,&指数);

首先,了解什么是IEEE-754单精度浮点格式。简单地说,它是存储浮点数的二进制格式。对于32位浮点数,它由一个单符号位(1负)、8位指数(超过127符号)和23位尾数/有效位(隐藏位格式)组成。关于如何转换为IEE754表示法或从IEE754表示法转换为IEE754表示法的例子不胜枚举,但只要说这是计算机用于存储浮点数的
1+8+23=32位
编码就足够了。例如,您的
0.25
数字存储为:

(0.25 float - value in memory)
 0 0 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -|
|s|      exp      |                  mantissa                   |
或以十六进制格式的
's'
'exp'
'尾数'

0  0x7d  0x0
联合
的整个问题与以下事实有关:
整数
也是一个
32位
值。因此,对于每个浮点值,都有一个等效的整数表示,可以从上面相同的32位派生。(这当然会带来您正在运行的硬件的持久性问题,因为这些位将以不同的方式存储在内存中)

尽管如此,由于注释和答案中的所有原因,不建议您在
int
(无符号)和
float
之间创建一个联合,这样您就可以满足内存中位的要求。例如:

typedef union {
    float fv;
    unsigned int iv;
} ifu;
如果您随后创建此
联合的一个实例
,并将您的
0.25
指定为浮点值,则它将存储在内存中,如上图所示(假设为小尾端等),例如:

然后,您可以将内存中的这些非常相同的位视为
浮点值(您的
0.25
值)或等效无符号整数值。使用
%u
0x%0x
的简单
printf
将为您提供:

1048576000   0x3e800000 (in hex)
这些位是非常相同的,您所做的只是查看对这些位的不同解释——要么作为浮点,要么作为整数


简而言之,这就是IEEE-754单精度浮点、符号位、指数、尾数、并集、无符号整数等效问题。问题远不止于此,但这将为您理解不同主题提供一个框架。

您希望得到什么输出?您实际得到什么输出?什么编译器,st您使用的是标准库和操作系统?这些标准库和操作系统的版本是什么?@Joachim Pileborg:代码运行得很好,我只是想了解它的工作原理。您期望什么?不要忘记尾数实际上是24位,因为MS位是一个隐含的
1
(0值除外)。指数也有一个偏移量。请阅读您知道格式是如何工作的吗?并集和结构只是表示格式的另一种方式。@Kevin问题标题是否不正确?是否应该是“一个<代码>并集如何工作?Hmmm“223位尾数”?(输入错误)。不同意“整数也是32位的”".OTOH,
uint32\u t
始终为32位。同意这两个观点。根据问题的级别,我尝试调整答案的级别,以提供相关信息,而不会进一步模糊或使主要问题与附带细节复杂化。有时我获得了正确的平衡,有时会留下一些需要改进的地方。对于pu在这里,我应该补充一点,为了便于讨论,我们假设int为32位。合理的平台对浮点值和整数使用相同的endian值,因为这样做有好处。C没有定义的东西,实际上可以是位字段的布局。
ifu tmp;
tmp.fv = 0.25;
1048576000   0x3e800000 (in hex)