如何将范围<0;99>的数字映射到范围<-1.0;1.0>?

16 投票
6 回答
36783 浏览
提问于 2025-04-16 06:54

我有一个函数,它总是返回一个在0到99之间的整数(也就是0, 1, ... 99)。

那么,怎样才能把这些数字正确地映射到-1.0到1.0的范围呢?

比如说,0应该对应-1.0,而99应该对应1.0。那么,如何计算中间的数字呢?

6 个回答

13

要把一个值 x 从这个范围:

[a..b]

映射到这个范围:

[a'..b']

你可以用这个公式:

x' = (x / 99) * 2 - 1

这种映射的工作原理如下:

x' = ((x - a) / (b - a)) * (b' - a') + a'

一步一步来:

  1. 首先,你要计算 xa..b 这个范围内的位置比例:

    (x - a) / (b - a)
    

    这个值会在0到1之间。

  2. 然后,你用这个值来计算在 a'..b' 这个范围内应该处于什么位置:

    ratio * (b' - a') + a'
    

在你的具体情况下:

x' = ((x - 0) / (99 - 0)) * (1.0 - (-1.0)) + (-1.0)

或者用简化的形式:

x' = (x / 99) * 2 - 1

注意:如果你在一个编程语言中,整数除以另一个整数会得到整数结果,你应该把这些值转换成浮点数,以避免精度损失的问题:

x' = (x / 99.0) * 2.0 - 1.0
26

别自己手动去做缩放,这样要花很多时间去琢磨数学公式,搞清楚到底想要什么。用一个辅助函数就好了。

def scale(val, src, dst):
    """
    Scale the given value from the scale of src to the scale of dst.
    """
    return ((val - src[0]) / (src[1]-src[0])) * (dst[1]-dst[0]) + dst[0]

print scale(0, (0.0, 99.0), (-1.0, +1.0))
print scale(1, (0.0, 99.0), (-1.0, +1.0))
print scale(99, (0.0, 99.0), (-1.0, +1.0))

我发现这个函数在任何编程语言中都非常有用;你一眼就能看出scale()这个函数在干什么。

27

使用线性映射:

y = ((x / 99.0) * 2) - 1

它是怎么工作的:

  • 先除以99:这样可以把范围从[0, 99]变成[0, 1]。
  • 再乘以2:这一步把范围扩大到[0, 2]。
  • 最后减去1:这一步是平移,把范围调整到[-1, 1]。

当然,如果你想的话,可以把这些步骤 ((x / 99.0) * 2) 合并成一个除法。我只是为了让大家更清楚,所以把它们分开了。

撰写回答