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

📄 qtrans.c

📁 Calc Software Package for Number Calc
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (qisneg(q1)) {		math_error("Negative base for qpower");		/*NOTREACHED*/	}	if (qisone(q2))		return qmappr(q1, epsilon, 24);	if (zrel(q1->num, q1->den) < 0) {		q1tmp = qinv(q1);		q2tmp = qneg(q2);	} else {		q1tmp = qlink(q1);		q2tmp = qlink(q2);	}	if (qisone(q2tmp)) {		qfree(q2tmp);		q2tmp = qmappr(q1tmp, epsilon, 24);		qfree(q1tmp);		return q2tmp;	}	m = qilog2(q1tmp);	n = qilog2(epsilon);	if (qisneg(q2tmp)) {		if (m > 0) {			tmp1 = itoq(m);			tmp2 = qmul(tmp1, q2tmp);			m = qtoi(tmp2);		} else {			tmp1 = qdec(q1tmp);			tmp2 = qqdiv(tmp1, q1tmp);			qfree(tmp1);			tmp1 = qmul(tmp2, q2tmp);			qfree(tmp2);			tmp2 = qmul(tmp1, &_qlge_);			m = qtoi(tmp2);		}	} else {		if (m > 0) {			tmp1 = itoq(m + 1);			tmp2 = qmul(tmp1, q2tmp);			m = qtoi(tmp2);		} else {			tmp1 = qdec(q1tmp);			tmp2 = qmul(tmp1, q2tmp);			qfree(tmp1);			tmp1 = qmul(tmp2, &_qlge_);			m = qtoi(tmp1);		}	}	qfree(tmp1);	qfree(tmp2);	if (m > (1 << 30)) {		qfree(q1tmp);		qfree(q2tmp);		return NULL;	}	m += 1;	if (m < n) {		qfree(q1tmp);		qfree(q2tmp);		return qlink(&_qzero_);	}	tmp1 = qqdiv(epsilon, q2tmp);	tmp2 = qscale(tmp1, -m - 4);	epsilon2 = qqabs(tmp2);	qfree(tmp1);	qfree(tmp2);	tmp1 = qln(q1tmp, epsilon2);	qfree(epsilon2);	tmp2 = qmul(tmp1, q2tmp);	qfree(tmp1);	qfree(q1tmp);	qfree(q2tmp);	if (qisneg(tmp2)) {		tmp1 = qneg(tmp2);		qfree(tmp2);		tmp2 = qexprel(tmp1, m - n + 3);		if (tmp2 == NULL) {			qfree(tmp1);			return NULL;		}		qfree(tmp1);		tmp1 = qinv(tmp2);	} else {		tmp1 = qexprel(tmp2, m - n + 3) ;		if (tmp1 == NULL) {			qfree(tmp2);			return NULL;		}	}	qfree(tmp2);	tmp2 = qmappr(tmp1, epsilon, 24L);	qfree(tmp1);	return tmp2;}/* * Calculate the Kth root of a number to within the specified accuracy. */NUMBER *qroot(NUMBER *q1, NUMBER *q2, NUMBER *epsilon){	NUMBER *tmp1, *tmp2;	int neg;	if (qiszero(epsilon)) {		math_error("Zero epsilon for root");		/*NOTREACHED*/	}	if (qisneg(q2) || qiszero(q2) || qisfrac(q2)) {		math_error("Taking bad root of number");		/*NOTREACHED*/	}	if (qiszero(q1) || qisone(q1) || qisone(q2))		return qlink(q1);	if (qistwo(q2))		return qsqrt(q1, epsilon, 24L);	neg = qisneg(q1);	if (neg) {		if (ziseven(q2->num)) {			math_error("Taking even root of negative number");			/*NOTREACHED*/		}		q1 = qqabs(q1);	}	tmp2 = qinv(q2);	tmp1 = qpower(q1, tmp2, epsilon);	qfree(tmp2);	if (tmp1 == NULL)		return NULL;	if (neg) {		tmp2 = qneg(tmp1);		qfree(tmp1);		tmp1 = tmp2;	}	return tmp1;}/* Calculate the hyperbolic cosine function to the nearest or next to * nearest multiple of epsilon. * This is calculated using cosh(x) = (exp(x) + 1/exp(x))/2; */NUMBER *qcosh(NUMBER *q, NUMBER *epsilon){	NUMBER *tmp1, *tmp2, *tmp3, *epsilon1;	epsilon1 = qscale(epsilon, -2);	tmp1 = qqabs(q);	tmp2 = qexp(tmp1, epsilon1);	qfree(tmp1);	qfree(epsilon1);	if (tmp2 == NULL)		return NULL;	tmp1 = qinv(tmp2);	tmp3 = qqadd(tmp1, tmp2);	qfree(tmp1)	qfree(tmp2)	tmp1 = qscale(tmp3, -1);	qfree(tmp3);	tmp2 = qmappr(tmp1, epsilon, 24L);	qfree(tmp1);	return tmp2;}/* * Calculate the hyperbolic sine to the nearest or next to nearest * multiple of epsilon. * This is calculated using sinh(x) = (exp(x) - 1/exp(x))/2. */NUMBER *qsinh(NUMBER *q, NUMBER *epsilon){	NUMBER *tmp1, *tmp2, *tmp3, *epsilon1;	if (qiszero(q))		return qlink(&_qzero_);	epsilon1 = qscale(epsilon, -3);	tmp1 = qqabs(q);	tmp2 = qexp(tmp1, epsilon1);	qfree(tmp1);	qfree(epsilon1);	if (tmp2 == NULL)		return NULL;	tmp1 = qinv(tmp2);	tmp3 = qispos(q) ? qsub(tmp2, tmp1) : qsub(tmp1, tmp2);	qfree(tmp1)	qfree(tmp2)	tmp1 = qscale(tmp3, -1);	qfree(tmp3);	tmp2 = qmappr(tmp1, epsilon, 24L);	qfree(tmp1);	return tmp2;}/* * Calculate the hyperbolic tangent to the nearest or next to nearest * multiple of epsilon. * This is calculated using the formulae: *	tanh(x) = 1 or -1 for very large abs(x) *	tanh(x) = (+ or -)(1 - 2 * exp(2 * x))	for large abx(x) *	tanh(x) = (exp(2*x) - 1)/(exp(2*x) + 1) otherwise */NUMBER *qtanh(NUMBER *q, NUMBER *epsilon){	NUMBER *tmp1, *tmp2, *tmp3;	long n, m;	n = qilog2(epsilon);	if (n > 0 || qiszero(q))		return qlink(&_qzero_);	n = -n;	tmp1 = qqabs(q);	tmp2 = qmul(tmp1, &_qlge_);	m = qtoi(tmp2);		/* exp(|q|) < 2^(m+1) or m == MAXLONG */	qfree(tmp2);	if (m > 1 + n/2) {		qfree(tmp1);		return q->num.sign ? qlink(&_qnegone_) : qlink(&_qone_);	}	tmp2 = qscale(tmp1, 1);	qfree(tmp1);	tmp1 = qexprel(tmp2, 2 + n);	qfree(tmp2);	if (m > 1 + n/4) {		tmp2 = qqdiv(&_qtwo_, tmp1);		qfree(tmp1);		tmp1 = qsub(&_qone_, tmp2);		qfree(tmp2);	} else {		tmp2 = qdec(tmp1);		tmp3 = qinc(tmp1);		qfree(tmp1);		tmp1 = qqdiv(tmp2, tmp3);		qfree(tmp2);		qfree(tmp3);	}	tmp2 = qmappr(tmp1, epsilon, 24L);	qfree(tmp1);	if (qisneg(q)) {		tmp1 = qneg(tmp2);		qfree(tmp2);		return tmp1;	}	return tmp2;}/* * Hyperbolic cotangent. * Calculated using coth(x) = 1 + 2/(exp(2*x) - 1) */NUMBER *qcoth(NUMBER *q, NUMBER *epsilon){	NUMBER *tmp1, *tmp2, *res;	long n, k;	if (qiszero(epsilon)) {		math_error("Zero epsilon value for coth");		/*NOTREACHED*/	}	if (qiszero(q)) {		math_error("Zero argument for coth");		/*NOTREACHED*/	}	tmp1 = qscale(q, 1);	tmp2 = qqabs(tmp1);	qfree(tmp1);	k = qilog2(tmp2);	n = qilog2(epsilon);	if (k > 0) {		tmp1 = qmul(&_qlge_, tmp2);		k = qtoi(tmp1);		qfree(tmp1);	} else {		k = 2 * k;	}	k = 4 - k - n;	if (k < 4)		k = 4;	tmp1 = qexprel(tmp2,  k);	qfree(tmp2);	tmp2 = qdec(tmp1);	qfree(tmp1);	if (qiszero(tmp2)) {		math_error("This should not happen ????");		/*NOTREACHED*/	}	tmp1 = qinv(tmp2);	qfree(tmp2);	tmp2 = qscale(tmp1, 1);	qfree(tmp1);	tmp1 = qinc(tmp2);	qfree(tmp2);	if (qisneg(q)) {		tmp2 = qneg(tmp1);		qfree(tmp1);		tmp1 = tmp2;	}	res = qmappr(tmp1, epsilon, 24L);	qfree(tmp1);	return res;}NUMBER *qsech(NUMBER *q, NUMBER *epsilon){	NUMBER *tmp1, *tmp2, *tmp3, *res;	long n, k;	if (qiszero(epsilon)) {		math_error("Zero epsilon value for sech");		/*NOTREACHED*/	}	if (qiszero(q))		return qlink(&_qone_);	tmp1 = qqabs(q);	k = 0;	if (zrel(tmp1->num, tmp1->den) >= 0) {		tmp2 = qmul(&_qlge_, tmp1);		k = qtoi(tmp2);		qfree(tmp2);	}	n = qilog2(epsilon);	if (k + n > 1) {		qfree(tmp1);		return qlink(&_qzero_);	}	tmp2 = qexprel(tmp1, 4 - k - n);	qfree(tmp1);	tmp1 = qinv(tmp2);	tmp3 = qqadd(tmp1, tmp2);	qfree(tmp1);	qfree(tmp2);	tmp1 = qinv(tmp3);	qfree(tmp3);	tmp2 = qscale(tmp1, 1);	qfree(tmp1);	res = qmappr(tmp2, epsilon, 24L);	qfree(tmp2);	return res;}NUMBER *qcsch(NUMBER *q, NUMBER *epsilon){	NUMBER *tmp1, *tmp2, *tmp3, *res;	long n, k;	if (qiszero(epsilon)) {		math_error("Zero epsilon value for csch");		/*NOTREACHED*/	}	if (qiszero(q)) {		math_error("Zero argument for csch");		/*NOTREACHED*/	}	n = qilog2(epsilon);	tmp1 = qqabs(q);	if (zrel(tmp1->num, tmp1->den) >= 0) {		tmp2 = qmul(&_qlge_, tmp1);		k = qtoi(tmp2);		qfree(tmp2);	} else {		k = 2 * qilog2(tmp1);	}	if (k + n >= 1) {		qfree(tmp1);		return qlink(&_qzero_);	}	tmp2 = qexprel(tmp1, 4 - k - n);	qfree(tmp1);	tmp1 = qinv(tmp2);	if (qisneg(q))		tmp3 = qsub(tmp1, tmp2);	else		tmp3 = qsub(tmp2, tmp1);	qfree(tmp1);	qfree(tmp2);	tmp1 = qinv(tmp3);	qfree(tmp3)	tmp2 = qscale(tmp1, 1);	qfree(tmp1);	res = qmappr(tmp2, epsilon, 24L);	qfree(tmp2);	return res;}/* * Compute the hyperbolic arccosine within the specified accuracy. * This is calculated using the formula: *	acosh(x) = ln(x + sqrt(x^2 - 1)). */NUMBER *qacosh(NUMBER *q, NUMBER *epsilon){	NUMBER *tmp1, *tmp2, *epsilon1;	long n;	if (qiszero(epsilon)) {		math_error("Zero epsilon value for acosh");		/*NOTREACHED*/	}	if (qisone(q))		return qlink(&_qzero_);	if (zrel(q->num, q->den) < 0)		return NULL;	n = qilog2(epsilon);	epsilon1 = qbitvalue(n - 3);	tmp1 = qsquare(q);	tmp2 = qdec(tmp1);	qfree(tmp1);	tmp1 = qsqrt(tmp2, epsilon1, 24L);	qfree(tmp2);	tmp2 = qqadd(tmp1, q);	qfree(tmp1);	tmp1 = qln(tmp2, epsilon1);	qfree(tmp2);	qfree(epsilon1);	tmp2 = qmappr(tmp1, epsilon, 24L);	qfree(tmp1);	return tmp2;}/* * Compute the hyperbolic arcsine within the specified accuracy. * This is calculated using the formula: *	asinh(x) = ln(x + sqrt(x^2 + 1)). */NUMBER *qasinh(NUMBER *q, NUMBER *epsilon){	NUMBER *tmp1, *tmp2, *epsilon1;	long n;	BOOL neg;	if (qiszero(epsilon)) {		math_error("Zero epsilon value for asinh");		/*NOTREACHED*/	}	if (qiszero(q))		return qlink(&_qzero_);	neg = qisneg(q);	q = qqabs(q);	n = qilog2(epsilon);	epsilon1 = qbitvalue(n - 3);	tmp1 = qsquare(q);	tmp2 = qinc(tmp1);	qfree(tmp1);	tmp1 = qsqrt(tmp2, epsilon1, 24L);	qfree(tmp2);	tmp2 = qqadd(tmp1, q);	qfree(tmp1);	tmp1 = qln(tmp2, epsilon1);	qfree(tmp2);	qfree(q);	qfree(epsilon1);	tmp2 = qmappr(tmp1, epsilon, 24L);	if (neg) {		tmp1 = qneg(tmp2);		qfree(tmp2);		return tmp1;	}	return tmp2;}/* * Compute the hyperbolic arctangent within the specified accuracy. * This is calculated using the formula: *	atanh(x) = ln((1 + x) / (1 - x)) / 2. */NUMBER *qatanh(NUMBER *q, NUMBER *epsilon){	NUMBER *tmp1, *tmp2, *tmp3, *epsilon1;	ZVALUE z;	if (qiszero(epsilon)) {		math_error("Zero epsilon value for atanh");		/*NOTREACHED*/	}	if (qiszero(q))		return qlink(&_qzero_);	z = q->num;	z.sign = 0;	if (zrel(z, q->den) >= 0)		return NULL;	tmp1 = qinc(q);	tmp2 = qsub(&_qone_, q);	tmp3 = qqdiv(tmp1, tmp2);	qfree(tmp1);	qfree(tmp2);	epsilon1 = qscale(epsilon, 1L);	tmp1 = qln(tmp3, epsilon1);	qfree(tmp3);	tmp2 = qscale(tmp1, -1L);	qfree(tmp1);	qfree(epsilon1);	return tmp2;}/* * Inverse hyperbolic secant function */NUMBER *qasech(NUMBER *q, NUMBER *epsilon){	NUMBER *tmp, *res;	tmp = qinv(q);	res = qacosh(tmp, epsilon);	qfree(tmp);	return res;}/* * Inverse hyperbolic cosecant function */NUMBER *qacsch(NUMBER *q, NUMBER *epsilon){	NUMBER *tmp, *res;	tmp = qinv(q);	res = qasinh(tmp, epsilon);	qfree(tmp);	return res;}/* * Inverse hyperbolic cotangent function */NUMBER *qacoth(NUMBER *q, NUMBER *epsilon){	NUMBER *tmp, *res;	tmp = qinv(q);	res = qatanh(tmp, epsilon);	qfree(tmp);	return res;}

⌨️ 快捷键说明

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