POK
/home/jaouen/pok_official/pok/trunk/libpok/libm/nextafterf.c
00001 /*
00002  *                               POK header
00003  * 
00004  * The following file is a part of the POK project. Any modification should
00005  * made according to the POK licence. You CANNOT use this file or a part of
00006  * this file is this part of a file for your own project
00007  *
00008  * For more information on the POK licence, please see our LICENCE FILE
00009  *
00010  * Please follow the coding guidelines described in doc/CODING_GUIDELINES
00011  *
00012  *                                      Copyright (c) 2007-2009 POK team 
00013  *
00014  * Created by julien on Fri Jan 30 14:41:34 2009 
00015  */
00016 
00017 /* s_nextafterf.c -- float version of s_nextafter.c.
00018  * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
00019  */
00020 
00021 /*
00022  * ====================================================
00023  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
00024  *
00025  * Developed at SunPro, a Sun Microsystems, Inc. business.
00026  * Permission to use, copy, modify, and distribute this
00027  * software is freely granted, provided that this notice
00028  * is preserved.
00029  * ====================================================
00030  */
00031 
00032 #ifdef POK_NEEDS_LIBMATH
00033 
00034 #include <libm.h>
00035 #include "math_private.h"
00036 
00037 float
00038 nextafterf(float x, float y)
00039 {
00040         int32_t hx,hy,ix,iy;
00041 
00042         GET_FLOAT_WORD(hx,x);
00043         GET_FLOAT_WORD(hy,y);
00044         ix = hx&0x7fffffff;             /* |x| */
00045         iy = hy&0x7fffffff;             /* |y| */
00046 
00047         if((ix>0x7f800000) ||   /* x is nan */
00048            (iy>0x7f800000))     /* y is nan */
00049            return x+y;
00050         if(x==y) return x;              /* x=y, return x */
00051         if(ix==0) {                             /* x == 0 */
00052             SET_FLOAT_WORD(x,(hy&0x80000000)|1);/* return +-minsubnormal */
00053             y = x*x;
00054             if(y==x) return y; else return x;   /* raise underflow flag */
00055         }
00056         if(hx>=0) {                             /* x > 0 */
00057             if(hx>hy) {                         /* x > y, x -= ulp */
00058                 hx -= 1;
00059             } else {                            /* x < y, x += ulp */
00060                 hx += 1;
00061             }
00062         } else {                                /* x < 0 */
00063             if(hy>=0||hx>hy){                   /* x < y, x -= ulp */
00064                 hx -= 1;
00065             } else {                            /* x > y, x += ulp */
00066                 hx += 1;
00067             }
00068         }
00069         hy = hx&0x7f800000;
00070         if(hy>=0x7f800000) return x+x;  /* overflow  */
00071         if(hy<0x00800000) {             /* underflow */
00072             y = x*x;
00073             if(y!=x) {          /* raise underflow flag */
00074                 SET_FLOAT_WORD(y,hx);
00075                 return y;
00076             }
00077         }
00078         SET_FLOAT_WORD(x,hx);
00079         return x;
00080 }
00081 
00082 #endif