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