使用联合计算 log2

Calculating log2, with unions

我发现以下代码计算 log2 of 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 值实际上是什么?谢谢。

您的 floatint 共享相同的内存位置。所以float占用的字节与int占用的字节相同。但它们的意思完全不同,因为 float 的二进制格式与 int 不同。所以你分配 float 值它会改变 int 但它的含义将完全不同。

联合是内存昂贵的时代产生的东西。它们用于节省内存。

当您声明联合时,它会足够大以容纳最大的成员。所以在这种情况下,vx 的大小将是 max(sizeof(f), sizeof(i)).

所以当你使用vx = {x}时,x的值会被放到已经为vx预留的内存中。当您使用 vx.f 时,内存中的任何内容都将被解释为 float,但是当您使用 vx.i 时,将被解释为 unsigned integer,但是原始二进制数据是相同的。

union 关键字基本上意味着 float f 和 unsigned int i 共享相同的内存。 初始化联合成员 f 然后读取 i 基本上是实现定义的。

你得到了浮点变量的二进制表示。聪明的编码器然后使用该二进制表示并缩放值,以便您获得输入值的 log2。

I can not understand how it uses something that is not initialized.

实际上vx.i被初始化了。联合将占用相同的内存位置。因此 vx.i 在初始化 vx.f 的同时被初始化。

And what vx.i value is actually?

要获得 vx.i 的实际值,您需要了解浮点数是如何存储在内存中的。在这里参考优秀答案 How are floating point numbers are stored in memory?

来自链接的答案,

如果 vx.f1.0 那么 vx.i 将是 3f800000(十六进制)