【问题标题】:Calculating log2, with unions使用联合计算 log2
【发布时间】:2018-10-03 10:51:27
【问题描述】:

我发现以下代码计算了log2float 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 的实际价值是什么?谢谢。

【问题讨论】:

    标签: c unions logarithm


    【解决方案1】:

    我无法理解它如何使用未初始化的东西。

    其实vx.i已经初始化了。联合将占用相同的内存位置。因此vx.i 会在vx.f 初始化的同时进行初始化。

    vx.i 的实际值是多少?

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

    从链接的答案,

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

    【讨论】:

      【解决方案2】:

      联合是在内存昂贵的时候出现的。它们用于节省内存。

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

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

      【讨论】:

      • 非常感谢您的清晰解释。实际上有一个问题需要接受。我会投票 2 并接受最后一个。
      • @NewUser:谢谢!关于工会,有一个很好的问题,在答案部分有各种巧妙的技巧,与工会相关:stackoverflow.com/questions/4788965/…
      【解决方案3】:

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

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

      【讨论】:

      • 非常感谢您的清晰解释。实际上有一个问题需要接受。我会投票 2 并接受最后一个。
      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-07-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-09
        相关资源
        最近更新 更多