1 /* $OpenBSD: sfcmp.c,v 1.4 2001/03/29 03:58:19 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 /* 25 * pmk1.1 26 */ 27 /* 28 * (c) Copyright 1986 HEWLETT-PACKARD COMPANY 29 * 30 * To anyone who acknowledges that this file is provided "AS IS" 31 * without any express or implied warranty: 32 * permission to use, copy, modify, and distribute this file 33 * for any purpose is hereby granted without fee, provided that 34 * the above copyright notice and this notice appears in all 35 * copies, and that the name of Hewlett-Packard Company not be 36 * used in advertising or publicity pertaining to distribution 37 * of the software without specific, written prior permission. 38 * Hewlett-Packard Company makes no representations about the 39 * suitability of this software for any purpose. 40 */ 41 42 #include "../spmath/float.h" 43 #include "../spmath/sgl_float.h" 44 45 /* 46 * sgl_cmp: compare two values 47 */ 48 int 49 sgl_fcmp(leftptr, rightptr, cond, status) 50 sgl_floating_point *leftptr, *rightptr; 51 unsigned int cond; /* The predicate to be tested */ 52 unsigned int *status; 53 { 54 register unsigned int left, right; 55 register int xorresult; 56 57 /* Create local copies of the numbers */ 58 left = *leftptr; 59 right = *rightptr; 60 /* 61 * Test for NaN 62 */ 63 if( (Sgl_exponent(left) == SGL_INFINITY_EXPONENT) 64 || (Sgl_exponent(right) == SGL_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( ( (Sgl_exponent(left) == SGL_INFINITY_EXPONENT) 70 && Sgl_isnotzero_mantissa(left) 71 && (Exception(cond) || Sgl_isone_signaling(left))) 72 || 73 ( (Sgl_exponent(right) == SGL_INFINITY_EXPONENT) 74 && Sgl_isnotzero_mantissa(right) 75 && (Exception(cond) || Sgl_isone_signaling(right)) ) ) 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( ((Sgl_exponent(left) == SGL_INFINITY_EXPONENT) 88 && Sgl_isnotzero_mantissa(left)) 89 || 90 ((Sgl_exponent(right) == SGL_INFINITY_EXPONENT) 91 && Sgl_isnotzero_mantissa(right)) ) 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 Sgl_xortointp1(left,right,xorresult); 102 if( xorresult < 0 ) 103 { 104 /* left negative => less, left positive => greater. 105 * equal is possible if both operands are zeros. */ 106 if( Sgl_iszero_exponentmantissa(left) 107 && Sgl_iszero_exponentmantissa(right) ) 108 { 109 Set_status_cbit(Equal(cond)); 110 } 111 else if( Sgl_isone_sign(left) ) 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( Sgl_all(left) == Sgl_all(right) ) 123 { 124 Set_status_cbit(Equal(cond)); 125 } 126 else if( Sgl_iszero_sign(left) ) 127 { 128 /* Positive compare */ 129 if( Sgl_all(left) < Sgl_all(right) ) 130 { 131 Set_status_cbit(Lessthan(cond)); 132 } 133 else 134 { 135 Set_status_cbit(Greaterthan(cond)); 136 } 137 } 138 else 139 { 140 /* Negative compare. Signed or unsigned compares 141 * both work the same. That distinction is only 142 * important when the sign bits differ. */ 143 if( Sgl_all(left) > Sgl_all(right) ) 144 { 145 Set_status_cbit(Lessthan(cond)); 146 } 147 else 148 { 149 Set_status_cbit(Greaterthan(cond)); 150 } 151 } 152 return(NOEXCEPTION); 153 } 154