1 /* $NetBSD: fcnvfxt.c,v 1.1 2002/06/05 01:04:25 fredette Exp $ */ 2 3 /* $OpenBSD: fcnvfxt.c,v 1.5 2001/03/29 03:58:18 mickey Exp $ */ 4 5 /* 6 * Copyright 1996 1995 by Open Software Foundation, Inc. 7 * All Rights Reserved 8 * 9 * Permission to use, copy, modify, and distribute this software and 10 * its documentation for any purpose and without fee is hereby granted, 11 * provided that the above copyright notice appears in all copies and 12 * that both the copyright notice and this permission notice appear in 13 * supporting documentation. 14 * 15 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 17 * FOR A PARTICULAR PURPOSE. 18 * 19 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 21 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 22 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 23 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 24 * 25 */ 26 /* 27 * pmk1.1 28 */ 29 /* 30 * (c) Copyright 1986 HEWLETT-PACKARD COMPANY 31 * 32 * To anyone who acknowledges that this file is provided "AS IS" 33 * without any express or implied warranty: 34 * permission to use, copy, modify, and distribute this file 35 * for any purpose is hereby granted without fee, provided that 36 * the above copyright notice and this notice appears in all 37 * copies, and that the name of Hewlett-Packard Company not be 38 * used in advertising or publicity pertaining to distribution 39 * of the software without specific, written prior permission. 40 * Hewlett-Packard Company makes no representations about the 41 * suitability of this software for any purpose. 42 */ 43 44 #include "../spmath/float.h" 45 #include "../spmath/sgl_float.h" 46 #include "../spmath/dbl_float.h" 47 #include "../spmath/cnv_float.h" 48 49 /* 50 * Convert single floating-point to single fixed-point format 51 * with truncated result 52 */ 53 /*ARGSUSED*/ 54 int 55 sgl_to_sgl_fcnvfxt(srcptr,dstptr,status) 56 57 sgl_floating_point *srcptr; 58 int *dstptr; 59 unsigned int *status; 60 { 61 register unsigned int src, temp; 62 register int src_exponent, result; 63 64 src = *srcptr; 65 src_exponent = Sgl_exponent(src) - SGL_BIAS; 66 67 /* 68 * Test for overflow 69 */ 70 if (src_exponent > SGL_FX_MAX_EXP) { 71 /* check for MININT */ 72 if ((src_exponent > SGL_FX_MAX_EXP + 1) || 73 Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) { 74 /* 75 * Since source is a number which cannot be 76 * represented in fixed-point format, return 77 * largest (or smallest) fixed-point number. 78 */ 79 Sgl_return_overflow(src,dstptr); 80 } 81 } 82 /* 83 * Generate result 84 */ 85 if (src_exponent >= 0) { 86 temp = src; 87 Sgl_clear_signexponent_set_hidden(temp); 88 Int_from_sgl_mantissa(temp,src_exponent); 89 if (Sgl_isone_sign(src)) result = -Sgl_all(temp); 90 else result = Sgl_all(temp); 91 *dstptr = result; 92 93 /* check for inexact */ 94 if (Sgl_isinexact_to_fix(src,src_exponent)) { 95 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 96 else Set_inexactflag(); 97 } 98 } 99 else { 100 *dstptr = 0; 101 102 /* check for inexact */ 103 if (Sgl_isnotzero_exponentmantissa(src)) { 104 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 105 else Set_inexactflag(); 106 } 107 } 108 return(NOEXCEPTION); 109 } 110 111 /* 112 * Single Floating-point to Double Fixed-point 113 */ 114 /*ARGSUSED*/ 115 int 116 sgl_to_dbl_fcnvfxt(srcptr,dstptr,status) 117 118 sgl_floating_point *srcptr; 119 dbl_integer *dstptr; 120 unsigned int *status; 121 { 122 register int src_exponent, resultp1; 123 register unsigned int src, temp, resultp2; 124 125 src = *srcptr; 126 src_exponent = Sgl_exponent(src) - SGL_BIAS; 127 128 /* 129 * Test for overflow 130 */ 131 if (src_exponent > DBL_FX_MAX_EXP) { 132 /* check for MININT */ 133 if ((src_exponent > DBL_FX_MAX_EXP + 1) || 134 Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) { 135 /* 136 * Since source is a number which cannot be 137 * represented in fixed-point format, return 138 * largest (or smallest) fixed-point number. 139 */ 140 Sgl_return_overflow_dbl(src,dstptr); 141 } 142 Dint_set_minint(resultp1,resultp2); 143 Dint_copytoptr(resultp1,resultp2,dstptr); 144 return(NOEXCEPTION); 145 } 146 /* 147 * Generate result 148 */ 149 if (src_exponent >= 0) { 150 temp = src; 151 Sgl_clear_signexponent_set_hidden(temp); 152 Dint_from_sgl_mantissa(temp,src_exponent,resultp1,resultp2); 153 if (Sgl_isone_sign(src)) { 154 Dint_setone_sign(resultp1,resultp2); 155 } 156 Dint_copytoptr(resultp1,resultp2,dstptr); 157 158 /* check for inexact */ 159 if (Sgl_isinexact_to_fix(src,src_exponent)) { 160 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 161 else Set_inexactflag(); 162 } 163 } 164 else { 165 Dint_setzero(resultp1,resultp2); 166 Dint_copytoptr(resultp1,resultp2,dstptr); 167 168 /* check for inexact */ 169 if (Sgl_isnotzero_exponentmantissa(src)) { 170 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 171 else Set_inexactflag(); 172 } 173 } 174 return(NOEXCEPTION); 175 } 176 177 /* 178 * Double Floating-point to Single Fixed-point 179 */ 180 /*ARGSUSED*/ 181 int 182 dbl_to_sgl_fcnvfxt(srcptr,dstptr,status) 183 184 dbl_floating_point *srcptr; 185 int *dstptr; 186 unsigned int *status; 187 { 188 register unsigned int srcp1, srcp2, tempp1, tempp2; 189 register int src_exponent, result; 190 191 Dbl_copyfromptr(srcptr,srcp1,srcp2); 192 src_exponent = Dbl_exponent(srcp1) - DBL_BIAS; 193 194 /* 195 * Test for overflow 196 */ 197 if (src_exponent > SGL_FX_MAX_EXP) { 198 /* check for MININT */ 199 if (Dbl_isoverflow_to_int(src_exponent,srcp1,srcp2)) { 200 Dbl_return_overflow(srcp1,srcp2,dstptr); 201 } 202 } 203 /* 204 * Generate result 205 */ 206 if (src_exponent >= 0) { 207 tempp1 = srcp1; 208 tempp2 = srcp2; 209 Dbl_clear_signexponent_set_hidden(tempp1); 210 Int_from_dbl_mantissa(tempp1,tempp2,src_exponent); 211 if (Dbl_isone_sign(srcp1) && (src_exponent <= SGL_FX_MAX_EXP)) 212 result = -Dbl_allp1(tempp1); 213 else result = Dbl_allp1(tempp1); 214 *dstptr = result; 215 216 /* check for inexact */ 217 if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) { 218 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 219 else Set_inexactflag(); 220 } 221 } 222 else { 223 *dstptr = 0; 224 225 /* check for inexact */ 226 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) { 227 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 228 else Set_inexactflag(); 229 } 230 } 231 return(NOEXCEPTION); 232 } 233 234 /* 235 * Double Floating-point to Double Fixed-point 236 */ 237 /*ARGSUSED*/ 238 int 239 dbl_to_dbl_fcnvfxt(srcptr,dstptr,status) 240 241 dbl_floating_point *srcptr; 242 dbl_integer *dstptr; 243 unsigned int *status; 244 { 245 register int src_exponent, resultp1; 246 register unsigned int srcp1, srcp2, tempp1, tempp2, resultp2; 247 248 Dbl_copyfromptr(srcptr,srcp1,srcp2); 249 src_exponent = Dbl_exponent(srcp1) - DBL_BIAS; 250 251 /* 252 * Test for overflow 253 */ 254 if (src_exponent > DBL_FX_MAX_EXP) { 255 /* check for MININT */ 256 if ((src_exponent > DBL_FX_MAX_EXP + 1) || 257 Dbl_isnotzero_mantissa(srcp1,srcp2) || Dbl_iszero_sign(srcp1)) { 258 /* 259 * Since source is a number which cannot be 260 * represented in fixed-point format, return 261 * largest (or smallest) fixed-point number. 262 */ 263 Dbl_return_overflow_dbl(srcp1,srcp2,dstptr); 264 } 265 } 266 /* 267 * Generate result 268 */ 269 if (src_exponent >= 0) { 270 tempp1 = srcp1; 271 tempp2 = srcp2; 272 Dbl_clear_signexponent_set_hidden(tempp1); 273 Dint_from_dbl_mantissa(tempp1,tempp2,src_exponent, 274 resultp1,resultp2); 275 if (Dbl_isone_sign(srcp1)) { 276 Dint_setone_sign(resultp1,resultp2); 277 } 278 Dint_copytoptr(resultp1,resultp2,dstptr); 279 280 /* check for inexact */ 281 if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) { 282 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 283 else Set_inexactflag(); 284 } 285 } 286 else { 287 Dint_setzero(resultp1,resultp2); 288 Dint_copytoptr(resultp1,resultp2,dstptr); 289 290 /* check for inexact */ 291 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) { 292 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 293 else Set_inexactflag(); 294 } 295 } 296 return(NOEXCEPTION); 297 } 298