sf_modf.c 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /*
  2. * This file is part of the MicroPython project, http://micropython.org/
  3. *
  4. * These math functions are taken from newlib-nano-2, the newlib/libm/common
  5. * directory, available from https://github.com/32bitmicro/newlib-nano-2.
  6. *
  7. * Appropriate copyright headers are reproduced below.
  8. */
  9. /* sf_modf.c -- float version of s_modf.c.
  10. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
  11. */
  12. /*
  13. * ====================================================
  14. * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  15. *
  16. * Developed at SunPro, a Sun Microsystems, Inc. business.
  17. * Permission to use, copy, modify, and distribute this
  18. * software is freely granted, provided that this notice
  19. * is preserved.
  20. * ====================================================
  21. */
  22. #include "fdlibm.h"
  23. #ifdef __STDC__
  24. static const float one = 1.0;
  25. #else
  26. static float one = 1.0;
  27. #endif
  28. #ifdef __STDC__
  29. float modff(float x, float *iptr)
  30. #else
  31. float modff(x, iptr)
  32. float x,*iptr;
  33. #endif
  34. {
  35. __int32_t i0,j0;
  36. __uint32_t i;
  37. GET_FLOAT_WORD(i0,x);
  38. j0 = ((i0>>23)&0xff)-0x7f; /* exponent of x */
  39. if(j0<23) { /* integer part in x */
  40. if(j0<0) { /* |x|<1 */
  41. SET_FLOAT_WORD(*iptr,i0&0x80000000); /* *iptr = +-0 */
  42. return x;
  43. } else {
  44. i = (0x007fffff)>>j0;
  45. if((i0&i)==0) { /* x is integral */
  46. __uint32_t ix;
  47. *iptr = x;
  48. GET_FLOAT_WORD(ix,x);
  49. SET_FLOAT_WORD(x,ix&0x80000000); /* return +-0 */
  50. return x;
  51. } else {
  52. SET_FLOAT_WORD(*iptr,i0&(~i));
  53. return x - *iptr;
  54. }
  55. }
  56. } else { /* no fraction part */
  57. __uint32_t ix;
  58. *iptr = x*one;
  59. GET_FLOAT_WORD(ix,x);
  60. SET_FLOAT_WORD(x,ix&0x80000000); /* return +-0 */
  61. return x;
  62. }
  63. }
  64. #ifdef _DOUBLE_IS_32BITS
  65. #ifdef __STDC__
  66. double modf(double x, double *iptr)
  67. #else
  68. double modf(x, iptr)
  69. double x,*iptr;
  70. #endif
  71. {
  72. return (double) modff((float) x, (float *) iptr);
  73. }
  74. #endif /* defined(_DOUBLE_IS_32BITS) */