首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有限资源C中线性输入曲线向对数型输出曲线的数学转换

有限资源C中线性输入曲线向对数型输出曲线的数学转换
EN

Stack Overflow用户
提问于 2017-05-31 10:04:04
回答 1查看 1.2K关注 0票数 1

我需要作出数学转换的输入值(线性曲线)到输出值(“对数或指数”曲线)在单片机上有限的资源(内存,时钟速度)。

但是这个问题是比较一般的C程序设计问题。

比如说,我们有两个变量:uint8_t inputuint8_t output。输入值为0-255。输出值也应该是0-255,但与输入不成线性关系。

例如(输入==>输出):

代码语言:javascript
复制
    0   ==> 0
    1   ==> 1
    10  ==> 1
    100 ==> 10
    200 ==> 75
    250 ==> 225
    255 ==> 255

比方说,我可以做数学转换,比如“2^(输入/32)-1”,我可以实现一些接近我所需要的东西。我试过:

output = (pow(2, (input/32)))-1

但是,根据uint8_t类型变量的局限性,我将得到2: 1,2,4的输出。最多128次(减1次),它们之间没有平稳过渡:

代码语言:javascript
复制
    0   ==> 0
    1   ==> 0
    10  ==> 0
    100 ==> 7
    200 ==> 63
    250 ==> 127
    255 ==> 127

另外,由于单片机资源有限,我不喜欢使用pow()。我可以通过在内存中使用表实现所需的结果,但是(再次)它将花费256字节的ROM,什么是不可接受的。我也可以用更小的桌子做个近似,但是..。

在低资源单片机的uint8-uint32算法中,可能还有其他的数学方法来实现这一结果吗?

编辑:“正确的”公式和数字不存在。输出数字可能会有所不同。在"input=0“==> "output=0","input=255”==> "output=255“。需求:最小且编译速度最快的代码。预期结果应该接近此图(在uint8_t中):

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-05-31 17:49:31

比方说,我可以做数学转换,比如“2^(输入/32)-1”,我可以实现一些接近我所需要的东西。

通过使用余数进行线性插值,您可以得到2^(input/32)的近似。假设input是整数,则可以使用简单的8位计算计算(1 + (input%32)/32.0) * pow(2, input/32)的等效值:

代码语言:javascript
复制
uint8_t f(uint8_t input) {
    uint8_t t = (input & 31) + 32;
    uint8_t u = input >> 5;
    return u < 5 ? t >> (5 - u) : t << (u - 5);
}

这将给出两次幂之间的线性插值,如下所示:

更新(数学背景)

我们希望近似函数f(input) = pow(2.0, input/32.0),它只需要整数运算的浮点运算。显而易见的方法是将范围0-255拆分为大小为32的子范围,并在0, 32, 64, 96, 128, 160, 192上使用只能使用整数计算的值,然后对之间的值执行简单的线性插值。现在假设我们要近似一些input的函数值,例如32*u <= input < 32*(u+1),其中u是一个整数。我们知道结尾处的值:f(32*u) = 2^uf(32*(u+1)) = 2^(u+1)。利用线性插值,我们得到了以下近似:

代码语言:javascript
复制
f_approx(input) = [f(32*(u+1))*(input - 32*u) + f(32*u)*(32*(u+1) - input)]/32

现在让我们简化一下:

代码语言:javascript
复制
f_approx(input) = [2^(u+1)*(input - 32*u) + 2^u*(32 - (input - 32*u))]/32
f_approx(input) = 2^u*[2*(input - 32*u) + 32 - (input - 32*u)]/32
f_approx(input) = 2^u*[(input - 32*u) + 32]/2^5
f_approx(input) = [(input - 32*u) + 32]*2^(u-5)

现在,如果我们注意到322的一个幂,我们可以看到,与input % 32相同的(input - 32*u)也可以计算为input & 31。因此

代码语言:javascript
复制
f_approx(input) = t*2^(u-5)

return中,三元if只是处理u-5的符号,用移位来计算2的幂。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44281734

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档