这是在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);
}
}
答案 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.
}