【发布时间】:2019-08-20 08:44:54
【问题描述】:
我有一个uint32_t 类型的整数,我想将它除以uint32_t 的最大值并获得float 的结果(范围为0..1)。
当然,我可以做到以下几点:
float result = static_cast<float>(static_cast<double>(value) / static_cast<double>(std::numeric_limits<uint32_t>::max()))
然而,这需要大量的转换,而且分割本身可能很昂贵。
有没有办法更快地实现上述操作,而不需要除法和多余的类型转换?或者也许我不应该担心,因为现代编译器已经能够生成高效的代码?
编辑:除以MAX+1,有效地给我一个[0..1) 范围内的浮点数也可以。
更多上下文:
我在对时间要求严格的循环中使用上述转换,uint32_t 由相对较快的随机数生成器(例如 pcg)生成。我预计上述转换的转换/除法可能会对我的代码性能产生一些明显的负面影响,尽管不是压倒性的。
【问题讨论】:
-
无论如何,您是否必须除以
maxint而不是maxint + 1?如果maxint+1有效,则可能可以做一些魔术,因为它是由2^31相除的,这实际上是数字的指数部分的减法。 -
在循环过程中是否需要将数字转换为浮点数?
value不是代表value / std::numeric_limits<std::uint32_t>::max()的分子吗? -
另请注意,在许多架构(尤其是 Intel x86 和 x64)上,存储
float值比存储double值慢 - 无论如何,算术运算通常在double中完成。所以也许完全避免float? -
@dyukha 是的,使用
maxint+1就足够了。 -
@CygnusX1 请注意,使用
float(value) / float(1ul << 32ul)很可能会为您提供[0, 1]的范围,而不是[0, 1)(这是实际发行版通常需要的)。uniform_real_distribution为您提供[0, 1)(除非您使用旧的错误版本的g++或 clang++`)。
标签: c++