Advertisement
tyotyotyo

modf

Apr 22nd, 2022
24
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.71 KB | None | 0 0
  1. /* modf
  2.  * ====================================================
  3.  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  4.  *
  5.  * Developed at SunPro, a Sun Microsystems, Inc. business.
  6.  * Permission to use, copy, modify, and distribute this
  7.  * software is freely granted, provided that this notice
  8.  * is preserved.
  9.  * ====================================================
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <stdint.h>
  14.  
  15. typedef union
  16. {
  17.     double value;
  18.     struct
  19.     {
  20.         uint32_t lsw;
  21.         uint32_t msw;
  22.     } parts;
  23. } ieee_double_shape_type;
  24.  
  25. /* Get two 32 bit ints from a double.  */
  26. #define EXTRACT_WORDS(ix0,ix1,d)                \
  27. do {                                \
  28.   ieee_double_shape_type ew_u;                  \
  29.   ew_u.value = (d);                     \
  30.   (ix0) = ew_u.parts.msw;                   \
  31.   (ix1) = ew_u.parts.lsw;                   \
  32. } while (0)
  33.  
  34. /* Set a double from two 32 bit ints.  */
  35. #define INSERT_WORDS(d,ix0,ix1)                 \
  36. do {                                \
  37.   ieee_double_shape_type iw_u;                  \
  38.   iw_u.parts.msw = (ix0);                   \
  39.   iw_u.parts.lsw = (ix1);                   \
  40.   (d) = iw_u.value;                     \
  41. } while (0)
  42.  
  43. /* Get the more significant 32 bit int from a double.  */
  44. #define GET_HIGH_WORD(i,d)                  \
  45. do {                                \
  46.   ieee_double_shape_type gh_u;                  \
  47.   gh_u.value = (d);                     \
  48.   (i) = gh_u.parts.msw;                     \
  49. } while (0)
  50.  
  51. static const double one = 1.0;
  52.  
  53. double
  54. modf(double x, double* iptr)
  55. {
  56.     int32_t i0, i1, j0;
  57.     uint32_t i;
  58.     EXTRACT_WORDS(i0, i1, x);
  59.     j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;  /* exponent of x */
  60.     if (j0 < 20) {          /* integer part in high x */
  61.         if (j0 < 0) {           /* |x|<1 */
  62.             INSERT_WORDS(*iptr, i0 & 0x80000000, 0);    /* *iptr = +-0 */
  63.             return x;
  64.         }
  65.         else {
  66.             i = (0x000fffff) >> j0;
  67.             if (((i0 & i) | i1) == 0) {     /* x is integral */
  68.                 uint32_t high;
  69.                 *iptr = x;
  70.                 GET_HIGH_WORD(high, x);
  71.                 INSERT_WORDS(x, high & 0x80000000, 0);  /* return +-0 */
  72.                 return x;
  73.             }
  74.             else {
  75.                 INSERT_WORDS(*iptr, i0 & (~i), 0);
  76.                 return x - *iptr;
  77.             }
  78.         }
  79.     }
  80.     else if (j0 > 51) {     /* no fraction part */
  81.         uint32_t high;
  82.         if (j0 == 0x400) {      /* inf/NaN */
  83.             *iptr = x;
  84.             return 0.0 / x;
  85.         }
  86.         *iptr = x * one;
  87.         GET_HIGH_WORD(high, x);
  88.         INSERT_WORDS(x, high & 0x80000000, 0);  /* return +-0 */
  89.         return x;
  90.     }
  91.     else {          /* fraction part in low x */
  92.         i = ((uint32_t)(0xffffffff)) >> (j0 - 20);
  93.         if ((i1 & i) == 0) {        /* x is integral */
  94.             uint32_t high;
  95.             *iptr = x;
  96.             GET_HIGH_WORD(high, x);
  97.             INSERT_WORDS(x, high & 0x80000000, 0);  /* return +-0 */
  98.             return x;
  99.         }
  100.         else {
  101.             INSERT_WORDS(*iptr, i0, i1 & (~i));
  102.             return x - *iptr;
  103.         }
  104.     }
  105. }
  106.  
  107. int main()
  108. {
  109.     double value = 3.14159265359;
  110.     double ipart = 0.0;
  111.     double frac = modf(value, &ipart);
  112.     printf("modf(%f):\n\tI: %f\n\tF: %f\n",value, ipart, frac);
  113.  
  114.     return 0;
  115. }
  116.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement