1.因为某些原因使用自定义的,没有自己写的代码都是拷贝的。
版本一:
exp:
static double my_log2(double x)
{
register double ret;
__asm__(
"fld1;"
"fxch;"
"fyl2x"
: "=t" (ret)
: "0" (x)
);
return ret;
}
static double log2(double x)
{
return my_log2(x);
}
static 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;;"
"fxch;;"
"fsub %%st(1);;"
"f2xm1;;"
: "=t" (ret), "=u" (value)
: "0" (log2 (x)), "1" (y)
);
ret += 1.0;
__asm__(
"fscale"
: "=t" (ret)
: "0" (ret), "u" (value)
);
return ret;
}
static double exp(double x)
{
return my_pow(2.718281828459,x);
}
log:
static double my_log10(double x)
{
register double ret;
__asm__(
"fldlg2;"
"fxch;"
"fyl2x"
: "=t" (ret)
: "0" (x)
);
return ret;
}
static double log10(double x)
{
return my_log10(x);
}
ln:
static double my_log(double x)
{
register double ret;
__asm__(
"fldln2;"
"fxch;"
"fyl2x"
: "=t" (ret)
: "0" (x)
);
return ret;
}
static double ln(double x)
{
return my_log(x);
}
由于是直接使用的嵌入汇编,在64位程序无法正确使用。然后就抄写了另外一种:
版本二:
使用泰勒公式进行计算(我哪里还记得当年学的这个啊!)。
static double exp(double x)
{
double term, ex;
unsigned long n;
int sign;
if (x == 0)
{
return (double)1;
}
if (x < 0)
{
sign = 0;
x = -x;
}
else
{
sign = 1;
}
n = 1;
ex = x + 1;
term = x;
do {
n += 1;
term /= n;
term *= x;
ex += term;
if (ex > 1E16)
{
if (sign)
{
return (1E17);
}
else
{
return 0;
}
}
} while (term > 1E-15);
if (sign)
{
return ex;
}
else
{
return 1 / ex;
}
}
static double log(double x)
{
double y, y2, r, num, lr, r1, x2;
unsigned long den;
int i, n, j;
if (x <= 0) //无效的参数
{
return 0;
}
if (x == 1)
{
return 0;
}
j = 0;
while (x < 1)
{
x *= 10;
j++;
}
if (x > 1 && x < 2)
{
y = (x - 1) / (x + 1);
y2 = y * y;
r = 0;
num = y;
den = 1;
do {
lr = r;
r += num / den;
num *= y2;
den += 2;
} while (lr != r);
return (r * 2 - j * LN10);
}
else
{
i = 0;
n = 1;
den = 2;
while (x > 2)
{
x /= 2;
i++;
}
x = (x - 1) / (x + 1);
x2 = x * x;
r1 = 2 * x;
r = 0;
while (r1 > 1E-15)
{
r += r1;
n += den;
x *= x2;
r1 = 2 * x / n;
}
return (r + LN2 * i - j * LN10);
}
}
static double log10(double x)
{
return log(x) / log(10);
}
都是使用比较简单的加减乘除,目前就这样。
|