首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有浮动指数的二次快速幂[C]

具有浮动指数的二次快速幂[C]
EN

Stack Overflow用户
提问于 2016-07-31 01:53:36
回答 1查看 1.2K关注 0票数 2

本质上,我试图使用在下面的代码中计算出来的值,但是当我将值存储在所有具有自己速率的对象中时,只会添加足够多的字节,从而导致缓存丢失。显然,使用查找表无助于解决问题。

所以我正在寻找一种方法,比标准的幂函数更快地得到这些值,由于可能的输入是非常有限的,我是否可以使用任何技巧?

代码语言:javascript
复制
static inline
double __attribute(( pure )) get_decay_rate(uint8_t rate)
{
     if(rate >= 128)
     {
          return 65535.0/65536.0;
     }

     double k = pow(2, rate/8.0);
     return (k - 1.0) / k;
}


/* pseudocode:
     double k = (int) pow(2, k/8.0);
     k = (k - 1) / k;
     return log(65535/65536)/log(k);
*/
static inline
uint16_t __attribute(( pure )) get_decay_modulus(uint8_t rate)
{
     if(rate <= 128)
     {
          return 1;
     }
//turns out to be the same as the above pseudocode, for some reason. 
     return pow(2, (rate - 128) / 8.0);
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-07-31 04:16:46

走这条线:

代码语言:javascript
复制
double k = pow(2, rate/8.0);

基本上,你在这里所做的是将2提高到一个不动点数的幂。

您可以利用以下事实: pow(a,b+c) = pow(a,b) * pow(a,c),非整数数=整数部分+小数部分。所以你用不动点数的积分部分来计算pow,然后用分数部分的pow乘以它。

将8个小数指数存储在查找表中:

代码语言:javascript
复制
double fractionalPowersOf2[8];

for(int i = 0; i < 8; i++)
    fractionalPowersOf2[i] = pow(2.0, i / 8.0);

然后你可以这样计算:

代码语言:javascript
复制
double k = (double)(1 << (rate >> 3)) * fractionalPowersOf2[rate & 7];

这掩盖了小数部分,并将其用于表查找,然后使用位移位将2乘以整数的幂。如果转换为double太慢,您也可以使用查找表。

您还可以使用一些奇特的位魔术类型方法,通过转换指针等方法,将值作为双值的指数使用,但这是不可移植的。

编辑:正如user3386109在注释中指出的那样,如果打开优化,编译器可能会为您优化将2提升到整数值的能力,因此这段代码可能会更快:

代码语言:javascript
复制
 double k = pow(2,rate>>3) * table[rate&7];
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38680065

复制
相关文章

相似问题

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