将浮点范围转换/量化为整数范围

发布于 2024-07-14 04:42:21 字数 818 浏览 6 评论 0原文

假设我有一个 [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 语言人员:只需假设 floatint 转换会截断浮点数。

编辑:因为我们在这里遇到了一些困惑:我需要一个映射,将最小的输入浮点数 (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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

柒七 2024-07-21 04:42:21

a * 256f 加上一个将 256 减少到 255 的检查怎么样? 所以类似:(

return (unsigned char) (min(255, (int) (a * 256f)));

对于你的平台上合适的 min 函数 - 我不记得它的 C 函数。)

基本上你想将范围划分为 256 个相等的部分,这就是应该做的。 1.0 变为 256 并需要向下舍入的边缘情况只是因为域在两端都包含在内。

How about a * 256f with a check to reduce 256 to 255? So something like:

return (unsigned char) (min(255, (int) (a * 256f)));

(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.

故事与诗 2024-07-21 04:42:21

我认为您正在寻找的是这样的:

unsigned char QuantizeFloat (float a)
{
  return (unsigned char) (a * 256.0f);
}

这会将 [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:

unsigned char QuantizeFloat (float a)
{
  return (unsigned char) (a * 256.0f);
}

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文