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

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.  *  Purpose:
  25.  * Single Floating-point Round to Integer
  26.  * Double Floating-point Round to Integer
  27.  * Quad Floating-point Round to Integer (returns unimplemented)
  28.  *
  29.  *  External Interfaces:
  30.  * dbl_frnd(srcptr,nullptr,dstptr,status)
  31.  * sgl_frnd(srcptr,nullptr,dstptr,status)
  32.  *
  33.  * END_DESC
  34. */
  35. #include "float.h"
  36. #include "sgl_float.h"
  37. #include "dbl_float.h"
  38. #include "cnv_float.h"
  39. /*
  40.  *  Single Floating-point Round to Integer
  41.  */
  42. /*ARGSUSED*/
  43. int
  44. sgl_frnd(sgl_floating_point *srcptr,
  45. unsigned int *nullptr,
  46. sgl_floating_point *dstptr,
  47. unsigned int *status)
  48. {
  49. register unsigned int src, result;
  50. register int src_exponent;
  51. register boolean inexact = FALSE;
  52. src = *srcptr;
  53.         /*
  54.          * check source operand for NaN or infinity
  55.          */
  56.         if ((src_exponent = Sgl_exponent(src)) == SGL_INFINITY_EXPONENT) {
  57.                 /*
  58.                  * is signaling NaN?
  59.                  */
  60.                 if (Sgl_isone_signaling(src)) {
  61.                         /* trap if INVALIDTRAP enabled */
  62.                         if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
  63.                         /* make NaN quiet */
  64.                         Set_invalidflag();
  65.                         Sgl_set_quiet(src);
  66.                 }
  67.                 /*
  68.                  * return quiet NaN or infinity
  69.                  */
  70.                 *dstptr = src;
  71.                 return(NOEXCEPTION);
  72.         }
  73. /* 
  74.  * Need to round?
  75.  */
  76. if ((src_exponent -= SGL_BIAS) >= SGL_P - 1) {
  77. *dstptr = src;
  78. return(NOEXCEPTION);
  79. }
  80. /*
  81.  * Generate result
  82.  */
  83. if (src_exponent >= 0) {
  84. Sgl_clear_exponent_set_hidden(src);
  85. result = src;
  86. Sgl_rightshift(result,(SGL_P-1) - (src_exponent));
  87. /* check for inexact */
  88. if (Sgl_isinexact_to_fix(src,src_exponent)) {
  89. inexact = TRUE;
  90. /*  round result  */
  91. switch (Rounding_mode()) {
  92. case ROUNDPLUS:
  93.      if (Sgl_iszero_sign(src)) Sgl_increment(result);
  94.      break;
  95. case ROUNDMINUS:
  96.      if (Sgl_isone_sign(src)) Sgl_increment(result);
  97.      break;
  98. case ROUNDNEAREST:
  99.      if (Sgl_isone_roundbit(src,src_exponent))
  100.         if (Sgl_isone_stickybit(src,src_exponent) 
  101. || (Sgl_isone_lowmantissa(result))) 
  102. Sgl_increment(result);
  103. }
  104. Sgl_leftshift(result,(SGL_P-1) - (src_exponent));
  105. if (Sgl_isone_hiddenoverflow(result)) 
  106. Sgl_set_exponent(result,src_exponent + (SGL_BIAS+1));
  107. else Sgl_set_exponent(result,src_exponent + SGL_BIAS);
  108. }
  109. else {
  110. result = src;   /* set sign */
  111. Sgl_setzero_exponentmantissa(result);
  112. /* check for inexact */
  113. if (Sgl_isnotzero_exponentmantissa(src)) {
  114. inexact = TRUE;
  115. /*  round result  */
  116. switch (Rounding_mode()) {
  117. case ROUNDPLUS:
  118.      if (Sgl_iszero_sign(src)) 
  119. Sgl_set_exponent(result,SGL_BIAS);
  120.      break;
  121. case ROUNDMINUS:
  122.      if (Sgl_isone_sign(src)) 
  123. Sgl_set_exponent(result,SGL_BIAS);
  124.      break;
  125. case ROUNDNEAREST:
  126.      if (src_exponent == -1)
  127.         if (Sgl_isnotzero_mantissa(src))
  128.    Sgl_set_exponent(result,SGL_BIAS);
  129. }
  130. }
  131. *dstptr = result;
  132. if (inexact) {
  133. if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
  134. else Set_inexactflag();
  135. }
  136. return(NOEXCEPTION);
  137. /*
  138.  *  Double Floating-point Round to Integer
  139.  */
  140. /*ARGSUSED*/
  141. int
  142. dbl_frnd(
  143. dbl_floating_point *srcptr,
  144. unsigned int *nullptr,
  145. dbl_floating_point *dstptr,
  146. unsigned int *status)
  147. {
  148. register unsigned int srcp1, srcp2, resultp1, resultp2;
  149. register int src_exponent;
  150. register boolean inexact = FALSE;
  151. Dbl_copyfromptr(srcptr,srcp1,srcp2);
  152.         /*
  153.          * check source operand for NaN or infinity
  154.          */
  155.         if ((src_exponent = Dbl_exponent(srcp1)) == DBL_INFINITY_EXPONENT) {
  156.                 /*
  157.                  * is signaling NaN?
  158.                  */
  159.                 if (Dbl_isone_signaling(srcp1)) {
  160.                         /* trap if INVALIDTRAP enabled */
  161.                         if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
  162.                         /* make NaN quiet */
  163.                         Set_invalidflag();
  164.                         Dbl_set_quiet(srcp1);
  165.                 }
  166.                 /*
  167.                  * return quiet NaN or infinity
  168.                  */
  169.                 Dbl_copytoptr(srcp1,srcp2,dstptr);
  170.                 return(NOEXCEPTION);
  171.         }
  172. /* 
  173.  * Need to round?
  174.  */
  175. if ((src_exponent -= DBL_BIAS) >= DBL_P - 1) {
  176. Dbl_copytoptr(srcp1,srcp2,dstptr);
  177. return(NOEXCEPTION);
  178. }
  179. /*
  180.  * Generate result
  181.  */
  182. if (src_exponent >= 0) {
  183. Dbl_clear_exponent_set_hidden(srcp1);
  184. resultp1 = srcp1;
  185. resultp2 = srcp2;
  186. Dbl_rightshift(resultp1,resultp2,(DBL_P-1) - (src_exponent));
  187. /* check for inexact */
  188. if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
  189. inexact = TRUE;
  190. /*  round result  */
  191. switch (Rounding_mode()) {
  192. case ROUNDPLUS:
  193.      if (Dbl_iszero_sign(srcp1)) 
  194. Dbl_increment(resultp1,resultp2);
  195.      break;
  196. case ROUNDMINUS:
  197.      if (Dbl_isone_sign(srcp1)) 
  198. Dbl_increment(resultp1,resultp2);
  199.      break;
  200. case ROUNDNEAREST:
  201.      if (Dbl_isone_roundbit(srcp1,srcp2,src_exponent))
  202.       if (Dbl_isone_stickybit(srcp1,srcp2,src_exponent) 
  203.   || (Dbl_isone_lowmantissap2(resultp2))) 
  204. Dbl_increment(resultp1,resultp2);
  205. }
  206. Dbl_leftshift(resultp1,resultp2,(DBL_P-1) - (src_exponent));
  207. if (Dbl_isone_hiddenoverflow(resultp1))
  208. Dbl_set_exponent(resultp1,src_exponent + (DBL_BIAS+1));
  209. else Dbl_set_exponent(resultp1,src_exponent + DBL_BIAS);
  210. }
  211. else {
  212. resultp1 = srcp1;  /* set sign */
  213. Dbl_setzero_exponentmantissa(resultp1,resultp2);
  214. /* check for inexact */
  215. if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
  216. inexact = TRUE;
  217. /*  round result  */
  218. switch (Rounding_mode()) {
  219. case ROUNDPLUS:
  220.      if (Dbl_iszero_sign(srcp1)) 
  221. Dbl_set_exponent(resultp1,DBL_BIAS);
  222.      break;
  223. case ROUNDMINUS:
  224.      if (Dbl_isone_sign(srcp1)) 
  225. Dbl_set_exponent(resultp1,DBL_BIAS);
  226.      break;
  227. case ROUNDNEAREST:
  228.      if (src_exponent == -1)
  229.         if (Dbl_isnotzero_mantissa(srcp1,srcp2))
  230.    Dbl_set_exponent(resultp1,DBL_BIAS);
  231. }
  232. }
  233. Dbl_copytoptr(resultp1,resultp2,dstptr);
  234. if (inexact) {
  235. if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
  236. else Set_inexactflag();
  237. }
  238. return(NOEXCEPTION);
  239. }