dfsqrt.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/dfsqrt.c $Revision: 1.1 $
  26.  *
  27.  *  Purpose:
  28.  * Double Floating-point Square Root
  29.  *
  30.  *  External Interfaces:
  31.  * dbl_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 "dbl_float.h"
  42. /*
  43.  *  Double Floating-point Square Root
  44.  */
  45. /*ARGSUSED*/
  46. unsigned int
  47. dbl_fsqrt(
  48.     dbl_floating_point *srcptr,
  49.     unsigned int *nullptr,
  50.     dbl_floating_point *dstptr,
  51.     unsigned int *status)
  52. {
  53. register unsigned int srcp1, srcp2, resultp1, resultp2;
  54. register unsigned int newbitp1, newbitp2, sump1, sump2;
  55. register int src_exponent;
  56. register boolean guardbit = FALSE, even_exponent;
  57. Dbl_copyfromptr(srcptr,srcp1,srcp2);
  58.         /*
  59.          * check source operand for NaN or infinity
  60.          */
  61.         if ((src_exponent = Dbl_exponent(srcp1)) == DBL_INFINITY_EXPONENT) {
  62.                 /*
  63.                  * is signaling NaN?
  64.                  */
  65.                 if (Dbl_isone_signaling(srcp1)) {
  66.                         /* trap if INVALIDTRAP enabled */
  67.                         if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
  68.                         /* make NaN quiet */
  69.                         Set_invalidflag();
  70.                         Dbl_set_quiet(srcp1);
  71.                 }
  72.                 /*
  73.                  * Return quiet NaN or positive infinity.
  74.  *  Fall thru to negative test if negative infinity.
  75.                  */
  76. if (Dbl_iszero_sign(srcp1) || 
  77.     Dbl_isnotzero_mantissa(srcp1,srcp2)) {
  78.                  Dbl_copytoptr(srcp1,srcp2,dstptr);
  79.                  return(NOEXCEPTION);
  80. }
  81.         }
  82.         /*
  83.          * check for zero source operand
  84.          */
  85. if (Dbl_iszero_exponentmantissa(srcp1,srcp2)) {
  86. Dbl_copytoptr(srcp1,srcp2,dstptr);
  87. return(NOEXCEPTION);
  88. }
  89.         /*
  90.          * check for negative source operand 
  91.          */
  92. if (Dbl_isone_sign(srcp1)) {
  93. /* trap if INVALIDTRAP enabled */
  94. if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
  95. /* make NaN quiet */
  96. Set_invalidflag();
  97. Dbl_makequietnan(srcp1,srcp2);
  98. Dbl_copytoptr(srcp1,srcp2,dstptr);
  99. return(NOEXCEPTION);
  100. }
  101. /*
  102.  * Generate result
  103.  */
  104. if (src_exponent > 0) {
  105. even_exponent = Dbl_hidden(srcp1);
  106. Dbl_clear_signexponent_set_hidden(srcp1);
  107. }
  108. else {
  109. /* normalize operand */
  110. Dbl_clear_signexponent(srcp1);
  111. src_exponent++;
  112. Dbl_normalize(srcp1,srcp2,src_exponent);
  113. even_exponent = src_exponent & 1;
  114. }
  115. if (even_exponent) {
  116. /* exponent is even */
  117. /* Add comment here.  Explain why odd exponent needs correction */
  118. Dbl_leftshiftby1(srcp1,srcp2);
  119. }
  120. /*
  121.  * Add comment here.  Explain following algorithm.
  122.  * 
  123.  * Trust me, it works.
  124.  *
  125.  */
  126. Dbl_setzero(resultp1,resultp2);
  127. Dbl_allp1(newbitp1) = 1 << (DBL_P - 32);
  128. Dbl_setzero_mantissap2(newbitp2);
  129. while (Dbl_isnotzero(newbitp1,newbitp2) && Dbl_isnotzero(srcp1,srcp2)) {
  130. Dbl_addition(resultp1,resultp2,newbitp1,newbitp2,sump1,sump2);
  131. if(Dbl_isnotgreaterthan(sump1,sump2,srcp1,srcp2)) {
  132. Dbl_leftshiftby1(newbitp1,newbitp2);
  133. /* update result */
  134. Dbl_addition(resultp1,resultp2,newbitp1,newbitp2,
  135.  resultp1,resultp2);  
  136. Dbl_subtract(srcp1,srcp2,sump1,sump2,srcp1,srcp2);
  137. Dbl_rightshiftby2(newbitp1,newbitp2);
  138. }
  139. else {
  140. Dbl_rightshiftby1(newbitp1,newbitp2);
  141. }
  142. Dbl_leftshiftby1(srcp1,srcp2);
  143. }
  144. /* correct exponent for pre-shift */
  145. if (even_exponent) {
  146. Dbl_rightshiftby1(resultp1,resultp2);
  147. }
  148. /* check for inexact */
  149. if (Dbl_isnotzero(srcp1,srcp2)) {
  150. if (!even_exponent && Dbl_islessthan(resultp1,resultp2,srcp1,srcp2)) {
  151. Dbl_increment(resultp1,resultp2);
  152. }
  153. guardbit = Dbl_lowmantissap2(resultp2);
  154. Dbl_rightshiftby1(resultp1,resultp2);
  155. /*  now round result  */
  156. switch (Rounding_mode()) {
  157. case ROUNDPLUS:
  158.      Dbl_increment(resultp1,resultp2);
  159.      break;
  160. case ROUNDNEAREST:
  161.      /* stickybit is always true, so guardbit 
  162.       * is enough to determine rounding */
  163.      if (guardbit) {
  164.     Dbl_increment(resultp1,resultp2);
  165.      }
  166.      break;
  167. }
  168. /* increment result exponent by 1 if mantissa overflowed */
  169. if (Dbl_isone_hiddenoverflow(resultp1)) src_exponent+=2;
  170. if (Is_inexacttrap_enabled()) {
  171. Dbl_set_exponent(resultp1,
  172.  ((src_exponent-DBL_BIAS)>>1)+DBL_BIAS);
  173. Dbl_copytoptr(resultp1,resultp2,dstptr);
  174. return(INEXACTEXCEPTION);
  175. }
  176. else Set_inexactflag();
  177. }
  178. else {
  179. Dbl_rightshiftby1(resultp1,resultp2);
  180. }
  181. Dbl_set_exponent(resultp1,((src_exponent-DBL_BIAS)>>1)+DBL_BIAS);
  182. Dbl_copytoptr(resultp1,resultp2,dstptr);
  183. return(NOEXCEPTION);
  184. }