当前位置:天才代写 > tutorial > C语言/C++ 教程 > Vdsp(bf561)中的浮点运算(14):fract16除法

Vdsp(bf561)中的浮点运算(14):fract16除法

2017-11-05 08:00 星期日 所属: C语言/C++ 教程 浏览:452

副标题#e#

本来指望可以或许有div_fr1x16之类的函数来实现fract16的除法,可是很遗憾vdsp居然不直接提供这样的函数,让人颇为难过,预计是因为其CPU不直接提供fract除法的缘故。不外vdsp文档内里提供了一个做除法的例子:

fract16 saturating_fract_divide(fract16 nom, fract16 denom)
{
 int partialres = (int)nom;
 int divisor = (int)denom;
 fract16 rtn;
 int i;
 int aq;   /* initial value irrelevant */

 if (partialres == 0) {
  /* 0/anything gives 0 */
  rtn = 0;
 } else if (partialres >= divisor) {
          /* fract16 values have the range -1.0 <= x < +1.0,  */
         /* so our result cannot be as high as 1.0.  */
         /* Therefore, for x/y, if x is larger than y, */
         /* saturate the result to positive maximum.   */
         rtn = 0x7fff;
 } else {
  /* nom is a 16-bit fractional value, so move */
  /* the 16 bits to the top of partialres. */
  /* (promote fract16 to fract32) */
  partialres <<= 16;

  /* initialize sign bit and AQ, via divs(). */
  partialres = divs(partialres, divisor, &aq);

  /* Update each of the value bits of the partial result */
  /* and reset AQ via divq().  */
  for (i=0; i<15; i++) {
   partialres = divq(partialres, divisor, &aq);
  }

  rtn = (fract16) partialres;
 }

 return rtn;

}

这个计较进程在不打开优化的环境下将需要500个cycle,在打开优化之后将只需要42个cycle!对较量于将fract16转换为float举办计较照旧要快得多。


#p#副标题#e#

可是很显然,例子中给出的这个函数并没有思量到标记位,好比计较0.2 / -0.4这样的式子时它将直接返回1,因而我们需要对它举办适当的修改。

fract16 saturating_fract_divide(fract16 nom, fract16 denom)
{
 int partialres;
 int divisor;
 fract16 rtn;
 int i;
 int aq;   /* initial value irrelevant */
 int sign = (nom ^ denom) & 0x8000;
 partialres = abs_fr1x16(nom);
 divisor = abs_fr1x16(denom);

 if (partialres == 0) {
  /* 0/anything gives 0 */
  rtn = 0;
 } else if (partialres >= divisor) {
    /* fract16 values have the range -1.0 <= x < +1.0,  */
    /* so our result cannot be as high as 1.0.  */
    /* Therefore, for x/y, if x is larger than y, */
    /* saturate the result to positive maximum.   */
    rtn = 0x7fff;
 } else {
     /* nom is a 16-bit fractional value, so move */
     /* the 16 bits to the top of partialres.     */
     /* (promote fract16 to fract32) */
     partialres <<= 16;

     /* initialize sign bit and AQ, via divs(). */
     partialres = divs(partialres, divisor, &aq);

     /* Update each of the value bits of the partial result */
     /* and reset AQ via divq().  */
     for (i=0; i<15; i++) {
      partialres = divq(partialres, divisor, &aq);
     }

     rtn = (fract16) (partialres);
     if(sign)
      rtn = negate_fr1x16(rtn);
 }

 return rtn;

}

优化之前需要522个cycle,优化之后需要50个cycle。

 

    关键字:

天才代写-代写联系方式