1/* $OpenBSD: frnd.c,v 1.9 2023/03/08 04:43:07 guenther Exp $ */ 2/* 3 (c) Copyright 1986 HEWLETT-PACKARD COMPANY 4 To anyone who acknowledges that this file is provided "AS IS" 5 without any express or implied warranty: 6 permission to use, copy, modify, and distribute this file 7 for any purpose is hereby granted without fee, provided that 8 the above copyright notice and this notice appears in all 9 copies, and that the name of Hewlett-Packard Company not be 10 used in advertising or publicity pertaining to distribution 11 of the software without specific, written prior permission. 12 Hewlett-Packard Company makes no representations about the 13 suitability of this software for any purpose. 14*/ 15/* @(#)frnd.c: Revision: 2.7.88.1 Date: 93/12/07 15:06:24 */ 16 17#include "float.h" 18#include "sgl_float.h" 19#include "dbl_float.h" 20#include "quad_float.h" 21#include "cnv_float.h" 22 23/* 24 * Single Floating-point Round to Integer 25 */ 26 27int 28sgl_frnd(srcptr, null, dstptr, status) 29 sgl_floating_point *srcptr, *null, *dstptr; 30 unsigned int *status; 31{ 32 register unsigned int src, result; 33 register int src_exponent; 34 register int inexact = FALSE; 35 36 src = *srcptr; 37 /* 38 * check source operand for NaN or infinity 39 */ 40 if ((src_exponent = Sgl_exponent(src)) == SGL_INFINITY_EXPONENT) { 41 /* 42 * is signaling NaN? 43 */ 44 if (Sgl_isone_signaling(src)) { 45 /* trap if INVALIDTRAP enabled */ 46 if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION); 47 /* make NaN quiet */ 48 Set_invalidflag(); 49 Sgl_set_quiet(src); 50 } 51 /* 52 * return quiet NaN or infinity 53 */ 54 *dstptr = src; 55 return(NOEXCEPTION); 56 } 57 /* 58 * Need to round? 59 */ 60 if ((src_exponent -= SGL_BIAS) >= SGL_P - 1) { 61 *dstptr = src; 62 return(NOEXCEPTION); 63 } 64 /* 65 * Generate result 66 */ 67 if (src_exponent >= 0) { 68 Sgl_clear_exponent_set_hidden(src); 69 result = src; 70 Sgl_rightshift(result,(SGL_P-1) - (src_exponent)); 71 /* check for inexact */ 72 if (Sgl_isinexact_to_fix(src,src_exponent)) { 73 inexact = TRUE; 74 /* round result */ 75 switch (Rounding_mode()) { 76 case ROUNDPLUS: 77 if (Sgl_iszero_sign(src)) Sgl_increment(result); 78 break; 79 case ROUNDMINUS: 80 if (Sgl_isone_sign(src)) Sgl_increment(result); 81 break; 82 case ROUNDNEAREST: 83 if (Sgl_isone_roundbit(src,src_exponent)) 84 if (Sgl_isone_stickybit(src,src_exponent) 85 || (Sgl_isone_lowmantissa(result))) 86 Sgl_increment(result); 87 } 88 } 89 Sgl_leftshift(result,(SGL_P-1) - (src_exponent)); 90 if (Sgl_isone_hiddenoverflow(result)) 91 Sgl_set_exponent(result,src_exponent + (SGL_BIAS+1)); 92 else Sgl_set_exponent(result,src_exponent + SGL_BIAS); 93 } 94 else { 95 result = src; /* set sign */ 96 Sgl_setzero_exponentmantissa(result); 97 /* check for inexact */ 98 if (Sgl_isnotzero_exponentmantissa(src)) { 99 inexact = TRUE; 100 /* round result */ 101 switch (Rounding_mode()) { 102 case ROUNDPLUS: 103 if (Sgl_iszero_sign(src)) 104 Sgl_set_exponent(result,SGL_BIAS); 105 break; 106 case ROUNDMINUS: 107 if (Sgl_isone_sign(src)) 108 Sgl_set_exponent(result,SGL_BIAS); 109 break; 110 case ROUNDNEAREST: 111 if (src_exponent == -1) 112 if (Sgl_isnotzero_mantissa(src)) 113 Sgl_set_exponent(result,SGL_BIAS); 114 } 115 } 116 } 117 *dstptr = result; 118 if (inexact) { 119 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 120 else Set_inexactflag(); 121 } 122 return(NOEXCEPTION); 123} 124 125/* 126 * Double Floating-point Round to Integer 127 */ 128 129int 130dbl_frnd(srcptr, null, dstptr, status) 131 dbl_floating_point *srcptr, *null, *dstptr; 132 unsigned int *status; 133{ 134 register unsigned int srcp1, srcp2, resultp1, resultp2; 135 register int src_exponent; 136 register int inexact = FALSE; 137 138 Dbl_copyfromptr(srcptr,srcp1,srcp2); 139 /* 140 * check source operand for NaN or infinity 141 */ 142 if ((src_exponent = Dbl_exponent(srcp1)) == DBL_INFINITY_EXPONENT) { 143 /* 144 * is signaling NaN? 145 */ 146 if (Dbl_isone_signaling(srcp1)) { 147 /* trap if INVALIDTRAP enabled */ 148 if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION); 149 /* make NaN quiet */ 150 Set_invalidflag(); 151 Dbl_set_quiet(srcp1); 152 } 153 /* 154 * return quiet NaN or infinity 155 */ 156 Dbl_copytoptr(srcp1,srcp2,dstptr); 157 return(NOEXCEPTION); 158 } 159 /* 160 * Need to round? 161 */ 162 if ((src_exponent -= DBL_BIAS) >= DBL_P - 1) { 163 Dbl_copytoptr(srcp1,srcp2,dstptr); 164 return(NOEXCEPTION); 165 } 166 /* 167 * Generate result 168 */ 169 if (src_exponent >= 0) { 170 Dbl_clear_exponent_set_hidden(srcp1); 171 resultp1 = srcp1; 172 resultp2 = srcp2; 173 Dbl_rightshift(resultp1,resultp2,(DBL_P-1) - (src_exponent)); 174 /* check for inexact */ 175 if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) { 176 inexact = TRUE; 177 /* round result */ 178 switch (Rounding_mode()) { 179 case ROUNDPLUS: 180 if (Dbl_iszero_sign(srcp1)) 181 Dbl_increment(resultp1,resultp2); 182 break; 183 case ROUNDMINUS: 184 if (Dbl_isone_sign(srcp1)) 185 Dbl_increment(resultp1,resultp2); 186 break; 187 case ROUNDNEAREST: 188 if (Dbl_isone_roundbit(srcp1,srcp2,src_exponent)) 189 if (Dbl_isone_stickybit(srcp1,srcp2,src_exponent) 190 || (Dbl_isone_lowmantissap2(resultp2))) 191 Dbl_increment(resultp1,resultp2); 192 } 193 } 194 Dbl_leftshift(resultp1,resultp2,(DBL_P-1) - (src_exponent)); 195 if (Dbl_isone_hiddenoverflow(resultp1)) 196 Dbl_set_exponent(resultp1,src_exponent + (DBL_BIAS+1)); 197 else Dbl_set_exponent(resultp1,src_exponent + DBL_BIAS); 198 } 199 else { 200 resultp1 = srcp1; /* set sign */ 201 Dbl_setzero_exponentmantissa(resultp1,resultp2); 202 /* check for inexact */ 203 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) { 204 inexact = TRUE; 205 /* round result */ 206 switch (Rounding_mode()) { 207 case ROUNDPLUS: 208 if (Dbl_iszero_sign(srcp1)) 209 Dbl_set_exponent(resultp1,DBL_BIAS); 210 break; 211 case ROUNDMINUS: 212 if (Dbl_isone_sign(srcp1)) 213 Dbl_set_exponent(resultp1,DBL_BIAS); 214 break; 215 case ROUNDNEAREST: 216 if (src_exponent == -1) 217 if (Dbl_isnotzero_mantissa(srcp1,srcp2)) 218 Dbl_set_exponent(resultp1,DBL_BIAS); 219 } 220 } 221 } 222 Dbl_copytoptr(resultp1,resultp2,dstptr); 223 if (inexact) { 224 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 225 else Set_inexactflag(); 226 } 227 return(NOEXCEPTION); 228} 229 230int 231quad_frnd(srcptr, null, dstptr, status) 232 quad_floating_point *srcptr, *null, *dstptr; 233 unsigned int *status; 234{ 235 return(UNIMPLEMENTEDEXCEPTION); 236} 237