1 /* $OpenBSD: dfcmp.c,v 1.4 2001/03/29 03:58:17 mickey Exp $ */ 2 3 /* 4 * Copyright 1996 1995 by Open Software Foundation, Inc. 5 * All Rights Reserved 6 * 7 * Permission to use, copy, modify, and distribute this software and 8 * its documentation for any purpose and without fee is hereby granted, 9 * provided that the above copyright notice appears in all copies and 10 * that both the copyright notice and this permission notice appear in 11 * supporting documentation. 12 * 13 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 14 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 15 * FOR A PARTICULAR PURPOSE. 16 * 17 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 19 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 20 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 21 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22 */ 23 /* 24 * pmk1.1 25 */ 26 /* 27 * (c) Copyright 1986 HEWLETT-PACKARD COMPANY 28 * 29 * To anyone who acknowledges that this file is provided "AS IS" 30 * without any express or implied warranty: 31 * permission to use, copy, modify, and distribute this file 32 * for any purpose is hereby granted without fee, provided that 33 * the above copyright notice and this notice appears in all 34 * copies, and that the name of Hewlett-Packard Company not be 35 * used in advertising or publicity pertaining to distribution 36 * of the software without specific, written prior permission. 37 * Hewlett-Packard Company makes no representations about the 38 * suitability of this software for any purpose. 39 */ 40 41 42 #include "../spmath/float.h" 43 #include "../spmath/dbl_float.h" 44 45 /* 46 * dbl_cmp: compare two values 47 */ 48 int 49 dbl_fcmp(leftptr, rightptr, cond, status) 50 dbl_floating_point *leftptr, *rightptr; 51 unsigned int cond; /* The predicate to be tested */ 52 unsigned int *status; 53 { 54 register unsigned int leftp1, leftp2, rightp1, rightp2; 55 register int xorresult; 56 57 /* Create local copies of the numbers */ 58 Dbl_copyfromptr(leftptr,leftp1,leftp2); 59 Dbl_copyfromptr(rightptr,rightp1,rightp2); 60 /* 61 * Test for NaN 62 */ 63 if( (Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT) 64 || (Dbl_exponent(rightp1) == DBL_INFINITY_EXPONENT) ) 65 { 66 /* Check if a NaN is involved. Signal an invalid exception when 67 * comparing a signaling NaN or when comparing quiet NaNs and the 68 * low bit of the condition is set */ 69 if( ((Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT) 70 && Dbl_isnotzero_mantissa(leftp1,leftp2) 71 && (Exception(cond) || Dbl_isone_signaling(leftp1))) 72 || 73 ((Dbl_exponent(rightp1) == DBL_INFINITY_EXPONENT) 74 && Dbl_isnotzero_mantissa(rightp1,rightp2) 75 && (Exception(cond) || Dbl_isone_signaling(rightp1))) ) 76 { 77 if( Is_invalidtrap_enabled() ) { 78 Set_status_cbit(Unordered(cond)); 79 return(INVALIDEXCEPTION); 80 } 81 else Set_invalidflag(); 82 Set_status_cbit(Unordered(cond)); 83 return(NOEXCEPTION); 84 } 85 /* All the exceptional conditions are handled, now special case 86 NaN compares */ 87 else if( ((Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT) 88 && Dbl_isnotzero_mantissa(leftp1,leftp2)) 89 || 90 ((Dbl_exponent(rightp1) == DBL_INFINITY_EXPONENT) 91 && Dbl_isnotzero_mantissa(rightp1,rightp2)) ) 92 { 93 /* NaNs always compare unordered. */ 94 Set_status_cbit(Unordered(cond)); 95 return(NOEXCEPTION); 96 } 97 /* infinities will drop down to the normal compare mechanisms */ 98 } 99 /* First compare for unequal signs => less or greater or 100 * special equal case */ 101 Dbl_xortointp1(leftp1,rightp1,xorresult); 102 if( xorresult < 0 ) 103 { 104 /* left negative => less, left positive => greater. 105 * equal is possible if both operands are zeros. */ 106 if( Dbl_iszero_exponentmantissa(leftp1,leftp2) 107 && Dbl_iszero_exponentmantissa(rightp1,rightp2) ) 108 { 109 Set_status_cbit(Equal(cond)); 110 } 111 else if( Dbl_isone_sign(leftp1) ) 112 { 113 Set_status_cbit(Lessthan(cond)); 114 } 115 else 116 { 117 Set_status_cbit(Greaterthan(cond)); 118 } 119 } 120 /* Signs are the same. Treat negative numbers separately 121 * from the positives because of the reversed sense. */ 122 else if(Dbl_isequal(leftp1,leftp2,rightp1,rightp2)) 123 { 124 Set_status_cbit(Equal(cond)); 125 } 126 else if( Dbl_iszero_sign(leftp1) ) 127 { 128 /* Positive compare */ 129 if( Dbl_allp1(leftp1) < Dbl_allp1(rightp1) ) 130 { 131 Set_status_cbit(Lessthan(cond)); 132 } 133 else if( Dbl_allp1(leftp1) > Dbl_allp1(rightp1) ) 134 { 135 Set_status_cbit(Greaterthan(cond)); 136 } 137 else 138 { 139 /* Equal first parts. Now we must use unsigned compares to 140 * resolve the two possibilities. */ 141 if( Dbl_allp2(leftp2) < Dbl_allp2(rightp2) ) 142 { 143 Set_status_cbit(Lessthan(cond)); 144 } 145 else 146 { 147 Set_status_cbit(Greaterthan(cond)); 148 } 149 } 150 } 151 else 152 { 153 /* Negative compare. Signed or unsigned compares 154 * both work the same. That distinction is only 155 * important when the sign bits differ. */ 156 if( Dbl_allp1(leftp1) > Dbl_allp1(rightp1) ) 157 { 158 Set_status_cbit(Lessthan(cond)); 159 } 160 else if( Dbl_allp1(leftp1) < Dbl_allp1(rightp1) ) 161 { 162 Set_status_cbit(Greaterthan(cond)); 163 } 164 else 165 { 166 /* Equal first parts. Now we must use unsigned compares to 167 * resolve the two possibilities. */ 168 if( Dbl_allp2(leftp2) > Dbl_allp2(rightp2) ) 169 { 170 Set_status_cbit(Lessthan(cond)); 171 } 172 else 173 { 174 Set_status_cbit(Greaterthan(cond)); 175 } 176 } 177 } 178 return(NOEXCEPTION); 179 } 180