【问题标题】:Address Type conversion of float to intfloat 到 int 的地址类型转换
【发布时间】:2016-09-13 20:46:49
【问题描述】:

我很好奇这个函数的作用以及它为什么有用。我知道这确实将浮点数转换为整数,任何详细解释将不胜感激。

unsigned int func(float t)
{
    return *(unsigned int *)&t;
}

谢谢

【问题讨论】:

标签: c pointers floating-point type-conversion


【解决方案1】:

假设floatunsigned int 的大小相同,它会给出一个unsigned int 值,该值使用与提供的float 相同的二进制表示(基础位)表示。

然后,调用者可以对返回值应用按位运算,并分别访问各个位(例如符号位、构成指数和尾数的位)。

机制是(unsigned int *)&t 转换为指向unsigned int 的指针。 * 然后获取该位置的值。最后一步正式具有未定义的行为。

对于floatunsigned int 具有不同大小的实现(编译器),行为可以是任何东西。

【讨论】:

  • 无论floatunsigned 的大小如何,行为都是未定义的。
  • 没错,EOF。因此是“最后一步……”这句话。
【解决方案2】:

它返回unsigned integer,其二进制表示与给定float的二进制表示相同。

uint_var = func(float_var);

本质上等同于:

memcpy(&uint_var, &float_var, sizeof(uint_var));

这样的类型双关会导致未定义的行为,因此这样的代码不可移植。然而,这在低级编程中并不少见,因为编译器的实现依赖行为是已知的。

【讨论】:

  • 这是未定义的行为。
  • @EOF - 从技术上讲,是的,但这是系统编程和嵌入式编程的常见做法,在这两个领域中没有合理的替代技术。
  • @EOF 我对此添加了一些内容。
【解决方案3】:

这并不完全将浮点数转换为 int 本身。在大多数(几乎所有)平台上,浮点数是具有以下四个字节的 32 位实体:

  1. 符号+7位指数
  2. 8thBitOfExponent+first7bitsOfMantissa
  3. 尾数的下 8 个
  4. 尾数的后 8 位

而无符号数只是 32 位数字(按照平台规定的字节顺序)。

直接的 float->unsigned int 转换会尝试将 float 的实际值硬塞到它可以容纳的最接近的 unsigned 中。此代码直接复制构成浮点数的位,而不试图解释它们的含义。所以 1.0f 转换为 0x3f800000(假设大端)。

上面对平台做了很多令人毛骨悚然的假设(在某些平台上,您会遇到大小不匹配的情况,最终可能会出现截断甚至内存损坏:-()。我也不完全确定您为什么' 想这样做(也许更容易做一些操作?序列化?)。无论如何,我个人更喜欢做一个显式的 memcpy() 以使发生的事情更明显。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-06
    • 2016-09-01
    • 2011-09-28
    • 2018-03-11
    相关资源
    最近更新 更多