s_modfl.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*-
  2. * Copyright (c) 2007 David Schultz <[email protected]>
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  15. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  16. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  17. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  18. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  19. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  20. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  21. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  22. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  23. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  24. * SUCH DAMAGE.
  25. *
  26. * Derived from s_modf.c, which has the following Copyright:
  27. * ====================================================
  28. * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  29. *
  30. * Developed at SunPro, a Sun Microsystems, Inc. business.
  31. * Permission to use, copy, modify, and distribute this
  32. * software is freely granted, provided that this notice
  33. * is preserved.
  34. * ====================================================
  35. *
  36. * $FreeBSD: src/lib/msun/src/s_modfl.c,v 1.1 2007/01/07 07:54:21 das Exp $
  37. */
  38. #include <float.h>
  39. #include <openlibm.h>
  40. #include "math_private.h"
  41. #include "fpmath.h"
  42. #if LDBL_MANL_SIZE > 32
  43. #define MASK ((u_int64_t)-1)
  44. #else
  45. #define MASK ((u_int32_t)-1)
  46. #endif
  47. /* Return the last n bits of a word, representing the fractional part. */
  48. #define GETFRAC(bits, n) ((bits) & ~(MASK << (n)))
  49. /* The number of fraction bits in manh, not counting the integer bit */
  50. #define HIBITS (LDBL_MANT_DIG - LDBL_MANL_SIZE)
  51. static const long double zero[] = { 0.0L, -0.0L };
  52. DLLEXPORT long double
  53. modfl(long double x, long double *iptr)
  54. {
  55. union IEEEl2bits ux;
  56. int e;
  57. ux.e = x;
  58. e = ux.bits.exp - LDBL_MAX_EXP + 1;
  59. if (e < HIBITS) { /* Integer part is in manh. */
  60. if (e < 0) { /* |x|<1 */
  61. *iptr = zero[ux.bits.sign];
  62. return (x);
  63. } else {
  64. if ((GETFRAC(ux.bits.manh, HIBITS - 1 - e) |
  65. ux.bits.manl) == 0) { /* X is an integer. */
  66. *iptr = x;
  67. return (zero[ux.bits.sign]);
  68. } else {
  69. /* Clear all but the top e+1 bits. */
  70. ux.bits.manh >>= HIBITS - 1 - e;
  71. ux.bits.manh <<= HIBITS - 1 - e;
  72. ux.bits.manl = 0;
  73. *iptr = ux.e;
  74. return (x - ux.e);
  75. }
  76. }
  77. } else if (e >= LDBL_MANT_DIG - 1) { /* x has no fraction part. */
  78. *iptr = x;
  79. if (x != x) /* Handle NaNs. */
  80. return (x);
  81. return (zero[ux.bits.sign]);
  82. } else { /* Fraction part is in manl. */
  83. if (GETFRAC(ux.bits.manl, LDBL_MANT_DIG - 1 - e) == 0) {
  84. /* x is integral. */
  85. *iptr = x;
  86. return (zero[ux.bits.sign]);
  87. } else {
  88. /* Clear all but the top e+1 bits. */
  89. ux.bits.manl >>= LDBL_MANT_DIG - 1 - e;
  90. ux.bits.manl <<= LDBL_MANT_DIG - 1 - e;
  91. *iptr = ux.e;
  92. return (x - ux.e);
  93. }
  94. }
  95. }