Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /* sf_scalbn.c -- float version of s_scalbn.c.
  2.  * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
  3.  */
  4.  
  5. /*
  6.  * ====================================================
  7.  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  8.  *
  9.  * Developed at SunPro, a Sun Microsystems, Inc. business.
  10.  * Permission to use, copy, modify, and distribute this
  11.  * software is freely granted, provided that this notice
  12.  * is preserved.
  13.  * ====================================================
  14.  */
  15.  
  16. #include "fdlibm.h"
  17. #include <limits.h>
  18. #include <float.h>
  19.  
  20. #if INT_MAX > 50000
  21. #define OVERFLOW_INT 50000
  22. #else
  23. #define OVERFLOW_INT 30000
  24. #endif
  25.  
  26. #ifdef __STDC__
  27. static const float
  28. #else
  29. static float
  30. #endif
  31. two25   =  3.355443200e+07,     /* 0x4c000000 */
  32. twom25  =  2.9802322388e-08,    /* 0x33000000 */
  33. huge   = 1.0e+30,
  34. tiny   = 1.0e-30;
  35.  
  36. #ifdef __STDC__
  37.         float scalbnf (float x, int n)
  38. #else
  39.         float scalbnf (x,n)
  40.         float x; int n;
  41. #endif
  42. {
  43.         __int32_t  k,ix;
  44.         __uint32_t hx;
  45.  
  46.         GET_FLOAT_WORD(ix,x);
  47.         hx = ix&0x7fffffff;
  48.         k = hx>>23;             /* extract exponent */
  49.         if (FLT_UWORD_IS_ZERO(hx))
  50.             return x;
  51.         if (!FLT_UWORD_IS_FINITE(hx))
  52.             return x+x;         /* NaN or Inf */
  53.         if (FLT_UWORD_IS_SUBNORMAL(hx)) {
  54.             x *= two25;
  55.             GET_FLOAT_WORD(ix,x);
  56.             k = ((ix&0x7f800000)>>23) - 25;
  57.             if (n< -50000) return tiny*x;       /*underflow*/
  58.         }
  59.         k = k+n;
  60.         if (k > FLT_LARGEST_EXP) return huge*copysignf(huge,x); /* overflow  */
  61.         if (k > 0)                              /* normal result */
  62.             {SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;}
  63.         if (k < FLT_SMALLEST_EXP) {
  64.             if (n > OVERFLOW_INT)       /* in case integer overflow in n+k */
  65.                 return huge*copysignf(huge,x);  /*overflow*/
  66.             else return tiny*copysignf(tiny,x); /*underflow*/
  67.         }
  68.         k += 25;                                /* subnormal result */
  69.         SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23));
  70.         return x*twom25;
  71. }
  72.  
  73. #ifdef _DOUBLE_IS_32BITS
  74.  
  75. #ifdef __STDC__
  76.         double scalbn(double x, int n)
  77. #else
  78.         double scalbn(x,n)
  79.         double x;
  80.         int n;
  81. #endif
  82. {
  83.         return (double) scalbnf((float) x, n);
  84. }
  85.  
  86. #endif /* defined(_DOUBLE_IS_32BITS) */
  87.