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

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/fcnvff.c $Revision: 1.1 $
  26.  *
  27.  *  Purpose:
  28.  * Single Floating-point to Double Floating-point
  29.  * Double Floating-point to Single Floating-point
  30.  *
  31.  *  External Interfaces:
  32.  * dbl_to_sgl_fcnvff(srcptr,nullptr,dstptr,status)
  33.  * sgl_to_dbl_fcnvff(srcptr,nullptr,dstptr,status)
  34.  *
  35.  *  Internal Interfaces:
  36.  *
  37.  *  Theory:
  38.  * <<please update with a overview of the operation of this file>>
  39.  *
  40.  * END_DESC
  41. */
  42. #include "float.h"
  43. #include "sgl_float.h"
  44. #include "dbl_float.h"
  45. #include "cnv_float.h"
  46. /*
  47.  *  Single Floating-point to Double Floating-point 
  48.  */
  49. /*ARGSUSED*/
  50. int
  51. sgl_to_dbl_fcnvff(
  52.     sgl_floating_point *srcptr,
  53.     unsigned int *nullptr,
  54.     dbl_floating_point *dstptr,
  55.     unsigned int *status)
  56. {
  57. register unsigned int src, resultp1, resultp2;
  58. register int src_exponent;
  59. src = *srcptr;
  60. src_exponent = Sgl_exponent(src);
  61. Dbl_allp1(resultp1) = Sgl_all(src);  /* set sign of result */
  62. /* 
  63.    * Test for NaN or infinity
  64.    */
  65. if (src_exponent == SGL_INFINITY_EXPONENT) {
  66. /*
  67.  * determine if NaN or infinity
  68.  */
  69. if (Sgl_iszero_mantissa(src)) {
  70. /*
  71.  * is infinity; want to return double infinity
  72.  */
  73. Dbl_setinfinity_exponentmantissa(resultp1,resultp2);
  74. Dbl_copytoptr(resultp1,resultp2,dstptr);
  75. return(NOEXCEPTION);
  76. }
  77. else {
  78. /* 
  79.  * is NaN; signaling or quiet?
  80.  */
  81. if (Sgl_isone_signaling(src)) {
  82. /* trap if INVALIDTRAP enabled */
  83. if (Is_invalidtrap_enabled())
  84. return(INVALIDEXCEPTION);
  85. /* make NaN quiet */
  86. else {
  87. Set_invalidflag();
  88. Sgl_set_quiet(src);
  89. }
  90. }
  91. /* 
  92.  * NaN is quiet, return as double NaN 
  93.  */
  94. Dbl_setinfinity_exponent(resultp1);
  95. Sgl_to_dbl_mantissa(src,resultp1,resultp2);
  96. Dbl_copytoptr(resultp1,resultp2,dstptr);
  97. return(NOEXCEPTION);
  98. }
  99. }
  100. /* 
  101.    * Test for zero or denormalized
  102.    */
  103. if (src_exponent == 0) {
  104. /*
  105.  * determine if zero or denormalized
  106.  */
  107. if (Sgl_isnotzero_mantissa(src)) {
  108. /*
  109.  * is denormalized; want to normalize
  110.  */
  111. Sgl_clear_signexponent(src);
  112. Sgl_leftshiftby1(src);
  113. Sgl_normalize(src,src_exponent);
  114. Sgl_to_dbl_exponent(src_exponent,resultp1);
  115. Sgl_to_dbl_mantissa(src,resultp1,resultp2);
  116. }
  117. else {
  118. Dbl_setzero_exponentmantissa(resultp1,resultp2);
  119. }
  120. Dbl_copytoptr(resultp1,resultp2,dstptr);
  121. return(NOEXCEPTION);
  122. }
  123. /*
  124.  * No special cases, just complete the conversion
  125.  */
  126. Sgl_to_dbl_exponent(src_exponent, resultp1);
  127. Sgl_to_dbl_mantissa(Sgl_mantissa(src), resultp1,resultp2);
  128. Dbl_copytoptr(resultp1,resultp2,dstptr);
  129. return(NOEXCEPTION);
  130. }
  131. /*
  132.  *  Double Floating-point to Single Floating-point 
  133.  */
  134. /*ARGSUSED*/
  135. int
  136. dbl_to_sgl_fcnvff(
  137.     dbl_floating_point *srcptr,
  138.     unsigned int *nullptr,
  139.     sgl_floating_point *dstptr,
  140.     unsigned int *status)
  141. {
  142.         register unsigned int srcp1, srcp2, result;
  143.         register int src_exponent, dest_exponent, dest_mantissa;
  144.         register boolean inexact = FALSE, guardbit = FALSE, stickybit = FALSE;
  145. register boolean lsb_odd = FALSE;
  146. boolean is_tiny;
  147. Dbl_copyfromptr(srcptr,srcp1,srcp2);
  148.         src_exponent = Dbl_exponent(srcp1);
  149. Sgl_all(result) = Dbl_allp1(srcp1);  /* set sign of result */
  150.         /* 
  151.          * Test for NaN or infinity
  152.          */
  153.         if (src_exponent == DBL_INFINITY_EXPONENT) {
  154.                 /*
  155.                  * determine if NaN or infinity
  156.                  */
  157.                 if (Dbl_iszero_mantissa(srcp1,srcp2)) {
  158.                         /*
  159.                          * is infinity; want to return single infinity
  160.                          */
  161.                         Sgl_setinfinity_exponentmantissa(result);
  162.                         *dstptr = result;
  163.                         return(NOEXCEPTION);
  164.                 }
  165.                 /* 
  166.                  * is NaN; signaling or quiet?
  167.                  */
  168.                 if (Dbl_isone_signaling(srcp1)) {
  169.                         /* trap if INVALIDTRAP enabled */
  170.                         if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
  171.                         else {
  172. Set_invalidflag();
  173.                          /* make NaN quiet */
  174.                          Dbl_set_quiet(srcp1);
  175. }
  176.                 }
  177.                 /* 
  178.                  * NaN is quiet, return as single NaN 
  179.                  */
  180.                 Sgl_setinfinity_exponent(result);
  181. Sgl_set_mantissa(result,Dallp1(srcp1)<<3 | Dallp2(srcp2)>>29);
  182. if (Sgl_iszero_mantissa(result)) Sgl_set_quiet(result);
  183.                 *dstptr = result;
  184.                 return(NOEXCEPTION);
  185.         }
  186.         /*
  187.          * Generate result
  188.          */
  189.         Dbl_to_sgl_exponent(src_exponent,dest_exponent);
  190. if (dest_exponent > 0) {
  191.          Dbl_to_sgl_mantissa(srcp1,srcp2,dest_mantissa,inexact,guardbit, 
  192. stickybit,lsb_odd);
  193. }
  194. else {
  195. if (Dbl_iszero_exponentmantissa(srcp1,srcp2)){
  196. Sgl_setzero_exponentmantissa(result);
  197. *dstptr = result;
  198. return(NOEXCEPTION);
  199. }
  200.                 if (Is_underflowtrap_enabled()) {
  201. Dbl_to_sgl_mantissa(srcp1,srcp2,dest_mantissa,inexact,
  202. guardbit,stickybit,lsb_odd);
  203.                 }
  204. else {
  205. /* compute result, determine inexact info,
  206.  * and set Underflowflag if appropriate
  207.  */
  208. Dbl_to_sgl_denormalized(srcp1,srcp2,dest_exponent,
  209. dest_mantissa,inexact,guardbit,stickybit,lsb_odd,
  210. is_tiny);
  211. }
  212. }
  213.         /* 
  214.          * Now round result if not exact
  215.          */
  216.         if (inexact) {
  217.                 switch (Rounding_mode()) {
  218.                         case ROUNDPLUS: 
  219.                                 if (Sgl_iszero_sign(result)) dest_mantissa++;
  220.                                 break;
  221.                         case ROUNDMINUS: 
  222.                                 if (Sgl_isone_sign(result)) dest_mantissa++;
  223.                                 break;
  224.                         case ROUNDNEAREST:
  225.                                 if (guardbit) {
  226.                                    if (stickybit || lsb_odd) dest_mantissa++;
  227.                                    }
  228.                 }
  229.         }
  230.         Sgl_set_exponentmantissa(result,dest_mantissa);
  231.         /*
  232.          * check for mantissa overflow after rounding
  233.          */
  234.         if ((dest_exponent>0 || Is_underflowtrap_enabled()) && 
  235.     Sgl_isone_hidden(result)) dest_exponent++;
  236.         /* 
  237.          * Test for overflow
  238.          */
  239.         if (dest_exponent >= SGL_INFINITY_EXPONENT) {
  240.                 /* trap if OVERFLOWTRAP enabled */
  241.                 if (Is_overflowtrap_enabled()) {
  242.                         /* 
  243.                          * Check for gross overflow
  244.                          */
  245.                         if (dest_exponent >= SGL_INFINITY_EXPONENT+SGL_WRAP) 
  246.                          return(UNIMPLEMENTEDEXCEPTION);
  247.                         
  248.                         /*
  249.                          * Adjust bias of result
  250.                          */
  251. Sgl_setwrapped_exponent(result,dest_exponent,ovfl);
  252. *dstptr = result;
  253. if (inexact) 
  254.     if (Is_inexacttrap_enabled())
  255. return(OVERFLOWEXCEPTION|INEXACTEXCEPTION);
  256.     else Set_inexactflag();
  257.                         return(OVERFLOWEXCEPTION);
  258.                 }
  259.                 Set_overflowflag();
  260. inexact = TRUE;
  261. /* set result to infinity or largest number */
  262. Sgl_setoverflow(result);
  263.         }
  264.         /* 
  265.          * Test for underflow
  266.          */
  267.         else if (dest_exponent <= 0) {
  268.                 /* trap if UNDERFLOWTRAP enabled */
  269.                 if (Is_underflowtrap_enabled()) {
  270.                         /* 
  271.                          * Check for gross underflow
  272.                          */
  273.                         if (dest_exponent <= -(SGL_WRAP))
  274.                          return(UNIMPLEMENTEDEXCEPTION);
  275.                         /*
  276.                          * Adjust bias of result
  277.                          */
  278. Sgl_setwrapped_exponent(result,dest_exponent,unfl);
  279. *dstptr = result;
  280. if (inexact) 
  281.     if (Is_inexacttrap_enabled())
  282. return(UNDERFLOWEXCEPTION|INEXACTEXCEPTION);
  283.     else Set_inexactflag();
  284.                         return(UNDERFLOWEXCEPTION);
  285.                 }
  286.                  /* 
  287.                   * result is denormalized or signed zero
  288.                   */
  289.                if (inexact && is_tiny) Set_underflowflag();
  290.         }
  291. else Sgl_set_exponent(result,dest_exponent);
  292. *dstptr = result;
  293.         /* 
  294.          * Trap if inexact trap is enabled
  295.          */
  296.         if (inexact)
  297.          if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
  298.          else Set_inexactflag();
  299.         return(NOEXCEPTION);
  300. }