e_logf.c 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. /* e_logf.c -- float version of e_log.c.
  2. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
  3. */
  4. /*
  5. * ====================================================
  6. * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  7. *
  8. * Developed at SunPro, a Sun Microsystems, Inc. business.
  9. * Permission to use, copy, modify, and distribute this
  10. * software is freely granted, provided that this notice
  11. * is preserved.
  12. * ====================================================
  13. */
  14. #include "cdefs-compat.h"
  15. //__FBSDID("$FreeBSD: src/lib/msun/src/e_logf.c,v 1.11 2008/03/29 16:37:59 das Exp $");
  16. #include <openlibm_math.h>
  17. #include "math_private.h"
  18. static const float
  19. ln2_hi = 6.9313812256e-01, /* 0x3f317180 */
  20. ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */
  21. two25 = 3.355443200e+07, /* 0x4c000000 */
  22. /* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */
  23. Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */
  24. Lg2 = 0xccce13.0p-25, /* 0.40000972152 */
  25. Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */
  26. Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */
  27. static const float zero = 0.0;
  28. OLM_DLLEXPORT float
  29. __ieee754_logf(float x)
  30. {
  31. float hfsq,f,s,z,R,w,t1,t2,dk;
  32. int32_t k,ix,i,j;
  33. GET_FLOAT_WORD(ix,x);
  34. k=0;
  35. if (ix < 0x00800000) { /* x < 2**-126 */
  36. if ((ix&0x7fffffff)==0)
  37. return -two25/zero; /* log(+-0)=-inf */
  38. if (ix<0) return (x-x)/zero; /* log(-#) = NaN */
  39. k -= 25; x *= two25; /* subnormal number, scale up x */
  40. GET_FLOAT_WORD(ix,x);
  41. }
  42. if (ix >= 0x7f800000) return x+x;
  43. k += (ix>>23)-127;
  44. ix &= 0x007fffff;
  45. i = (ix+(0x95f64<<3))&0x800000;
  46. SET_FLOAT_WORD(x,ix|(i^0x3f800000)); /* normalize x or x/2 */
  47. k += (i>>23);
  48. f = x-(float)1.0;
  49. if((0x007fffff&(0x8000+ix))<0xc000) { /* -2**-9 <= f < 2**-9 */
  50. if(f==zero) {
  51. if(k==0) {
  52. return zero;
  53. } else {
  54. dk=(float)k;
  55. return dk*ln2_hi+dk*ln2_lo;
  56. }
  57. }
  58. R = f*f*((float)0.5-(float)0.33333333333333333*f);
  59. if(k==0) return f-R; else {dk=(float)k;
  60. return dk*ln2_hi-((R-dk*ln2_lo)-f);}
  61. }
  62. s = f/((float)2.0+f);
  63. dk = (float)k;
  64. z = s*s;
  65. i = ix-(0x6147a<<3);
  66. w = z*z;
  67. j = (0x6b851<<3)-ix;
  68. t1= w*(Lg2+w*Lg4);
  69. t2= z*(Lg1+w*Lg3);
  70. i |= j;
  71. R = t2+t1;
  72. if(i>0) {
  73. hfsq=(float)0.5*f*f;
  74. if(k==0) return f-(hfsq-s*(hfsq+R)); else
  75. return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f);
  76. } else {
  77. if(k==0) return f-s*(f-R); else
  78. return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f);
  79. }
  80. }