【问题标题】:Casting bit data To and From float将位数据转换为浮点数和从浮点数
【发布时间】:2013-12-23 23:52:16
【问题描述】:

我有一个问题,我想将非常特定的数据打包到特定的位中并将它们存储在浮点数中。我已经研究了将数字简单地打包成浮点数的方法,但是使用简单的数学无法满足我的需求,因为我需要使用完整的 32 位来存储非常具体的值。如果是 32 位整数,那就很简单了。

所以我想要做的是将数据编码为 32 位整数,然后将此位数据直接转换为浮点数,所有位都保持不变(除非有人对如何做有更好的建议)。哪些语言可以让我进行这样的转换?显然,不是 javascript 和 python,因为它们不支持 32 位浮点数。 C# 或 C++ 会这样做吗?

我需要在 GLSL 或 HLSL 顶点着色器中解码数据。着色器当然会接收 32 位浮点数。是否有一个运算符可以让我将浮点数直接转换为具有所有相同位的整数,而不是普通的强制转换?或者可能有其他方式直接读取位?


更新:Eric Postpischil 在下面的答案中展示了如何轻松地在 C 中进行直接转换。现在我只需要知道是否有办法在顶点着色器中直接从浮点数转换为整数或位数据。有人可以帮忙吗?

【问题讨论】:

  • @IInspectable:在 IEEE-754 32 位二进制浮点中,定义了所有位模式。每个模式要么是 +0、-0、特定的唯一非零有限数、+infinity、-infinity,要么是安静或信号 NaN。如果不计算 NaN,则不存在非法位模式。
  • 对于 HLSL 着色器模型 4 及更高版本,asuint 内在函数可用。对于 Shader Model 5 及以上版本,asuint 函数可用。
  • 您的目标硬件是什么?现代 GPU 支持跳过将这些东西打包成浮点所需的一切,并在整个管道中简单地使用整数。
  • @Jim 我在您的另一个问题中给出的答案是您如何获得 24 位。除此之外,它不会工作,对不起。
  • @Jim 您的问题被标记为 [glsl] 并且您在对另一个答案的评论中明确要求使用 GLSL 着色器,所以我假设您正在寻找 OpenGL 解决方案。重读这个问题,我还发现了 HLSL 并提供了 DirectX 文档的链接。很少有人要求使用 DirectX 或 OpenGL 的解决方案。

标签: c# c++ encoding floating-point glsl


【解决方案1】:

您可以在 C 中使用:

#include <stdint.h>

float IntegerToFloat(uint32_t u)
{
    return (union { uint32_t u; float f; }) {u} .f;
}

uint32_t FloatToInteger(float f)
{
    return (union { float f; uint32_t u; }) {f} .u;
}

当然,这要求在 C 实现中 float 是 32 位,并且 uint32_t 是受支持的类型(但如果不是,您可以使用另一个 32 位整数类型,可能是 unsigned int)。一些生成的float 值可能是 NaN,在某些操作中可能不会保持不变,例如打印或显示的转换和转换回来。即使是普通的float 值通常也不会保持不变,除非它们以足够的精度显示并且 C 实现对十进制到二进制和二进制到十进制的转换使用正确的舍入。

因此,除非迫不得已,否则像这样滥用比特是个坏主意。

【讨论】:

  • 我认为 C 可能可以做到。我知道它会给出古怪的 NaN 值,我感谢您指出它需要格外小心以确保这些位不会意外更改。不过,这是我必须做的才能完成结果。这将对性能产生巨大的积极影响。现在我希望有人能给我一些 GLSL 着色器的见解,了解我是否可以从可能是 NaN 的浮点数中解压缩这些位。
猜你喜欢
  • 2012-05-25
  • 1970-01-01
  • 2013-09-12
  • 1970-01-01
  • 1970-01-01
  • 2019-01-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多