sp_sqrt.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:3k
- /* IEEE754 floating point arithmetic
- * single precision square root
- */
- /*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- * This program is free software; you can distribute it and/or modify it
- * under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
- #include "ieee754sp.h"
- static const struct ieee754sp_konst knan = {
- 0, SP_EBIAS + SP_EMAX + 1, 0
- };
- #define nan ((ieee754sp)knan)
- ieee754sp ieee754sp_sqrt(ieee754sp x)
- {
- int sign = (int) 0x80000000;
- int ix, s, q, m, t, i;
- unsigned int r;
- COMPXDP;
- /* take care of Inf and NaN */
- EXPLODEXDP;
- /* x == INF or NAN? */
- switch (xc) {
- case IEEE754_CLASS_QNAN:
- case IEEE754_CLASS_SNAN:
- /* sqrt(Nan) = Nan */
- return ieee754sp_nanxcpt(x, "sqrt");
- case IEEE754_CLASS_ZERO:
- /* sqrt(0) = 0 */
- return x;
- case IEEE754_CLASS_INF:
- if (xs)
- /* sqrt(-Inf) = Nan */
- return ieee754sp_nanxcpt(nan, "sqrt");
- /* sqrt(+Inf) = Inf */
- return x;
- case IEEE754_CLASS_DNORM:
- case IEEE754_CLASS_NORM:
- if (xs)
- /* sqrt(-x) = Nan */
- return ieee754sp_nanxcpt(nan, "sqrt");
- break;
- }
- ix = x.bits;
- /* normalize x */
- m = (ix >> 23);
- if (m == 0) { /* subnormal x */
- for (i = 0; (ix & 0x00800000) == 0; i++)
- ix <<= 1;
- m -= i - 1;
- }
- m -= 127; /* unbias exponent */
- ix = (ix & 0x007fffff) | 0x00800000;
- if (m & 1) /* odd m, double x to make it even */
- ix += ix;
- m >>= 1; /* m = [m/2] */
- /* generate sqrt(x) bit by bit */
- ix += ix;
- q = s = 0; /* q = sqrt(x) */
- r = 0x01000000; /* r = moving bit from right to left */
- while (r != 0) {
- t = s + r;
- if (t <= ix) {
- s = t + r;
- ix -= t;
- q += r;
- }
- ix += ix;
- r >>= 1;
- }
- if (ix != 0) {
- switch (ieee754_csr.rm) {
- case IEEE754_RP:
- q += 2;
- break;
- case IEEE754_RN:
- q += (q & 1);
- break;
- }
- }
- ix = (q >> 1) + 0x3f000000;
- ix += (m << 23);
- x.bits = ix;
- return x;
- }