我很好奇这个功能是做什么的,为什么它有用。我知道这会将float类型转换为整数,任何详细的解释都会很感激。
unsigned int func(float t)
{
return *(unsigned int *)&t;
}
由于
答案 0 :(得分:3)
返回unsigned integer
,其二进制表示与给定float
的二进制表示相同。
uint_var = func(float_var);
基本上相当于:
memcpy(&uint_var, &float_var, sizeof(uint_var));
像这样的类型惩罚会导致未定义的行为,因此像这样的代码不可移植。但是,它在低级编程中并不少见,因为编译器的依赖于实现的行为是已知的。
答案 1 :(得分:3)
假设float
和unsigned int
大小相同,它会给出一个unsigned int
值,该值使用与提供的{{1}相同的二进制表示(基础位)表示}。
然后,调用者可以对返回值应用按位运算,并分别访问各个位(例如符号位,构成指数和尾数的位)。
机制是float
将(unsigned int *)
转换为指向&t
的指针。然后unsigned int
获取该位置的值。最后一步正式具有未定义的行为。
对于*
和float
具有不同大小的实现(编译器),行为可以是任何内容。
答案 2 :(得分:2)
这并不能将float本身完全转换为int。在大多数(几乎所有)平台上,float是一个32位实体,具有以下四个字节:
而unsigned只是32位的数字(由平台决定的字节顺序)。
直接浮点数> unsigned int转换会尝试将浮点数的实际值变为最内部的无符号值。这段代码直接复制组成浮点数的位而不试图解释它们的含义。所以1.0f转换为0x3f800000(假设是大端)。
上面对平台做了相当多的grody假设(在某些平台上,你会有一个大小不匹配,最终可能会出现截断甚至内存损坏:-()。我也不完全确定你的原因“我想要做到这一点(或许可以让位操作更容易一些?序列化?)。无论如何,我个人更喜欢做一个显式的memcpy()来让它更明显地发生了什么。”