sfsqrt.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:5k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * Linux/PA-RISC Project (http://www.parisc-linux.org/)
  3.  *
  4.  * Floating-point emulation code
  5.  *  Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
  6.  *
  7.  *    This program is free software; you can redistribute it and/or modify
  8.  *    it under the terms of the GNU General Public License as published by
  9.  *    the Free Software Foundation; either version 2, or (at your option)
  10.  *    any later version.
  11.  *
  12.  *    This program is distributed in the hope that it will be useful,
  13.  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *    GNU General Public License for more details.
  16.  *
  17.  *    You should have received a copy of the GNU General Public License
  18.  *    along with this program; if not, write to the Free Software
  19.  *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  */
  21. /*
  22.  * BEGIN_DESC
  23.  *
  24.  *  File:
  25.  * @(#) pa/spmath/sfsqrt.c $Revision: 1.1 $
  26.  *
  27.  *  Purpose:
  28.  * Single Floating-point Square Root
  29.  *
  30.  *  External Interfaces:
  31.  * sgl_fsqrt(srcptr,nullptr,dstptr,status)
  32.  *
  33.  *  Internal Interfaces:
  34.  *
  35.  *  Theory:
  36.  * <<please update with a overview of the operation of this file>>
  37.  *
  38.  * END_DESC
  39. */
  40. #include "float.h"
  41. #include "sgl_float.h"
  42. /*
  43.  *  Single Floating-point Square Root
  44.  */
  45. /*ARGSUSED*/
  46. unsigned int
  47. sgl_fsqrt(
  48.     sgl_floating_point *srcptr,
  49.     unsigned int *nullptr,
  50.     sgl_floating_point *dstptr,
  51.     unsigned int *status)
  52. {
  53. register unsigned int src, result;
  54. register int src_exponent;
  55. register unsigned int newbit, sum;
  56. register boolean guardbit = FALSE, even_exponent;
  57. src = *srcptr;
  58.         /*
  59.          * check source operand for NaN or infinity
  60.          */
  61.         if ((src_exponent = Sgl_exponent(src)) == SGL_INFINITY_EXPONENT) {
  62.                 /*
  63.                  * is signaling NaN?
  64.                  */
  65.                 if (Sgl_isone_signaling(src)) {
  66.                         /* trap if INVALIDTRAP enabled */
  67.                         if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
  68.                         /* make NaN quiet */
  69.                         Set_invalidflag();
  70.                         Sgl_set_quiet(src);
  71.                 }
  72.                 /*
  73.                  * Return quiet NaN or positive infinity.
  74.  *  Fall thru to negative test if negative infinity.
  75.                  */
  76. if (Sgl_iszero_sign(src) || Sgl_isnotzero_mantissa(src)) {
  77.                  *dstptr = src;
  78.                  return(NOEXCEPTION);
  79. }
  80.         }
  81.         /*
  82.          * check for zero source operand
  83.          */
  84. if (Sgl_iszero_exponentmantissa(src)) {
  85. *dstptr = src;
  86. return(NOEXCEPTION);
  87. }
  88.         /*
  89.          * check for negative source operand 
  90.          */
  91. if (Sgl_isone_sign(src)) {
  92. /* trap if INVALIDTRAP enabled */
  93. if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
  94. /* make NaN quiet */
  95. Set_invalidflag();
  96. Sgl_makequietnan(src);
  97. *dstptr = src;
  98. return(NOEXCEPTION);
  99. }
  100. /*
  101.  * Generate result
  102.  */
  103. if (src_exponent > 0) {
  104. even_exponent = Sgl_hidden(src);
  105. Sgl_clear_signexponent_set_hidden(src);
  106. }
  107. else {
  108. /* normalize operand */
  109. Sgl_clear_signexponent(src);
  110. src_exponent++;
  111. Sgl_normalize(src,src_exponent);
  112. even_exponent = src_exponent & 1;
  113. }
  114. if (even_exponent) {
  115. /* exponent is even */
  116. /* Add comment here.  Explain why odd exponent needs correction */
  117. Sgl_leftshiftby1(src);
  118. }
  119. /*
  120.  * Add comment here.  Explain following algorithm.
  121.  * 
  122.  * Trust me, it works.
  123.  *
  124.  */
  125. Sgl_setzero(result);
  126. newbit = 1 << SGL_P;
  127. while (newbit && Sgl_isnotzero(src)) {
  128. Sgl_addition(result,newbit,sum);
  129. if(sum <= Sgl_all(src)) {
  130. /* update result */
  131. Sgl_addition(result,(newbit<<1),result);
  132. Sgl_subtract(src,sum,src);
  133. }
  134. Sgl_rightshiftby1(newbit);
  135. Sgl_leftshiftby1(src);
  136. }
  137. /* correct exponent for pre-shift */
  138. if (even_exponent) {
  139. Sgl_rightshiftby1(result);
  140. }
  141. /* check for inexact */
  142. if (Sgl_isnotzero(src)) {
  143. if (!even_exponent && Sgl_islessthan(result,src)) 
  144. Sgl_increment(result);
  145. guardbit = Sgl_lowmantissa(result);
  146. Sgl_rightshiftby1(result);
  147. /*  now round result  */
  148. switch (Rounding_mode()) {
  149. case ROUNDPLUS:
  150.      Sgl_increment(result);
  151.      break;
  152. case ROUNDNEAREST:
  153.      /* stickybit is always true, so guardbit 
  154.       * is enough to determine rounding */
  155.      if (guardbit) {
  156. Sgl_increment(result);
  157.      }
  158.      break;
  159. }
  160. /* increment result exponent by 1 if mantissa overflowed */
  161. if (Sgl_isone_hiddenoverflow(result)) src_exponent+=2;
  162. if (Is_inexacttrap_enabled()) {
  163. Sgl_set_exponent(result,
  164.  ((src_exponent-SGL_BIAS)>>1)+SGL_BIAS);
  165. *dstptr = result;
  166. return(INEXACTEXCEPTION);
  167. }
  168. else Set_inexactflag();
  169. }
  170. else {
  171. Sgl_rightshiftby1(result);
  172. }
  173. Sgl_set_exponent(result,((src_exponent-SGL_BIAS)>>1)+SGL_BIAS);
  174. *dstptr = result;
  175. return(NOEXCEPTION);
  176. }