sf_rint.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. /* sf_rint.c -- float version of s_rint.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 "fdlibm.h"
  15. #ifdef __STDC__
  16. static const float
  17. #else
  18. static float
  19. #endif
  20. TWO23[2]={
  21. 8.3886080000e+06, /* 0x4b000000 */
  22. -8.3886080000e+06, /* 0xcb000000 */
  23. };
  24. #ifdef __STDC__
  25. float rintf(float x)
  26. #else
  27. float rintf(x)
  28. float x;
  29. #endif
  30. {
  31. int32_t i0,j0,sx;
  32. uint32_t i,i1;
  33. float w,t;
  34. GET_FLOAT_WORD(i0,x);
  35. sx = (i0>>31)&1;
  36. j0 = ((i0>>23)&0xff)-0x7f;
  37. if(j0<23) {
  38. if(j0<0) {
  39. if((i0&0x7fffffff)==0) return x;
  40. i1 = (i0&0x07fffff);
  41. i0 &= 0xfff00000;
  42. i0 |= ((i1|-i1)>>9)&0x400000;
  43. SET_FLOAT_WORD(x,i0);
  44. w = TWO23[sx]+x;
  45. t = w-TWO23[sx];
  46. GET_FLOAT_WORD(i0,t);
  47. SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31));
  48. return t;
  49. } else {
  50. i = (0x007fffff)>>j0;
  51. if((i0&i)==0) return x; /* x is integral */
  52. i>>=1;
  53. if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0);
  54. }
  55. } else {
  56. if(j0==0x80) return x+x; /* inf or NaN */
  57. else return x; /* x is integral */
  58. }
  59. SET_FLOAT_WORD(x,i0);
  60. w = TWO23[sx]+x;
  61. return w-TWO23[sx];
  62. }
  63. #ifdef _DOUBLE_IS_32BITS
  64. #ifdef __STDC__
  65. double rint(double x)
  66. #else
  67. double rint(x)
  68. double x;
  69. #endif
  70. {
  71. return (double) rintf((float) x);
  72. }
  73. #endif /* defined(_DOUBLE_IS_32BITS) */