代码之家  ›  专栏  ›  技术社区  ›  Pod

inline float to uint“representation”不工作?

c c++
  •  0
  • Pod  · 技术社区  · 15 年前

    这是在C中,但我把它标记为C++,以防它是相同的。这是用以下材料建造的: 802.86微软(R)32位C/C++优化编译器版本1400、50727.220 如果有什么不同

    为什么会这样?

    (英瓦是0x80)

    float flt = (float) inVal;
    outVal = *((unsigned long*)&flt);
    

    (结果outval为0x43000000——正确)

    但这不是吗?

    outVal = *((unsigned long*)&((float)inVal));
    

    (导致outval为0x00000080--不正确:()

    在问这个问题之前,我搜索了一下,发现 this function 在Java中,基本上做我想做的事情。如果你对我要做的事情有点困惑,这个程序可能有助于解释:

    class hello
    {
        public static void main(String[] args)
        {
            int inside = Float.floatToIntBits(128.0f);
            System.out.printf("0x%08X", inside);
        }
    }
    
    3 回复  |  直到 15 年前
        1
  •  7
  •   Konrad Rudolph    15 年前

    您试图获取一个非常量临时地址(您的 (float) 这是非法的C++(也可能在C中)。因此,您的代码会产生垃圾。

    在您的第一个工作代码中,您没有使用临时代码,所以您的代码正在工作。请注意,从标准的角度来看,这仍然是不正确的定义,因为所涉及类型的大小和内部表示没有指定,并且可能因平台和编译器的不同而有所不同。不过,你可能很安全。

        2
  •  2
  •   Christoph    15 年前

    在C99中,您可以使用复合文字使此工作内联:

    unsigned long outVal = *((unsigned long *)&((float){ inVal }));
    

    文字 (float){ inVal } 将创建一个具有定义好地址的自动存储持续时间(即已分配堆栈)的变量。

    类型punning也可以使用联合而不是指针强制转换来完成。使用复合文字和非标准文字 __typeof__ 运算符,您甚至可以执行一些宏魔术:

    #define wicked_cast(TYPE, VALUE) \
        (((union { __typeof__(VALUE) src; TYPE dest; }){ .src = VALUE }).dest)
    
    unsigned long outVal = wicked_cast(unsigned long, (float)inVal);
    

    在优化方面,GCC更喜欢联合而不是指针类型转换。这可能根本不适用于MS编译器,因为据说它的C99支持是不存在的。

        3
  •  0
  •   Loki Astari    15 年前

    假设:inval和outval是参数。

    void func(int inVal,unsigned long* outVal)
    {
        float flt = (float) inVal;
    
        *outVal = (unsigned long)flt; // convert flot to unsigned long.
                                      // Then assign to the variable by de-ref
                                      // the pointer.
    }