blogernice

导航

math.h()函数源码

hypot()函数源码

/*

   hypot函数对于给定的直角三角形的两个直角边,

   求其斜边的长度。

*/

 

//一般的常规算法:

 

double my_hypot01(double x, double y)

{

   double hypotenuse;

   x = fabs(x);

   y = fabs(y);

   if (x < y)

    {

      double temp = x;

      x = y;

      y = temp;

   }

   if (x == 0.)

      return 0.;

   else

    {

      hypotenuse = y/x;

      return x*sqrt(1.+hypotenuse*hypotenuse);

   }

}

#define __SQRT_DBL_MAX 1.3e+154

#define __SQRT_DBL_MIN 2.3e-162

 

double my_hypot02(double x, double y)

{

   double ratio;

   double r, t, s, p, q;

  

   x = fabs(x), y = fabs(y);

  

 

   if (x < y)

   {

      double temp = x;

      x = y;

      y = temp;

   }//保持x 是两个直角边中较长的边,y是较短的边。

 

   if (y == 0.)

      return x;

   /*

      主要考虑的是当x很大而y很小,那么它们的平方和将会造成

      丢失小数的现象。首先要判断y是否是太小,x是不是太大。

      如果出现这种情况则用,第一个公式来处理。其他的则用

      这样可以让求出的斜边更加精确一些。

   */

   if ((ratio = y / x) > __SQRT_DBL_MIN && x < __SQRT_DBL_MAX)

      return x * sqrt(1. + ratio*ratio);

   else

   {//使用3次迭代是增加精确度。

      r = ratio*ratio, p = x, q = y;

      do

      {

        t = 4.+ r;

        if (t == 4.)

           break;

        s = r / t;

        p += 2. * s * p;

        q *= s;

        r = (q / p) * (q / p);

      } while (1);

      return p;

   }

}

struct complex

{

   double x;

   double y;

}

double cabs(struct complex x)

{

   return hypot(z.x,z.y);

}//hypot 函数的封装(这里不再举调用的例子了。)

 

# define DBL_MAX 1.79769313486231e+308

# define DBL_MIN 2.22507385850721e-308

int main(void)

   printf("hypot(3, 4)                    =%25.17e/n",hypot(3., 4.));

   printf("hypot(3*10^150,4*10^150)       =%25.17g/n",hypot(3.e+150, 4.e+150));

   printf("hypot(3*10^306,4*10^306)       =%25.17g/n",hypot(3.e+306, 4.e+306));

   printf("hypot(3*10^-320,4*10^-320)     =%25.17g/n",hypot(3.e-320, 4.e-320));

   printf("hypot(0.7*DBL_MAX,0.7*DBL_MAX) =%25.17g/n",hypot(0.7*DBL_MAX,0.7*DBL_MAX));

   printf("hypot(DBL_MAX, 1.0)            =%25.17g/n",hypot(DBL_MAX, 1.0));

   printf("hypot(1.0, DBL_MAX)            =%25.17g/n",hypot(1.0, DBL_MAX));

   printf("hypot(0.0, DBL_MAX)            =%25.17g/n",hypot(0.0, DBL_MAX));

   printf("/n************************************************************/n");

   printf("hypot(3, 4)                    =%25.17e/n",my_hypot01(3., 4.));

   printf("hypot(3*10^150,4*10^150)       =%25.17g/n",my_hypot01(3.e+150, 4.e+150));

   printf("hypot(3*10^306,4*10^306)       =%25.17g/n",my_hypot01(3.e+306, 4.e+306));

   printf("hypot(3*10^-320,4*10^-320)     =%25.17g/n",my_hypot01(3.e-320, 4.e-320));

   printf("hypot(0.7*DBL_MAX,0.7*DBL_MAX) =%25.17g/n",my_hypot01(0.7*DBL_MAX,0.7*DBL_MAX));

   printf("hypot(DBL_MAX, 1.0)            =%25.17g/n",my_hypot01(DBL_MAX, 1.0));

   printf("hypot(1.0, DBL_MAX)            =%25.17g/n",my_hypot01(1.0, DBL_MAX));

   printf("hypot(0.0, DBL_MAX)            =%25.17g/n",my_hypot01(0.0, DBL_MAX));

 

 printf("/n************************************************************/n");

   printf("hypot(3, 4)                    =%25.17e/n",my_hypot02(3., 4.));

   printf("hypot(3*10^150,4*10^150)       =%25.17g/n",my_hypot02(3.e+150, 4.e+150));

   printf("hypot(3*10^306,4*10^306)       =%25.17g/n",my_hypot02(3.e+306, 4.e+306));

   printf("hypot(3*10^-320,4*10^-320)     =%25.17g/n",my_hypot02(3.e-320, 4.e-320));

   printf("hypot(0.7*DBL_MAX,0.7*DBL_MAX) =%25.17g/n",my_hypot02(0.7*DBL_MAX,0.7*DBL_MAX));

   printf("hypot(DBL_MAX, 1.0)            =%25.17g/n",my_hypot02(DBL_MAX, 1.0));

   printf("hypot(1.0, DBL_MAX)            =%25.17g/n",my_hypot02(1.0, DBL_MAX));

   printf("hypot(0.0, DBL_MAX)            =%25.17g/n",my_hypot02(0.0, DBL_MAX));

   system("pause");

   return 0;

}

 

modf()函数源码

/*

   将浮点数x分解成整数部分和小数部分。

   返回小数部分,将整数部分存入* iptr所指内存中。

*/

double my_modf01(double x, double *iptr)

{

   double ret = fmod(x,1.0);

   *iptr = x - ret;

   return ret;

}//这个函数算法比较简单,也容易让人理解。

 

//下面的这个函数理解起来就有点困难了。

 

typedef struct

{

   unsigned int mantissal:32;

   unsigned int mantissah:20;

   unsigned int exponent:11;

   unsigned int sign:1;

}double_t;//这个结构体在IEEE.h定义。

double my_modf02(double x, double *y)

{

   double_t * z = (double_t *)&x;

   double_t * iptr = (double_t *)y;

 

   int j0;

   unsigned int i;

   j0 = z->exponent - 0x3ff;  /* exponent of x */ 

   if(j0<20)

   {/* integer part in high x */

      if(j0<0)

      {                  /* |x|<1 */

        *y = 0.0;

        iptr->sign = z->sign;

        return x;

      }

      else

      {

        if ( z->mantissah == 0 && z->mantissal == 0 )

        {

           *y = x;

           return 0.0;

        }

        i = (0x000fffff)>>j0;

        iptr->sign = z->sign;

        iptr->exponent = z->exponent;

        iptr->mantissah = z->mantissah&(~i);

        iptr->mantissal = 0;

        if ( x == *y )

        {

           x = 0.0;

           z->sign = iptr->sign;

           return x;

        }         

              return x - *y;       

      }

   }

   else if (j0>51)

   {             /* no fraction part */

      *y = x;

      if ( isnan(x) || isinf(x) )

        return x;

      x = 0.0;

      z->sign = iptr->sign;

      return x;

   }

   else

   {                        /* fraction part in low x */

      i = ((unsigned)(0xffffffff))>>(j0-20);

      iptr->sign = z->sign;

      iptr->exponent = z->exponent;

      iptr->mantissah = z->mantissah;

      iptr->mantissal = z->mantissal&(~i);

      if ( x == *y )

      {

        x = 0.0;

        z->sign = iptr->sign;

        return x;

      }

      return x - *y;       

   }

}

//下面是两个要用到的函数

int isnan(double d)

{

   union

   {

      unsigned long long l;

      double d;

   } u;

   u.d=d;

   return (u.l==0x7FF8000000000000ll || u.l==0x7FF0000000000000ll || u.l==0xfff8000000000000ll);

}

int isinf(double d)

{

   union

   {

      unsigned long long l;

      double d;

   } u;

   u.d=d;

   return (u.l==0x7FF0000000000000ll?1:u.l==0xFFF0000000000000ll?-1:0);

}

 

int main()

{

   double x,y;

  

   x = 12345678901.1234567;

 

   printf("%f = (%f) + (%f) /n",x,y,modf(x,&y));

   printf("%f = (%f) + (%f) /n",x,y,my_modf01(x,&y));

   printf("%f = (%f) + (%f) /n",x,y,my_modf02(x,&y));

  

   printf("/n******************************************/n");

  

   printf("%f = (%f) + (%f) /n",-x,y,modf(-x,&y));

   printf("%f = (%f) + (%f) /n",-x,y,my_modf01(-x,&y));

   printf("%f = (%f) + (%f) /n",-x,y,my_modf02(-x,&y));

  

   system("pause");

   return 0;

}

 

fmod()函数源码

/*

   计算x/y的余数。返回x-n*y,符号同y。

   n=[x/y](向离开零的方向取整)

*/

double my_fmod01(double x, double y)

{

   register double ret;

   __asm__(

      "1:     fprem/n/t"

      "fstsw   %%ax/n/t"

      "sahf/n/t"

      "jp        1b"

      : "=t" (ret)

      : "0" (x), "u" (y)

      : "ax", "cc"

   );

 

   return ret;

}

double my_fmod02(double x, double y)

{

   double temp, ret;

  

   if (y == 0.0)

      return 0.0;

   temp = floor(x/y);

   ret = x - temp * y;

   if ((x < 0.0) != (y < 0.0))

      ret = ret - y;

   return ret;

}

int main()

{

   double x,y;

  

   x = 80.8,y = 3.0;

 

   printf("fmod(%f,%f)      = %f/n",x,y,fmod(x,y));

   printf("my_fmod01(%f,%f) = %f/n",x,y,my_fmod01(x,y));

   printf("my_fmod02(%f,%f) = %f/n",x,y,my_fmod01(x,y));

  

   printf("/n******************************************/n");

  

   x = -55.968,y = 8.8;

   printf("fmod(%f,%f)      = %f/n",x,y,fmod(x,y));

   printf("my_fmod01(%f,%f) = %f/n",x,y,my_fmod01(x,y));

   printf("my_fmod02(%f,%f) = %f/n",x,y,my_fmod01(x,y));

  

   system("pause");

   return 0;

}

 

ldexp()函数源码

/*

   装载浮点数,v是尾数,e为指数。

   如:x=ldexp(1.0,6);则表示要转载的浮点数是1.0*2^6

*/

double my_ldexp01(double v, int e)

{

   double two = 2.0;

   if (e < 0)

   {

      e = -e; /*这句话和后面的if语句是用来对两位溢出码的机器*/

      if (e < 0) return 0.0;

      while (e > 0)

      {

        if (e & 1) v /= two;

        two *= two;

         e >>= 1;

      }

   }

   else if (e > 0)

   {

      while (e > 0)

      {

        if (e & 1) v *= two;

        two *= two;

        e >>= 1;

      }

   }

   return v;

}

double my_ldexp02(double v, int e)

{

   double temp1, texp, temp2;

   texp = e;

   __asm__(

      "fscale "

      : "=u" (temp2), "=t" (temp1)

      : "0" (texp), "1" (v)

   );

   return (temp1);

}

main()

{

   float x,y;

  

   y = 1.0;

   x=my_ldexp01(y,6);  // 1.0*2^6

   printf("2^6=%.2f/n",x);

   x=my_ldexp01(-y,6);  // 1.0*2^6

   printf("2^6=%.2f/n",x);

   x=my_ldexp02(y,6);  // 1.0*2^6

   printf("2^6=%.2f/n",x);

   x=my_ldexp02(-y,6);  // 1.0*2^6

   printf("2^6=%.2f/n",x);

  

 

   system("pause");

   return 0;

}

 

frexp()函数源码

/*

   把浮点数x分解成尾数和指数。x=m*2^exptr,m为规格化小数。

   返回尾数m,并将指数存入exptr中。

*/

double my_frexp01(double x, int *exptr)

{

   union

   {

      double d;

      unsigned char c[8];

   } u;

   u.d = x;

   //得到移码,并减去1022得到指数值。

   *exptr = (int)(((u.c[7] & 0x7f) << 4) | (u.c[6] >> 4)) - 1022;

   //把指数部分置为0x03FE

   u.c[7] &= 0x80;

   u.c[7] |= 0x3f;

   u.c[6] &= 0x0f;

   u.c[6] |= 0xe0;

   return u.d;

}

double my_frexp02(double x, int *eptr)

{

   union

   {

      double v;

      struct

      {

        unsigned mantissa2 : 32;

        unsigned mantissa1 : 20;

        unsigned exponent : 11;

        unsigned sign :  1;

      } s;

   } u;

   if (x)

   {

      u.v = x;

      //得到移码,并减去1022得到指数值。

      *eptr = u.s.exponent - 1022;

      //把指数部分置为0x03FE

      u.s.exponent = 1022;

      return(u.v);

   }

   else

   {

      *eptr = 0;

      return((double)0);

   }

}

main()

{

   float x,y;

   int exp;

  

   y = 64.0;

   x = my_frexp01(y,&exp);

   printf("%f=%.2f*2^%d/n",y,x,exp);

   x = my_frexp01(-y,&exp);

   printf("%f=%.2f*2^%d/n",y,x,exp);

  

   printf("/n************************/n");

  

   x = my_frexp02(y,&exp);

   printf("%f=%.2f*2^%d/n",y,x,exp);

   x = my_frexp02(-y,&exp);

   printf("%f=%.2f*2^%d/n",y,x,exp);

 

   system("pause");

   return 0;

}

 

tanh()函数源码

double my_tanh(double x)

{

   double ret,temp;

   if (x > 50)

      return 1;

   else if (x < -50)

      return -1;

   else

   {

      ret = exp(x);

      temp = 1.0 / ret;

      return ( (ret - temp) / (ret + temp));

   }

}//计算x的双曲正切值。

 

int main()

{

   double a = 0.5;

   printf("tanh(%f)    = %f/n",a,tanh(a));

   printf("my_tanh(%f) = %f/n",a,my_tanh(a));

   a = -0.5;

   printf("tanh(%f)    = %f/n",a,tanh(a));

   printf("my_tanh(%f) = %f/n",a,my_tanh(a));

  

   system("pause");

   return 0;

}

 

sinh()函数源码

double my_sinh(double x)

{

   double ret;

   if(x >= 0.0)

   {

      ret = exp(x);

      return (ret - 1.0/ret) / 2.0;

   }

   else

   {

      ret = exp(-x);

      return (1.0/ret - ret) / 2.0;

   }

}//计算x的双曲正弦值。

int main()

{

   double a = 0.5;

   printf("sinh(%f)    = %f/n",a,sinh(a));

   printf("my_sinh(%f) = %f/n",a,my_sinh(a));

   a = -0.5;

   printf("sinh(%f)    = %f/n",a,sinh(a));

   printf("my_sinh(%f) = %f/n",a,my_sinh(a));

  

   system("pause");

   return 0;

}

 

cosh()函数源码

double my_cosh(double x)

{

   double ret;

   ret = exp(fabs(x));

   return (ret + 1.0/ret) / 2.0;

}//计算x的双曲余弦值。

int main()

{

   double a = 0.5;

   printf("cosh(%f)    = %f/n",a,cosh(a));

   printf("my_cosh(%f) = %f/n",a,my_cosh(a));

   a = -0.5;

   printf("cosh(%f)    = %f/n",a,cosh(a));

   printf("my_cosh(%f) = %f/n",a,my_cosh(a));

  

   system("pause");

   return 0;

}

 

 atan()函数源码

double my_atan(double x)

{

   register double ret;

   __asm__(

      "fld1/n/t"

      "fpatan"

      : "=t" (ret)

      : "0" (x)

   );

  

   return ret;

}//求x的反正切值。

int main()

{

   double a = 0.5;

   printf("atan(%f)    = %f/n",a,atan(a));

   printf("my_atan(%f) = %f/n",a,my_atan(a));

   a = -0.5;

   printf("atan(%f)    = %f/n",a,atan(a));

   printf("my_atan(%f) = %f/n",a,my_atan(a));

 

   system("pause");

   return 0;

}

 

acos()函数源码

double atan2 (double x, double y)

{

   register double ret;

   __asm__(

      "fpatan/n/t"

      "fld %%st(0)"

      : "=t" (ret)

      : "0" (y), "u" (x)

   );

  

   return ret;

}//求x / y的反正切值。

double my_acos(double x)

{

  return atan2 (sqrt (1.0 - x * x), x);

}//求x的反余弦值。

int main()

{

   double a = 0.5;

   printf("acos(%f)    = %f/n",a,acos(a));

   printf("my_acos(%f) = %f/n",a,my_acos(a));

   a = -0.5;

   printf("acos(%f)    = %f/n",a,acos(a));

   printf("my_acos(%f) = %f/n",a,my_acos(a));

  

   system("pause");

   return 0;

}

 

asin()函数源码

double atan2 (double x, double y)

{

   register double ret;

   __asm__(

      "fpatan/n/t"

      "fld %%st(0)"

      : "=t" (ret)

      : "0" (y), "u" (x)

   );

  

   return ret;

}//求x / y的反正切值。

 

double my_asin(double x)

{

   return atan2 (x, sqrt (1.0 - x * x));

}//求x的反正弦值。

int main()

{

   double a = 0.5;

   printf("asin(%f)    = %f/n",a,asin(a));

   printf("my_asin(%f) = %f/n",a,my_asin(a));

   a = -0.5;

   printf("asin(%f)    = %f/n",a,asin(a));

   printf("my_asin(%f) = %f/n",a,my_asin(a));

 

   system("pause");

   return 0;

}

 

exp()函数源码

double my_exp(double x)

{

   register double ret, value;

   __asm__(

      "fldl2e;"   

      "fmul %%st(1);"

      "fst  %%st(1);/n/t"

      "frndint;"        

      "fxch;/n/t"

      "fsub %%st(1);" 

      "f2xm1"

      : "=t" (ret), "=u" (value)

      : "0" (x)

   );

  

   ret += 1.0;

 

   __asm__(

      "fscale"

      : "=t" (ret)

      : "0" (ret), "u" (value)

   );

 

   return ret;

}//求e的x次幂

int main()

{

   double a = 1;

   printf("exp(%f) = %f/n",a,exp(a));

   printf("exp(%f) = %f/n",a,my_exp(a));

   a = 9.9;

   printf("exp(%f) = %f/n",a,exp(a));

   printf("exp(%f) = %f/n",a,my_exp(a));

  

   system("pause");

   return 0;

}

 

floor()函数源码

double my_floor(double x)

{

   register double ret;

   unsigned short int temp1, temp2;

 

   __asm__("fnstcw %0" : "=m" (temp1));

   temp2 = (temp1 & 0xf3ff) | 0x0400; /* rounding down */

   __asm__ ("fldcw %0" : : "m" (temp2));

   __asm__ ("frndint" : "=t" (ret) : "0" (x));

   __asm__ ("fldcw %0" : : "m" (temp1));

 

   return ret;

}//向下取整

//下面是俺自己写的向下取整的函数

double my_floor01(double x)

{

   double y=x;

    if( (*( ( (int *) &y)+1) & 0x80000000)  != 0) //或者if(x<0)

        return (float)((int)x)-1;

    else

        return (float)((int)x);

}

int main()

{

   double a = 88.8;

   printf("floor(%f) = %f/n",a,my_floor(a));

   a = -88.8;

   printf("floor(%f) = %f/n",a,my_floor(a));

   printf("****************************/n");

   a = 88.8;

   printf("floor(%f) = %f/n",a,my_floor01(a));

   a = -88.8;

   printf("floor(%f) = %f/n",a,my_floor01(a));

 

   system("pause");

   return 0;

}

 

ceil()函数源码

double my_ceil(double x)

{

   register double ret;

   unsigned short int temp1, temp2;

  

   __asm__("fnstcw %0" : "=m" (temp1));

   temp2 = (temp1 & 0xf3ff) | 0x0800; /* rounding up */

   __asm__("fldcw %0" : : "m" (temp2));

   __asm__("frndint" : "=t" (ret) : "0" (x));

   __asm__("fldcw %0" : : "m" (temp1));

  

   return ret;

}//向上取整

//下面是俺自己写的向上取整函数

double my_ceil01(double x)

{

   double y=x;

    if( (*( ( (int *) &y)+1) & 0x80000000) != 0)//或者if(x<0)

        return (float)((int)x);

    else                 //讨论非负的情况。

   {

        if(x == 0)

        return (float)((int)x);

        else

        return (float)((int)x) + 1;

   }

}

 

int main()

{

   double a = 88.8;

   printf("ceil(%f) = %f/n",a,my_ceil(a));

   a = -88.8;

   printf("ceil(%f) = %f/n",a,my_ceil(a));

   printf("****************************/n");

   a = 88.8;

   printf("ceil(%f) = %f/n",a,my_ceil01(a));

   a = -88.8;

   printf("ceil(%f) = %f/n",a,my_ceil01(a));

 

   system("pause");

   return 0;

}

 

sqrt()函数源码

double my_sqrt(double x)

{

   register double ret;

   __asm__(

      "fsqrt"

      : "=t" (ret)

      : "0" (x)

      );

 

   return ret;

}//计算x的平方根。

int main()

{

   double a = 4;

   printf("sqrt(%f) = %f/n",a,my_sqrt(a));

   a = 81;

   printf("sqrt(%f) = %f/n",a,my_sqrt(a));

   a = 12345678;

   printf("sqrt(%f) = %f/n",a,my_sqrt(a));

   system("pause");

   return 0;

}

 

pow10()函数源码

double my_pow10(double x)

{

   register double ret, value;

   __asm__(

      "fldl2t;/n/t"

      "fmul  %%st(1);/n/t"

      "fst   %%st(1);/n/t"

      "frndint;/n/t"

      "fxch;/n/t"

      "fsub  %%st(1);/n/t"

      "f2xm1 ;/n/t"

      : "=t" (ret), "=u" (value)

      : "0" (x)

   );

   ret += 1.0;

   __asm__(

      "fscale"

      : "=t" (ret)

      : "0" (ret), "u" (value)

   );

   return ret;

}//求10的x次幂(类似于求解exp的x次幂的算法)

int main()

{

   printf("%f/n",my_pow10(0.0));

   printf("%f/n",my_pow10(4));

   printf("%f/n",my_pow10(20));

 

   system("pause");

   return 0;

}

 

pow()函数源码

double my_pow(double x, double y)

{

   register double ret, value;

   double r = 1.0;

   long p = (long) y;

 

   if (x == 0.0 && y > 0.0)

      return 0.0;

   if (y == (double) p)

   {

     

      if (p == 0)

        return 1.0;

      if (p < 0)

      {

        p = -p;

        x = 1.0 / x;

      }

      while (1)

      {

        if (p & 1)

           r *= x;

        p >>= 1;

        if (p == 0)

           return r;

        x *= x;

      }

   }

   __asm__(

      "fmul  %%st(1);"

      "fst   %%st(1);"

      "frndint;/n/t"

      "fxch;/n/t"

      "fsub %%st(1);/n/t"

      "f2xm1;/n/t"

      : "=t" (ret), "=u" (value)

      :  "0" (log2 (x)), "1" (y)

   );

   ret += 1.0;

   __asm__(

      "fscale"

      : "=t" (ret)

      : "0" (ret), "u" (value)

   );

   return ret;

}

//这是一个求x的y次幂的函数,因为要求是浮点数类型的,所以代码复杂了许多。

//如果仅仅是求整数的x的y次幂,那么就简单了许多。

int main()

{

   printf("%f/n",my_pow(0.0,0.0));

   printf("%f/n",my_pow(1024.0,0.0));

   printf("%f/n",my_pow(2.0,10.0));

   printf("%f/n",pow(2.5,12.6));

   printf("%f/n",my_pow(2.5,12.6));

   system("pause");

   return 0;

}

 

log10()函数源码

double my_log10(double x)

{

   register double ret;

   __asm__(

      "fldlg2/n/t"

      "fxch/n/t"

      "fyl2x"

      : "=t" (ret)

      : "0" (x)

   );

   return ret;

}//计算x的常用对数。

int main()

{

   printf("%f/n",log10(1000000));

   printf("%f/n",my_log10(1024.1024));

  

   system("pause");

   return 0;

}

 

log2()函数源码

double my_log2(double x)

{

   register double ret;

   __asm__(

      "fld1/n/t"

      "fxch/n/t"

      "fyl2x"

      : "=t" (ret)

      : "0" (x)

   );

 

   return ret;

}//计算以2为底的对数

int main()

{

   printf("%f/n",log2(1024.1024));

   printf("%f/n",my_log2(1024.1024));

  

   system("pause");

   return 0;

}

 

log()函数源码

double my_log(double x)

{

   register double ret;

   __asm__(

      "fldln2/n/t"

      "fxch/n/t"

      "fyl2x"

      : "=t" (ret)

      : "0" (x)

   );

   return ret;

}//计算x的自然对数。

int main()

{

   printf("%f/n",log(1024.1024));

   printf("%f/n",my_log(1024.1024));

  

   system("pause");

   return 0;

}

 

tan()函数源码

double my_tan(double x)

{

   register double ret;

   register double value;

   __asm__(

      "fptan"

      : "=t" (value),

      "=u" (ret)

      : "0" (x)

   );

   return ret;

}//计算x(弧度表示)的正切值。

int main()

{

   printf("%f/n",tan(0.5));

   printf("%f/n",my_tan(0.5));

   system("pause");

   return 0;

}

 

cos()函数源码

double my_cos (double x)

{

   register double ret;

   __asm__(

      "fcos"

      : "=t" (ret)

      : "0" (x)

   );

   return ret;

}//计算x(弧度表示)的余弦值。

int main()

{

   printf("%f/n",cos(0.5));

   printf("%f/n",my_cos(0.5));

   system("pause");

   return 0;

}

 

sin()函数源码

double my_sin(double x)

{

   register double ret;

   __asm__ (

      "fsin"

      : "=t" (ret)

      : "0" (x)

   );

   return ret;

}//计算x(弧度表示)的正弦值。

int main()

{

   printf("%f/n",sin(0.5));

   printf("%f/n",my_sin(0.5));

   system("pause");

   return 0;

}

 

fabs()函数源码

float my_fabs01 (float fnumber)

{

  float ret;

  __asm__ (

     "fabs/n/r"

     : "=t" (ret)

     : "0" (fnumber)

  );

  return ret;

}

//直接调用了奔腾系列CPU浮点指令系统中的求浮点数绝对值指令。

 

float my_fabs02(float fnumber)

{

   *( (int *) &fnumber) &=0x7FFFFFFF;

  return fnumber;

}

//取得浮点数的地址,然后把符号位置0。

 

double my_fabs03(double dnumber)

{

  *( ( (int *) & dnumber) + 1) &=0x7FFFFFFF;

  return dnumber;

}

int main()

{

  

   printf("%f/n",my_fabs01(0.000001));

   printf("%f/n",my_fabs01(-0.000001));

   printf("%f/n",my_fabs01(1.1234567));

   printf("%f/n",my_fabs01(-1.1234567));

  

   printf("****************************/n");

  

   printf("%f/n",my_fabs02(0.000001));

   printf("%f/n",my_fabs02(-0.000001));

   printf("%f/n",my_fabs02(1.1234567));

   printf("%f/n",my_fabs02(-1.1234567));

  

   printf("****************************/n");

  

   printf("%f/n",my_fabs03(111111111.0000019));

   printf("%f/n",my_fabs03(-111111111.0000019));

   printf("%f/n",my_fabs03(1234567.12345678));

   printf("%f/n",my_fabs03(-1234567.12345678));

 

   system("pause");

   return 0;

}

 

labs()函数源码

long int my_labs(long int number)

{

   return (number>= 0 ? number : -number);

}

 

long int my_asmlabs(long int number)

{

   __asm__(

      "mov %1,%%eax; /n/r"  //由输入寄存器 %1移动到eax

      "or %%eax,%%eax; /n/r" //或运算

      "jge 4f; /n/r"        //SF = OF 跳转

                //(符号位和溢出位相同的时候,为正数)

      "neg %%eax; /n/r"     //取负数预算指令

      "4:"      

      "mov %%eax,%0; /n/r"  //eax值赋给输出寄存器 %0

      :"=r"(number)       //输出寄存器 %0

      :"r"(number)        //输入寄存器 %1

   );

   return number;

}

 

int main()

{

   printf("%d/n",my_asmlabs(1));

   printf("%d/n",my_asmlabs(-1));

   printf("%d/n",my_asmlabs(0x7FFFFFFF));

   printf("%d/n",my_asmlabs(-0x7FFFFFFF));

   system("pause");

   return 0;

}

 

abs()函数源码

int my_abs(int number)

{

   return (number>= 0 ? number : -number);

}

int my_asmabs(int number)

{

   __asm__(

      "mov %1,%%eax; /n/r"  //由输入寄存器 %1移动到eax

      "or %%eax,%%eax; /n/r" //或运算

      "jge 4f; /n/r"        //SF=OF 跳转

                    //(符号位和溢出位相同的时候,为正数)

      "neg %%eax; /n/r"     //取负数预算指令

      "4:"      

      "mov %%eax,%0; /n/r"  //把eax的值赋给输出寄存器 %0

      :"=r"(number)       //输出寄存器 %0

      :"r"(number)        //输入寄存器 %1

   );

   return number;

}

 

int main()

{

   printf("%d/n",my_asmabs(1));

   printf("%d/n",my_asmabs(-1));

   printf("%d/n",my_asmabs(0x7FFFFFFF));

   printf("%d/n",my_asmabs(-0x7FFFFFFF));

   system("pause");

   return 0;

}

posted on 2018-10-30 17:54  blogernice  阅读(728)  评论(0编辑  收藏  举报