首页 > 代码库 > math.h()函数源码
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;
}
math.h()函数源码