内联浮动到uint“表示”不起作用?

时间:2009-06-23 11:04:00

标签: c++ c

这是在C中,但我标记它是C ++,因为它是相同的。这是建立在:     Microsoft(R)32位C / C ++优化编译器版本14.00.50727.220(适用于80x86) 如果这有任何不同

为什么这样做?

(inVal为0x80)

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

(导致outVal为0x43000000 - 正确)

但这不是吗?

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

(导致outVal为0x00000080 - NOT CORRECT :()

在问这个问题之前,我用Google搜索了一下,发现java中的this function基本上可以满足我的需求。如果你对我正在尝试做的事情感到有点困惑,这个程序可能有助于解释它:

class hello
{
    public static void main(String[] args)
    {
        int inside = Float.floatToIntBits(128.0f);
        System.out.printf("0x%08X", inside);
    }
}

3 个答案:

答案 0 :(得分:7)

你试图获取非const临时的地址(你的(float)转换的结果) - 这在C ++中是非法的(也可能在C中)。因此,您的代码会导致垃圾。

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

答案 1 :(得分:2)

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

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

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

类型双关语也可以使用联合而不是指针强制转换来完成。使用复合文字和非标准__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支持是不存在的。

答案 2 :(得分:0)

假设: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.
}