POK
/home/jaouen/pok_official/pok/trunk/libpok/libm/asinhf.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_asinhf.c -- float version of s_asinh.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 <types.h>
00035 #include <libm.h>
00036 #include "math_private.h"
00037 
00038 static const float
00039 one =  1.0000000000e+00, /* 0x3F800000 */
00040 ln2 =  6.9314718246e-01, /* 0x3f317218 */
00041 huge=  1.0000000000e+30;
00042 
00043 float
00044 asinhf(float x)
00045 {
00046         float t,w;
00047         int32_t hx,ix;
00048         GET_FLOAT_WORD(hx,x);
00049         ix = hx&0x7fffffff;
00050         if(ix>=0x7f800000) return x+x;  /* x is inf or NaN */
00051         if(ix< 0x31800000) {    /* |x|<2**-28 */
00052             if(huge+x>one) return x;    /* return x inexact except 0 */
00053         }
00054         if(ix>0x4d800000) {     /* |x| > 2**28 */
00055             w = __ieee754_logf(fabsf(x))+ln2;
00056         } else if (ix>0x40000000) {     /* 2**28 > |x| > 2.0 */
00057             t = fabsf(x);
00058             w = __ieee754_logf((float)2.0*t+one/(__ieee754_sqrtf(x*x+one)+t));
00059         } else {                /* 2.0 > |x| > 2**-28 */
00060             t = x*x;
00061             w =log1pf(fabsf(x)+t/(one+__ieee754_sqrtf(one+t)));
00062         }
00063         if(hx>0) return w; else return -w;
00064 }
00065 #endif
00066