我发现以下代码计算出log2
中的float x
:
union { float f; unsigned int i; } vx = { x };
float y = vx.i;
y *= 1.0 / (1 << 23);
y = y - 126.94269504f;
return y;
union的f
参数被初始化为输入x
,然后使用i
吗?我不明白它如何使用未初始化的东西。 vx.i
的实际值是多少?谢谢。
答案 0 :(得分:5)
我不明白它如何使用未初始化的东西。
实际上vx.i
已初始化。联合将占用相同的内存位置。因此,vx.i
在初始化vx.f
的同时被初始化。
什么是vx.i值呢?
要获取vx.i
的实际值,您需要了解浮点数如何存储在内存中。在此处How are floating point numbers are stored in memory?
从链接的答案中,
如果vx.f
为1.0
,则vx.i
将为3f800000
(十六进制)
答案 1 :(得分:3)
联盟是从内存昂贵的时代开始的。它们用于节省内存。
声明工会时,工会的大小足以容纳最大的会员。因此,在这种情况下,vx
的大小将为max(sizeof(f), sizeof(i))
。
因此,当您使用vx = {x}
时,x
的值将放入为vx
保留的内存中。当您使用vx.f
时,该内存中的所有内容将被解释为float
,但是当您使用vx.i
时将被解释为unsigned integer
,但是原始二进制数据是相同的。
答案 2 :(得分:3)
union关键字基本上意味着float f和unsigned int我共享相同的内存。 初始化联合成员f,然后读取i基本上是实现定义的。
发生的事情是您获得了float变量的二进制表示形式。然后,聪明的编码器使用该二进制表示形式并缩放该值,以便获得输入值的log2。
答案 3 :(得分:2)
您的float
和int
共享相同的内存位置。因此float
占用的字节与int
的字节相同。但是它们的含义完全不同,因为float的二进制格式与int不同。因此,在分配浮点值时,它将更改int,但其含义将完全不同。