s_rintf.c 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. /* s_rintf.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 "cdefs-compat.h"
  15. //__FBSDID("$FreeBSD: src/lib/msun/src/s_rintf.c,v 1.12 2008/02/22 02:30:35 das Exp $");
  16. #include <float.h>
  17. #include <openlibm_math.h>
  18. #include <stdint.h>
  19. #include "math_private.h"
  20. static const float
  21. TWO23[2]={
  22. 8.3886080000e+06, /* 0x4b000000 */
  23. -8.3886080000e+06, /* 0xcb000000 */
  24. };
  25. DLLEXPORT float
  26. rintf(float x)
  27. {
  28. int32_t i0,j0,sx;
  29. float w,t;
  30. GET_FLOAT_WORD(i0,x);
  31. sx = (i0>>31)&1;
  32. j0 = ((i0>>23)&0xff)-0x7f;
  33. if(j0<23) {
  34. if(j0<0) {
  35. if((i0&0x7fffffff)==0) return x;
  36. STRICT_ASSIGN(float,w,TWO23[sx]+x);
  37. t = w-TWO23[sx];
  38. GET_FLOAT_WORD(i0,t);
  39. SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31));
  40. return t;
  41. }
  42. STRICT_ASSIGN(float,w,TWO23[sx]+x);
  43. return w-TWO23[sx];
  44. }
  45. if(j0==0x80) return x+x; /* inf or NaN */
  46. else return x; /* x is integral */
  47. }