c - 将一个数字范围映射到另一个

标签 c math arduino

数学从来不是我在学校的强项:(

int input_start = 0;    // The lowest number of the range input.
int input_end = 254;    // The largest number of the range input.
int output_start = 500; // The lowest number of the range output.
int output_end = 5500;  // The largest number of the range output.

int input = 127; // Input value.
int output = 0;

如何将输入值转换为该范围对应的输出值?

例如,输入值“0”等于输出值“500”,输入值“254”等于输出值“5500”。如果输入值为 50 或 101,我不知道如何计算输出值。

我敢肯定这很简单,我现在想不起来:)

编辑:我只需要整数,不需要分数或任何东西。

最佳答案

让我们忘记数学并尝试直观地解决这个问题。

首先,如果我们想将范围 [0, x] 中的输入数字映射到输出范围 [0, y],我们只需要适本地缩放。 0 变为 0,x 变为 y,数字 t 将变为 (y/x)*t.

那么,让我们将您的问题简化为上述更简单的问题。

[input_start, input_end] 的输入范围有 input_end - input_start + 1 个数字。所以它等效于 [0, r] 的范围,其中 r = input_end - input_start

同样,输出范围等价于[0, R],其中R = output_end - output_start

input 的输入等同于x = input - input_start。从第一段开始,这将转换为 y = (R/r)*x。然后,我们可以通过添加 output_starty 值转换回原始输出范围:output = output_start + y

这给了我们:

output = output_start + ((output_end - output_start) / (input_end - input_start)) * (input - input_start)

或者,换一种方式:

/* Note, "slope" below is a constant for given numbers, so if you are calculating
   a lot of output values, it makes sense to calculate it once.  It also makes
   understanding the code easier */
slope = (output_end - output_start) / (input_end - input_start)
output = output_start + slope * (input - input_start)

现在,这是 C,C 中的除法会截断,您应该尝试通过计算 float 来获得更准确的答案:

double slope = 1.0 * (output_end - output_start) / (input_end - input_start)
output = output_start + slope * (input - input_start)

如果想要更加正确,您可以在最后一步进行舍入而不是截断。您可以通过编写一个简单的 round 函数来做到这一点:

#include <math.h>
double round(double d)
{
    return floor(d + 0.5);
}

然后:

output = output_start + round(slope * (input - input_start))

关于c - 将一个数字范围映射到另一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5731863/

相关文章:

c - 在 C 中将文件 Strtok 放入数组中

我可以在 C 中创建一个 Char 指针数组吗?

java - atan(location1 - location2) 返回错误值

c++ - Arduino 串行监视器上的垃圾。如何解决?

arduino - 使用 SD 卡和 arduino 的单位模式

arduino - ESP8266/Arduino : Why is it necessary to add the ICACHE_RAM_ATTR macro to ISRs and functions called from there?

创建一个函数,如果 x < 0,则返回 1,否则仅使用按位运算返回 0

c - printf 不产生输入值

algorithm - 如何计算非二次幂字母表的 de Bruijn 序列?

algorithm - 如何预测数据质量?