⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftcalc.c

📁 Qt/Embedded是一个多平台的C++图形用户界面应用程序框架
💻 C
📖 第 1 页 / 共 2 页
字号:
  /*                                                                       */  /* <Description>                                                         */  /*    A very simple function used to perform the computation             */  /*    `(a*b)/0x10000' with maximum accuracy.  Most of the time, this is  */  /*    used to multiply a given value by a 16.16 fixed float factor.      */  /*                                                                       */  /* <Input>                                                               */  /*    a :: The first multiplier.                                         */  /*    b :: The second multiplier.  Use a 16.16 factor here whenever      */  /*         possible (see note below).                                    */  /*                                                                       */  /* <Return>                                                              */  /*    The result of `(a*b)/0x10000'.                                     */  /*                                                                       */  /* <Note>                                                                */  /*    The optimization for FT_MulFix() is different.  We could simply be */  /*    happy by applying the same principles as with FT_MulDiv(), because */  /*                                                                       */  /*      c = 0x10000 < 176096                                             */  /*                                                                       */  /*    However, in most cases, we have a `b' with a value around 0x10000  */  /*    which is greater than 46340.                                       */  /*                                                                       */  /*    According to some testing, most cases have `a' < 2048, so a good   */  /*    idea is to use bounds like 2048 and 1048576 (=floor((2^31-1)/2048) */  /*    for `a' and `b', respectively.                                     */  /*                                                                       */  EXPORT_FUNC  FT_Long  FT_MulFix( FT_Long  a,                      FT_Long  b )  {    FT_Long   s;    if ( a == 0 || b == 0x10000L )      return a;    s  = a; a = ABS(a);    s ^= b; b = ABS(b);    if ( a <= 2048 && b <= 1048576L )    {      a = ( a*b + 0x8000 ) >> 16;    }    else    {      FT_Long  al = a & 0xFFFF;      a = (a >> 16)*b + al*(b >> 16) + ( al*(b & 0xFFFF) >> 16 );    }    return ( s < 0 ? -a : a );  }  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    FT_DivFix                                                          */  /*                                                                       */  /* <Description>                                                         */  /*    A very simple function used to perform the computation             */  /*    `(a*0x10000)/b' with maximum accuracy.  Most of the time, this is  */  /*    used to divide  a given value by a 16.16 fixed float factor.       */  /*                                                                       */  /* <Input>                                                               */  /*    a :: The first multiplier.                                         */  /*    b :: The second multiplier.  Use a 16.16 factor here whenever      */  /*         possible (see note below).                                    */  /*                                                                       */  /* <Return>                                                              */  /*    The result of `(a*0x10000)/b'.                                     */  /*                                                                       */  /* <Note>                                                                */  /*    The optimization for FT_DivFix() is simple: If (a << 16) fits in   */  /*    32 bits, then the division is computed directly.  Otherwise, we    */  /*    use a specialized version of the old FT_MulDiv64().                */  /*                                                                       */  EXPORT_FUNC  FT_Long  FT_DivFix( FT_Long  a,                      FT_Long  b )  {    FT_Int32   s;    FT_Word32  q;    s  = a; a = ABS(a);    s ^= b; b = ABS(b);    if ( b == 0 )      /* check for divide by 0 */      q = 0x7FFFFFFF;    else if ( (a >> 16) == 0 )    {      /* compute result directly */      q = (FT_Word32)(a << 16) / (FT_Word32)b;    }    else    {      /* we need more bits, we'll have to do it by hand */      FT_Word32  c;      q  = ( a / b ) << 16;      c  = a % b;      /* we must compute C*0x10000/B; we simply shift C and B so */      /* C becomes smaller than 16 bits                          */      while ( c >> 16 )      {        c >>= 1;        b <<= 1;      }      q += ( c << 16 ) / b;    }    return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );  }  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    FT_Add64                                                           */  /*                                                                       */  /* <Description>                                                         */  /*    Add two Int64 values.                                              */  /*                                                                       */  /* <Input>                                                               */  /*    x :: A pointer to the first value to be added.                     */  /*    y :: A pointer to the second value to be added.                    */  /*                                                                       */  /* <Output>                                                              */  /*    z :: A pointer to the result of `x + y'.                           */  /*                                                                       */  /* <Note>                                                                */  /*    Will be wrapped by the ADD_64() macro.                             */  /*                                                                       */  BASE_FUNC  void  FT_Add64( FT_Int64*  x,                  FT_Int64*  y,                  FT_Int64*  z )  {    register FT_Word32  lo, hi;    lo = x->lo + y->lo;    hi = x->hi + y->hi + ( lo < x->lo );    z->lo = lo;    z->hi = hi;  }  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    FT_MulTo64                                                         */  /*                                                                       */  /* <Description>                                                         */  /*    Multiplies two Int32 integers.  Returns a Int64 integer.           */  /*                                                                       */  /* <Input>                                                               */  /*    x :: The first multiplier.                                         */  /*    y :: The second multiplier.                                        */  /*                                                                       */  /* <Output>                                                              */  /*    z :: A pointer to the result of `x * y'.                           */  /*                                                                       */  /* <Note>                                                                */  /*    Will be wrapped by the MUL_64() macro.                             */  /*                                                                       */  BASE_FUNC  void  FT_MulTo64( FT_Int32   x,                    FT_Int32   y,                    FT_Int64*  z )  {    FT_Int32   s;    s  = x; x = ABS( x );    s ^= y; y = ABS( y );    {      FT_Word32  lo1, hi1, lo2, hi2, lo, hi, i1, i2;      lo1 = x & 0x0000FFFF;  hi1 = x >> 16;      lo2 = y & 0x0000FFFF;  hi2 = y >> 16;      lo = lo1 * lo2;      i1 = lo1 * hi2;      i2 = lo2 * hi1;      hi = hi1 * hi2;      /* Check carry overflow of i1 + i2 */      i1 += i2;      if ( i1 < i2 )        hi += 1L << 16;      hi += i1 >> 16;      i1  = i1 << 16;      /* Check carry overflow of i1 + lo */      lo += i1;      hi += (lo < i1);      z->lo = lo;      z->hi = hi;    }    if ( s < 0 )    {      z->lo = (FT_Word32)-(FT_Int32)z->lo;      z->hi = ~z->hi + !(z->lo);    }  }  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    FT_Div64by32                                                       */  /*                                                                       */  /* <Description>                                                         */  /*    Divides an Int64 value by an Int32 value.  Returns an Int32        */  /*    integer.                                                           */  /*                                                                       */  /* <Input>                                                               */  /*    x :: A pointer to the dividend.                                    */  /*    y :: The divisor.                                                  */  /*                                                                       */  /* <Return>                                                              */  /*    The result of `x / y'.                                             */  /*                                                                       */  /* <Note>                                                                */  /*    Will be wrapped by the DIV_64() macro.                             */  /*                                                                       */  BASE_FUNC  FT_Int32  FT_Div64by32( FT_Int64*  x,                          FT_Int32   y )  {    FT_Int32   s;    FT_Word32  q, r, i, lo;    s  = x->hi;    if ( s < 0 )    {      x->lo = (FT_Word32)-(FT_Int32)x->lo;      x->hi = ~x->hi + !(x->lo);    }    s ^= y;  y = ABS( y );    /* Shortcut */    if ( x->hi == 0 )    {      q = x->lo / y;      return ( s < 0 ) ? -(FT_Int32)q : (FT_Int32)q;    }    r  = x->hi;    lo = x->lo;    if ( r >= (FT_Word32)y ) /* we know y is to be treated as unsigned here */      return ( s < 0 ) ? 0x80000001L : 0x7FFFFFFFL;                            /* Return Max/Min Int32 if divide overflow. */                            /* This includes division by zero!          */    q = 0;    for ( i = 0; i < 32; i++ )    {      r <<= 1;      q <<= 1;      r  |= lo >> 31;      if ( r >= (FT_Word32)y )      {        r -= y;        q |= 1;      }      lo <<= 1;    }    return ( s < 0 ) ? -(FT_Int32)q : (FT_Int32)q;  }#endif /* LONG64 *//* END */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -