将uint8转换为范围0-1的浮点数的最有效方法

时间:2016-01-24 17:13:22

标签: c++ floating-point

将uint8值转换为规范化浮点数非常简单:

uint8 i = 0xAF;
float f = float(i)/float(0xFF);

但这感觉比它应该更贵......

有没有办法让这种转换效率更高?我主要是出于好奇,但也因为我的3D程序进行了很多次转换。

可读性并不重要,uint8将始​​终涵盖整个范围

0 == 0.f255 == 1.f

2 个答案:

答案 0 :(得分:2)

如果您关闭编译器严格的别名规则,下面是一些可以在常用平台上执行您喜欢的操作:

float tofloat(uint8_t x) {
  uint32_t foo = 0x3f800000 + x * 0x8080;
  return (float &)foo + 256 - 257;
}

float tofloat(uint8_t x) {
  uint32_t foo = 0x3f800000 + x * 0x8080 + (x+1) / 2;
  return (float &)foo - 1;
}

答案 1 :(得分:1)

以下是我看到的操作:

在编译时:

  • 将0xFF转换为浮点常量。

在运行时:

  1. i转换为浮点并存储在临时变量中(或 寄存器)。
  2. i的浮点值除以浮点常数
  3. 将除法结果分配给浮点变量 f
  4. 瓶颈:

    瓶颈在于分裂。分工需要很长时间,一段时间(无论如何实施)。

    下一个主要瓶颈可能是将整数转换为浮点数。某些处理器可能有单个指令来执行此操作;否则将执行软件功能(通常比分区更快)。

    优化:

    1. 摆脱分裂。使用其他方法,如移位或 表查找。
    2. 最小化浮点转换。只在必要时转换, 通常在输入和输出。保持不变或保持浮动状态 点。
    3. 说明:

      • 硬编码常量很快 - 编译器存储在内存和 执行从内存中获取。编译器不需要计算。
      • 常量表达式更快,但编译速度变慢 (可能是微不足道的)。编译器执行计算和 将结果放在可执行文件中。
      • 乘法通常比分裂更快。
      • 积分数学通常比浮点更快,因为浮动 在计算之前,需要将点格式分开 重组后的话(即使在硬件中,也有更多的工作 简单的积分运算)。