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

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/fcnvxf.c $Revision: 1.1 $
  26.  *
  27.  *  Purpose:
  28.  * Single Fixed-point to Single Floating-point
  29.  * Single Fixed-point to Double Floating-point 
  30.  * Double Fixed-point to Single Floating-point 
  31.  * Double Fixed-point to Double Floating-point 
  32.  *
  33.  *  External Interfaces:
  34.  * dbl_to_dbl_fcnvxf(srcptr,nullptr,dstptr,status)
  35.  * dbl_to_sgl_fcnvxf(srcptr,nullptr,dstptr,status)
  36.  * sgl_to_dbl_fcnvxf(srcptr,nullptr,dstptr,status)
  37.  * sgl_to_sgl_fcnvxf(srcptr,nullptr,dstptr,status)
  38.  *
  39.  *  Internal Interfaces:
  40.  *
  41.  *  Theory:
  42.  * <<please update with a overview of the operation of this file>>
  43.  *
  44.  * END_DESC
  45. */
  46. #include "float.h"
  47. #include "sgl_float.h"
  48. #include "dbl_float.h"
  49. #include "cnv_float.h"
  50. /*
  51.  *  Convert single fixed-point to single floating-point format
  52.  */
  53. int
  54. sgl_to_sgl_fcnvxf(
  55.     int *srcptr,
  56.     unsigned int *nullptr,
  57.     sgl_floating_point *dstptr,
  58.     unsigned int *status)
  59. {
  60. register int src, dst_exponent;
  61. register unsigned int result = 0;
  62. src = *srcptr;
  63. /* 
  64.  * set sign bit of result and get magnitude of source 
  65.  */
  66. if (src < 0) {
  67. Sgl_setone_sign(result);  
  68. Int_negate(src);
  69. }
  70. else {
  71. Sgl_setzero_sign(result);
  72.          /* Check for zero */ 
  73.          if (src == 0) { 
  74.                  Sgl_setzero(result); 
  75. *dstptr = result;
  76.                  return(NOEXCEPTION); 
  77.          } 
  78. }
  79. /*
  80.  * Generate exponent and normalized mantissa
  81.  */
  82. dst_exponent = 16;    /* initialize for normalization */
  83. /*
  84.  * Check word for most significant bit set.  Returns
  85.  * a value in dst_exponent indicating the bit position,
  86.  * between -1 and 30.
  87.  */
  88. Find_ms_one_bit(src,dst_exponent);
  89. /*  left justify source, with msb at bit position 1  */
  90. if (dst_exponent >= 0) src <<= dst_exponent;
  91. else src = 1 << 30;
  92. Sgl_set_mantissa(result, src >> (SGL_EXP_LENGTH-1));
  93. Sgl_set_exponent(result, 30+SGL_BIAS - dst_exponent);
  94. /* check for inexact */
  95. if (Int_isinexact_to_sgl(src)) {
  96. switch (Rounding_mode()) {
  97. case ROUNDPLUS: 
  98. if (Sgl_iszero_sign(result)) 
  99. Sgl_increment(result);
  100. break;
  101. case ROUNDMINUS: 
  102. if (Sgl_isone_sign(result)) 
  103. Sgl_increment(result);
  104. break;
  105. case ROUNDNEAREST:
  106. Sgl_roundnearest_from_int(src,result);
  107. }
  108. if (Is_inexacttrap_enabled()) {
  109. *dstptr = result;
  110. return(INEXACTEXCEPTION);
  111. }
  112. else Set_inexactflag();
  113. }
  114. *dstptr = result;
  115. return(NOEXCEPTION);
  116. }
  117. /*
  118.  *  Single Fixed-point to Double Floating-point 
  119.  */
  120. int
  121. sgl_to_dbl_fcnvxf(
  122.     int *srcptr,
  123.     unsigned int *nullptr,
  124.     dbl_floating_point *dstptr,
  125.     unsigned int *status)
  126. {
  127. register int src, dst_exponent;
  128. register unsigned int resultp1 = 0, resultp2 = 0;
  129. src = *srcptr;
  130. /* 
  131.  * set sign bit of result and get magnitude of source 
  132.  */
  133. if (src < 0) {
  134. Dbl_setone_sign(resultp1);  
  135. Int_negate(src);
  136. }
  137. else {
  138. Dbl_setzero_sign(resultp1);
  139.          /* Check for zero */
  140.          if (src == 0) {
  141.                  Dbl_setzero(resultp1,resultp2);
  142.                  Dbl_copytoptr(resultp1,resultp2,dstptr);
  143.                  return(NOEXCEPTION);
  144.          }
  145. }
  146. /*
  147.  * Generate exponent and normalized mantissa
  148.  */
  149. dst_exponent = 16;    /* initialize for normalization */
  150. /*
  151.  * Check word for most significant bit set.  Returns
  152.  * a value in dst_exponent indicating the bit position,
  153.  * between -1 and 30.
  154.  */
  155. Find_ms_one_bit(src,dst_exponent);
  156. /*  left justify source, with msb at bit position 1  */
  157. if (dst_exponent >= 0) src <<= dst_exponent;
  158. else src = 1 << 30;
  159. Dbl_set_mantissap1(resultp1, src >> DBL_EXP_LENGTH - 1);
  160. Dbl_set_mantissap2(resultp2, src << (33-DBL_EXP_LENGTH));
  161. Dbl_set_exponent(resultp1, (30+DBL_BIAS) - dst_exponent);
  162. Dbl_copytoptr(resultp1,resultp2,dstptr);
  163. return(NOEXCEPTION);
  164. }
  165. /*
  166.  *  Double Fixed-point to Single Floating-point 
  167.  */
  168. int
  169. dbl_to_sgl_fcnvxf(
  170. dbl_integer *srcptr,
  171. unsigned int *nullptr,
  172. sgl_floating_point *dstptr,
  173. unsigned int *status)
  174. {
  175. int dst_exponent, srcp1;
  176. unsigned int result = 0, srcp2;
  177. Dint_copyfromptr(srcptr,srcp1,srcp2);
  178. /* 
  179.  * set sign bit of result and get magnitude of source 
  180.  */
  181. if (srcp1 < 0) {
  182. Sgl_setone_sign(result);  
  183. Dint_negate(srcp1,srcp2);
  184. }
  185. else {
  186. Sgl_setzero_sign(result);
  187.          /* Check for zero */
  188.          if (srcp1 == 0 && srcp2 == 0) {
  189.                  Sgl_setzero(result);
  190.                  *dstptr = result;
  191.                  return(NOEXCEPTION);
  192. }
  193.         }
  194. /*
  195.  * Generate exponent and normalized mantissa
  196.  */
  197. dst_exponent = 16;    /* initialize for normalization */
  198. if (srcp1 == 0) {
  199. /*
  200.  * Check word for most significant bit set.  Returns
  201.  * a value in dst_exponent indicating the bit position,
  202.  * between -1 and 30.
  203.  */
  204. Find_ms_one_bit(srcp2,dst_exponent);
  205. /*  left justify source, with msb at bit position 1  */
  206. if (dst_exponent >= 0) {
  207. srcp1 = srcp2 << dst_exponent;    
  208. srcp2 = 0;
  209. }
  210. else {
  211. srcp1 = srcp2 >> 1;
  212. srcp2 <<= 31; 
  213. }
  214. /*
  215.  *  since msb set is in second word, need to 
  216.  *  adjust bit position count
  217.  */
  218. dst_exponent += 32;
  219. }
  220. else {
  221. /*
  222.  * Check word for most significant bit set.  Returns
  223.  * a value in dst_exponent indicating the bit position,
  224.  * between -1 and 30.
  225.  *
  226.  */
  227. Find_ms_one_bit(srcp1,dst_exponent);
  228. /*  left justify source, with msb at bit position 1  */
  229. if (dst_exponent > 0) {
  230. Variable_shift_double(srcp1,srcp2,(32-dst_exponent),
  231.  srcp1); 
  232. srcp2 <<= dst_exponent;
  233. }
  234. /*
  235.  * If dst_exponent = 0, we don't need to shift anything.
  236.  * If dst_exponent = -1, src = - 2**63 so we won't need to 
  237.  * shift srcp2.
  238.  */
  239. else srcp1 >>= -(dst_exponent);
  240. }
  241. Sgl_set_mantissa(result, srcp1 >> SGL_EXP_LENGTH - 1);
  242. Sgl_set_exponent(result, (62+SGL_BIAS) - dst_exponent);
  243. /* check for inexact */
  244. if (Dint_isinexact_to_sgl(srcp1,srcp2)) {
  245. switch (Rounding_mode()) {
  246. case ROUNDPLUS: 
  247. if (Sgl_iszero_sign(result)) 
  248. Sgl_increment(result);
  249. break;
  250. case ROUNDMINUS: 
  251. if (Sgl_isone_sign(result)) 
  252. Sgl_increment(result);
  253. break;
  254. case ROUNDNEAREST:
  255. Sgl_roundnearest_from_dint(srcp1,srcp2,result);
  256. }
  257. if (Is_inexacttrap_enabled()) {
  258. *dstptr = result;
  259. return(INEXACTEXCEPTION);
  260. }
  261. else Set_inexactflag();
  262. }
  263. *dstptr = result;
  264. return(NOEXCEPTION);
  265. }
  266. /*
  267.  *  Double Fixed-point to Double Floating-point 
  268.  */
  269. int
  270. dbl_to_dbl_fcnvxf(
  271.     dbl_integer *srcptr,
  272.     unsigned int *nullptr,
  273.     dbl_floating_point *dstptr,
  274.     unsigned int *status)
  275. {
  276. register int srcp1, dst_exponent;
  277. register unsigned int srcp2, resultp1 = 0, resultp2 = 0;
  278. Dint_copyfromptr(srcptr,srcp1,srcp2);
  279. /* 
  280.  * set sign bit of result and get magnitude of source 
  281.  */
  282. if (srcp1 < 0) {
  283. Dbl_setone_sign(resultp1);
  284. Dint_negate(srcp1,srcp2);
  285. }
  286. else {
  287. Dbl_setzero_sign(resultp1);
  288.          /* Check for zero */
  289.          if (srcp1 == 0 && srcp2 ==0) {
  290.                  Dbl_setzero(resultp1,resultp2);
  291.                  Dbl_copytoptr(resultp1,resultp2,dstptr);
  292.                  return(NOEXCEPTION);
  293. }
  294.         }
  295. /*
  296.  * Generate exponent and normalized mantissa
  297.  */
  298. dst_exponent = 16;    /* initialize for normalization */
  299. if (srcp1 == 0) {
  300. /*
  301.  * Check word for most significant bit set.  Returns
  302.  * a value in dst_exponent indicating the bit position,
  303.  * between -1 and 30.
  304.  */
  305. Find_ms_one_bit(srcp2,dst_exponent);
  306. /*  left justify source, with msb at bit position 1  */
  307. if (dst_exponent >= 0) {
  308. srcp1 = srcp2 << dst_exponent;    
  309. srcp2 = 0;
  310. }
  311. else {
  312. srcp1 = srcp2 >> 1;
  313. srcp2 <<= 31;
  314. }
  315. /*
  316.  *  since msb set is in second word, need to 
  317.  *  adjust bit position count
  318.  */
  319. dst_exponent += 32;
  320. }
  321. else {
  322. /*
  323.  * Check word for most significant bit set.  Returns
  324.  * a value in dst_exponent indicating the bit position,
  325.  * between -1 and 30.
  326.  */
  327. Find_ms_one_bit(srcp1,dst_exponent);
  328. /*  left justify source, with msb at bit position 1  */
  329. if (dst_exponent > 0) {
  330. Variable_shift_double(srcp1,srcp2,(32-dst_exponent),
  331.  srcp1); 
  332. srcp2 <<= dst_exponent;
  333. }
  334. /*
  335.  * If dst_exponent = 0, we don't need to shift anything.
  336.  * If dst_exponent = -1, src = - 2**63 so we won't need to 
  337.  * shift srcp2.
  338.  */
  339. else srcp1 >>= -(dst_exponent);
  340. }
  341. Dbl_set_mantissap1(resultp1, srcp1 >> (DBL_EXP_LENGTH-1));
  342. Shiftdouble(srcp1,srcp2,DBL_EXP_LENGTH-1,resultp2);
  343. Dbl_set_exponent(resultp1, (62+DBL_BIAS) - dst_exponent);
  344. /* check for inexact */
  345. if (Dint_isinexact_to_dbl(srcp2)) {
  346. switch (Rounding_mode()) {
  347. case ROUNDPLUS: 
  348. if (Dbl_iszero_sign(resultp1)) {
  349. Dbl_increment(resultp1,resultp2);
  350. }
  351. break;
  352. case ROUNDMINUS: 
  353. if (Dbl_isone_sign(resultp1)) {
  354. Dbl_increment(resultp1,resultp2);
  355. }
  356. break;
  357. case ROUNDNEAREST:
  358. Dbl_roundnearest_from_dint(srcp2,resultp1,
  359. resultp2);
  360. }
  361. if (Is_inexacttrap_enabled()) {
  362. Dbl_copytoptr(resultp1,resultp2,dstptr);
  363. return(INEXACTEXCEPTION);
  364. }
  365. else Set_inexactflag();
  366. }
  367. Dbl_copytoptr(resultp1,resultp2,dstptr);
  368. return(NOEXCEPTION);
  369. }