将浮点范围转换/量化为整数范围
假设我有一个 [0, 1] 范围内的浮点数,我想对其进行量化并将其存储在无符号字节中。 听起来很简单,但实际上它非常复杂:
明显的解决方案如下所示:
unsigned char QuantizeFloat(float a)
{
return (unsigned char)(a * 255.0f);
}
到目前为止,我得到了从 0 到 255 的所有数字,但整数的分布不均匀。 如果 a 恰好为 1.0f
,则该函数仅返回 255
。 这不是一个好的解决方案。
如果我进行适当的舍入,我只需转移问题:
unsigned char QuantizeFloat(float a)
{
return (unsigned char)(a * 255.0f + 0.5f);
}
这里的结果 0
仅覆盖浮点范围的一半,而不是任何其他数字。
如何进行浮点范围均匀分布的量化? 理想情况下,如果我量化均匀分布的随机浮点数,我希望获得均匀分布的整数。
有任何想法吗?
顺便说一句:我的代码也是用 C 语言编写的,问题与语言无关。 对于非 C 语言人员:只需假设 float
到 int
转换会截断浮点数。
编辑:因为我们在这里遇到了一些困惑:我需要一个映射,将最小的输入浮点数 (0) 映射到最小的无符号字符,并将范围内的最高浮点数 (1.0f) 映射到最高的无符号字符字节(255)。
Say I have a float in the range of [0, 1] and I want to quantize and store it in an unsigned byte. Sounds like a no-brainer, but in fact it's quite complicated:
The obvious solution looks like this:
unsigned char QuantizeFloat(float a)
{
return (unsigned char)(a * 255.0f);
}
This works in so far that I get all numbers from 0 to 255, but the distribution of the integers is not even. The function only returns 255
if a is exactly 1.0f
. Not a good solution.
If I do proper rounding I just shift the problem:
unsigned char QuantizeFloat(float a)
{
return (unsigned char)(a * 255.0f + 0.5f);
}
Here the the result 0
only covers half of the float-range than any other number.
How do I do a quantization with equal distribution of the floating point range? Ideally I would like to get a equal distribution of integers if I quantize equally distributed random floats.
Any ideas?
Btw: Also my code is in C the problem is language-agnostic. For the non-C people: Just assume that float
to int
conversion truncates the float.
EDIT: Since we had some confusion here: I need a mapping that maps the smallest input float (0) to the smallest unsigned char, and the highest float of my range (1.0f) to the highest unsigned byte (255).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
a * 256f
加上一个将 256 减少到 255 的检查怎么样? 所以类似:(对于你的平台上合适的 min 函数 - 我不记得它的 C 函数。)
基本上你想将范围划分为 256 个相等的部分,这就是应该做的。 1.0 变为 256 并需要向下舍入的边缘情况只是因为域在两端都包含在内。
How about
a * 256f
with a check to reduce 256 to 255? So something like:(For a suitable min function on your platform - I can't remember the C function for it.)
Basically you want to divide the range into 256 equal portions, which is what that should do. The edge case for 1.0 going to 256 and requiring rounding down is just because the domain is inclusive at both ends.
我认为您正在寻找的是这样的:
这会将 [0, 1] 中的统一浮点值映射到 [0, 255] 中的统一字节值。 对于 0..255 中的 i,[i/256, (i+1)/256[(即排除 (i+1)/256)中的所有值都映射到 i。 可能不受欢迎的是 1.0f 映射到 256.0f,后者环绕为 0。
I think what you are looking for is this:
This will map uniform float values in [0, 1] to uniform byte values in [0, 255]. All values in [i/256, (i+1)/256[ (that is excluding (i+1)/256), for i in 0..255, are mapped to i. What might be undesirable is that 1.0f is mapped to 256.0f which wraps around to 0.