代码之家  ›  专栏  ›  技术社区  ›  Mike Boers

将int存储为float

  •  8
  • Mike Boers  · 技术社区  · 14 年前

    假设我有一个API,它只允许我存储浮点数或浮点数数组。但是,我想在这里存储整数值。

    我(大致)明白我对2^23左右的直投是很好的,但是如果我想走得更高呢?有没有什么方法可以让我更充分地利用一个浮点的32位,并确保我会得到相同的数字?


    澄清:

    我正在用皮克斯的PRMan(即RenderMan)在点云上做一些操作。我可以用C或C++连接到预编译的点云API。PRMan在任何情况下都不必使用我正在存储的这些int;我只需要它在操作完附加到这些int的其他数据之后,完整地将它们交还给我。

    3 回复  |  直到 12 年前
        1
  •  9
  •   Oliver Charlesworth    14 年前

    可疑:

    在C中,您可以执行以下操作,这可能是不安全的(由于严格的别名规则):

    int i = XXX;
    float f;
    *(int *)&f = i;
    

    它依赖于这样的假设 sizeof(int) == sizeof(float)

    不那么可疑:

    更安全,但更冗长的是:

    int i = XXX;
    float f;
    memcpy(&f, &i, sizeof(int));
    

    这仍然依赖于匹配的数据类型大小。但是,以上两种方法都假设您正在使用的库的内部将 没有什么 所有的数据。例如,它不会对NaN或/-infinity等有任何特殊处理。

    安全:

    按照完全不同的思路,如果您愿意在每个int中浪费两个float,您可以执行以下操作:

    int i = XXX;
    float f[2] = { (i & 0xFFFF), ((unsigned)i >> 16 };
    

    最后一个是安全的(除了对浮点和整数大小的一些非常合理的假设)。

        2
  •  4
  •   Ben Voigt    14 年前

    尾数字段允许您存储23位。指数字段允许您存储 差不多8位 ,它宽8位,保留了一些值。还有一点迹象。

    避免指数中的保留值,您仍然可以存储31位的选择。

    你可能会发现 frexp ldexp 有用。

        3
  •  0
  •   R.. GitHub STOP HELPING ICE    14 年前

    这里给出的所有答案都假定您只想使用为浮点存储保留的字节作为存储int的位置。它们不允许您对用浮点值编码的int执行算术。如果你想算数,你就得用24.99位(也就是说,范围是-(2^24-1)到(2^24-1);我认为符号位是0.99位,而不是1位,因为不能用float的符号/大小表示来存储可能的最低值)和一组稀疏的较大值(例如,256的任何32位整数倍数都可以用float表示)。