home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / x / xntp3.zip / include / ntp_fp.h < prev    next >
Text File  |  1992-01-03  |  8KB  |  279 lines

  1. /*
  2.  * ntp_fp.h - definitions for NTP fixed point arithmetic
  3.  */
  4.  
  5. /*
  6.  * NTP uses two fixed point formats.  The first (l_fp) is the "long" format
  7.  * and is 64 bits long with the decimal between bits 31 and 32.  This
  8.  * is used for time stamps in the NTP packet header (in network byte
  9.  * order) and for internal computations of offsets (in local host byte
  10.  * order).  We use the same structure for both signed and unsigned values,
  11.  * which is a big hack but saves rewriting all the operators twice.  Just
  12.  * to confuse this, we also sometimes just carry the fractional part in
  13.  * calculations, in both signed and unsigned forms.  Anyway, an l_fp looks
  14.  * like:
  15.  *
  16.  *    0              1              2              3
  17.  *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  18.  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  19.  *   |                   Integral Part                 |
  20.  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  21.  *   |                   Fractional Part                 |
  22.  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  23.  *
  24.  */
  25. typedef struct {
  26.     union {
  27.         u_long Xl_ui;
  28.         long Xl_i;
  29.     } Ul_i;
  30.     union {
  31.         u_long Xl_uf;
  32.         long Xl_f;
  33.     } Ul_f;
  34. } l_fp;
  35.  
  36. #define l_ui    Ul_i.Xl_ui        /* unsigned integral part */
  37. #define    l_i    Ul_i.Xl_i        /* signed integral part */
  38. #define    l_uf    Ul_f.Xl_uf        /* unsigned fractional part */
  39. #define    l_f    Ul_f.Xl_f        /* signed fractional part */
  40.  
  41. /*
  42.  * Fractional precision (of an l_fp) is actually the number of
  43.  * bits in a long.
  44.  */
  45. #define    FRACTION_PREC    (32)
  46.  
  47.  
  48. /*
  49.  * The second fixed point format is 32 bits, with the decimal between
  50.  * bits 15 and 16.  There is a signed version (s_fp) and an unsigned
  51.  * version (u_fp).  This is used to represent synchronizing distance
  52.  * and synchronizing dispersion in the NTP packet header (again, in
  53.  * network byte order) and internally to hold both distance and
  54.  * dispersion values (in local byte order).  In network byte order
  55.  * it looks like:
  56.  *
  57.  *    0              1              2              3
  58.  *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  59.  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  60.  *   |          Integer Part         |       Fraction Part         |
  61.  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  62.  *
  63.  */
  64. typedef long s_fp;
  65. typedef u_long u_fp;
  66.  
  67. /*
  68.  * A unit second in fp format.  Actually 2**(half_the_bits_in_a_long)
  69.  */
  70. #define    FP_SECOND    (0x10000)
  71.  
  72. /*
  73.  * Byte order conversions
  74.  */
  75. #define    HTONS_FP(x)    (htonl(x))
  76. #define    HTONL_FP(h, n)    do { (n)->l_ui = htonl((h)->l_ui); \
  77.                  (n)->l_uf = htonl((h)->l_uf); } while (0)
  78. #define    NTOHS_FP(x)    (ntohl(x))
  79. #define    NTOHL_FP(n, h)    do { (h)->l_ui = ntohl((n)->l_ui); \
  80.                  (h)->l_uf = ntohl((n)->l_uf); } while (0)
  81. #define    NTOHL_MFP(ni, nf, hi, hf) \
  82.     do { (hi) = ntohl(ni); (hf) = ntohl(nf); } while (0)
  83. #define    HTONL_MFP(hi, hf, ni, nf) \
  84.     do { (ni) = ntohl(hi); (nf) = ntohl(hf); } while (0)
  85.  
  86. /* funny ones.  Converts ts fractions to net order ts */
  87. #define    HTONL_UF(uf, nts) \
  88.     do { (nts)->l_ui = 0; (nts)->l_uf = htonl(uf); } while (0)
  89. #define    HTONL_F(f, nts) do { (nts)->l_uf = htonl(f); \
  90.                 if ((f) & 0x80000000) \
  91.                     (nts)->l_i = -1; \
  92.                 else \
  93.                     (nts)->l_i = 0; \
  94.             } while (0)
  95.  
  96. /*
  97.  * Conversions between the two fixed point types
  98.  */
  99. #define    MFPTOFP(x_i, x_f)    (((x_i)<<16) | (((x_f)>>16)&0xffff))
  100. #define    LFPTOFP(v)        MFPTOFP((v)->l_ui, (v)->l_uf)
  101.  
  102. #define UFPTOLFP(x, v) ((v)->l_ui = (u_fp)(x)>>16, (v)->l_uf = (x)<<16)
  103. #define FPTOLFP(x, v)  (UFPTOLFP((x), (v)), (x) < 0 ? (v)->l_ui -= 0x10000 : 0)
  104.  
  105. /*
  106.  * Primitive operations on long fixed point values.  If these are
  107.  * reminiscent of assembler op codes it's only because some may
  108.  * be replaced by inline assembler for particular machines someday.
  109.  * These are the (kind of inefficient) run-anywhere versions.
  110.  */
  111. #define    M_NEG(v_i, v_f)     /* v = -v */ \
  112.     do { \
  113.         if ((v_f) == 0) \
  114.             (v_i) = -(v_i); \
  115.         else { \
  116.             (v_f) = -(v_f); \
  117.             (v_i) = ~(v_i); \
  118.         } \
  119.     } while(0)
  120.  
  121. #define    M_NEGM(r_i, r_f, a_i, a_f)     /* r = -a */ \
  122.     do { \
  123.         if ((a_f) == 0) { \
  124.             (r_f) = 0; \
  125.             (r_i) = -(a_i); \
  126.         } else { \
  127.             (r_f) = -(a_f); \
  128.             (r_i) = ~(a_i); \
  129.         } \
  130.     } while(0)
  131.  
  132. #define M_ADD(r_i, r_f, a_i, a_f)     /* r += a */ \
  133.     do { \
  134.         register u_long lo_tmp; \
  135.         register u_long hi_tmp; \
  136.         \
  137.         lo_tmp = ((r_f) & 0xffff) + ((a_f) & 0xffff); \
  138.         hi_tmp = (((r_f) >> 16) & 0xffff) + (((a_f) >> 16) & 0xffff); \
  139.         if (lo_tmp & 0x10000) \
  140.             hi_tmp++; \
  141.         (r_f) = ((hi_tmp & 0xffff) << 16) | (lo_tmp & 0xffff); \
  142.         \
  143.         (r_i) += (a_i); \
  144.         if (hi_tmp & 0x10000) \
  145.             (r_i)++; \
  146.     } while (0)
  147.  
  148. #define M_ADD3(r_ovr, r_i, r_f, a_ovr, a_i, a_f) /* r += a, three word */ \
  149.     do { \
  150.         register u_long lo_tmp; \
  151.         register u_long hi_tmp; \
  152.         \
  153.         lo_tmp = ((r_f) & 0xffff) + ((a_f) & 0xffff); \
  154.         hi_tmp = (((r_f) >> 16) & 0xffff) + (((a_f) >> 16) & 0xffff); \
  155.         if (lo_tmp & 0x10000) \
  156.             hi_tmp++; \
  157.         (r_f) = ((hi_tmp & 0xffff) << 16) | (lo_tmp & 0xffff); \
  158.         \
  159.         lo_tmp = ((r_i) & 0xffff) + ((a_i) & 0xffff); \
  160.         if (hi_tmp & 0x10000) \
  161.             lo_tmp++; \
  162.         hi_tmp = (((r_i) >> 16) & 0xffff) + (((a_i) >> 16) & 0xffff); \
  163.         if (lo_tmp & 0x10000) \
  164.             hi_tmp++; \
  165.         (r_i) = ((hi_tmp & 0xffff) << 16) | (lo_tmp & 0xffff); \
  166.         \
  167.         (r_ovr) += (a_ovr); \
  168.         if (hi_tmp & 0x10000) \
  169.             (r_ovr)++; \
  170.     } while (0)
  171.  
  172. #define M_SUB(r_i, r_f, a_i, a_f)    /* r -= a */ \
  173.     do { \
  174.         register u_long lo_tmp; \
  175.         register u_long hi_tmp; \
  176.         \
  177.         if ((a_f) == 0) { \
  178.             (r_i) -= (a_i); \
  179.         } else { \
  180.             lo_tmp = ((r_f) & 0xffff) + ((-(a_f)) & 0xffff); \
  181.             hi_tmp = (((r_f) >> 16) & 0xffff) \
  182.                 + (((-(a_f)) >> 16) & 0xffff); \
  183.             if (lo_tmp & 0x10000) \
  184.                 hi_tmp++; \
  185.             (r_f) = ((hi_tmp & 0xffff) << 16) | (lo_tmp & 0xffff); \
  186.             \
  187.             (r_i) += ~(a_i); \
  188.             if (hi_tmp & 0x10000) \
  189.                 (r_i)++; \
  190.         } \
  191.     } while (0)
  192.  
  193. #define    M_RSHIFTU(v_i, v_f)        /* v >>= 1, v is unsigned */ \
  194.     do { \
  195.         (v_f) = (u_long)(v_f) >> 1; \
  196.         if ((v_i) & 01) \
  197.             (v_f) |= 0x80000000; \
  198.         (v_i) = (u_long)(v_i) >> 1; \
  199.     } while (0)
  200.  
  201. #define    M_RSHIFT(v_i, v_f)        /* v >>= 1, v is signed */ \
  202.     do { \
  203.         (v_f) = (u_long)(v_f) >> 1; \
  204.         if ((v_i) & 01) \
  205.             (v_f) |= 0x80000000; \
  206.         if ((v_i) & 0x80000000) \
  207.             (v_i) = ((v_i) >> 1) | 0x80000000; \
  208.         else \
  209.             (v_i) = (v_i) >> 1; \
  210.     } while (0)
  211.  
  212. #define    M_LSHIFT(v_i, v_f)        /* v <<= 1 */ \
  213.     do { \
  214.         (v_i) <<= 1; \
  215.         if ((v_f) & 0x80000000) \
  216.             (v_i) |= 0x1; \
  217.         (v_f) <<= 1; \
  218.     } while (0)
  219.  
  220. #define    M_LSHIFT3(v_ovr, v_i, v_f)    /* v <<= 1, with overflow */ \
  221.     do { \
  222.         (v_ovr) <<= 1; \
  223.         if ((v_i) & 0x80000000) \
  224.             (v_ovr) |= 0x1; \
  225.         (v_i) <<= 1; \
  226.         if ((v_f) & 0x80000000) \
  227.             (v_i) |= 0x1; \
  228.         (v_f) <<= 1; \
  229.     } while (0)
  230.  
  231. #define    M_ADDUF(r_i, r_f, uf)         /* r += uf, uf is u_long fraction */ \
  232.     M_ADD((r_i), (r_f), 0, (uf))    /* let optimizer worry about it */
  233.  
  234. #define    M_SUBUF(r_i, r_f, uf)        /* r -= uf, uf is u_long fraction */ \
  235.     M_SUB((r_i), (r_f), 0, (uf))    /* let optimizer worry about it */
  236.  
  237. #define    M_ADDF(r_i, r_f, f)        /* r += f, f is a long fraction */ \
  238.     do { \
  239.         if ((f) > 0) \
  240.             M_ADD((r_i), (r_f), 0, (f)); \
  241.         else if ((f) < 0) \
  242.             M_ADD((r_i), (r_f), (-1), (f));\
  243.     } while(0)
  244.  
  245. #define    M_ISNEG(v_i, v_f)         /* v < 0 */ \
  246.     (((v_i) & 0x80000000) != 0)
  247.  
  248. #define    M_ISHIS(a_i, a_f, b_i, b_f)    /* a >= b unsigned */ \
  249.     (((u_long)(a_i)) > ((u_long)(b_i)) || \
  250.       ((a_i) == (b_i) && ((u_long)(a_f)) >= ((u_long)(b_f))))
  251.  
  252. #define    M_ISGEQ(a_i, a_f, b_i, b_f)    /* a >= b signed */ \
  253.     (((long)(a_i)) > ((long)(b_i)) || \
  254.       ((a_i) == (b_i) && ((u_long)(a_f)) >= ((u_long)(b_f))))
  255.  
  256. #define    M_ISEQU(a_i, a_f, b_i, b_f)    /* a == b unsigned */ \
  257.     ((a_i) == (b_i) && (a_f) == (b_f))
  258.  
  259. /*
  260.  * Operations on the long fp format
  261.  */
  262. #define    L_ADD(r, a)    M_ADD((r)->l_ui, (r)->l_uf, (a)->l_ui, (a)->l_uf)
  263. #define    L_SUB(r, a)    M_SUB((r)->l_ui, (r)->l_uf, (a)->l_ui, (a)->l_uf)
  264. #define    L_NEG(v)    M_NEG((v)->l_ui, (v)->l_uf)
  265. #define L_ADDUF(r, uf)    M_ADDUF((r)->l_ui, (r)->l_uf, (uf))
  266. #define L_SUBUF(r, uf)    M_SUBUF((r)->l_ui, (r)->l_uf, (uf))
  267. #define    L_ADDF(r, f)    M_ADDF((r)->l_ui, (r)->l_uf, (f))
  268. #define    L_RSHIFT(v)    M_RSHIFT((v)->l_i, (v)->l_uf)
  269. #define    L_RSHIFTU(v)    M_RSHIFT((v)->l_ui, (v)->l_uf)
  270. #define    L_LSHIFT(v)    M_LSHIFT((v)->l_ui, (v)->l_uf)
  271. #define    L_CLR(v)    ((v)->l_ui = (v)->l_uf = 0)
  272.  
  273. #define    L_ISNEG(v)    (((v)->l_ui & 0x80000000) != 0)
  274. #define    L_ISHIS(a, b)    ((a)->l_ui > (b)->l_ui || \
  275.               ((a)->l_ui == (b)->l_ui && (a)->l_uf >= (b)->l_uf))
  276. #define    L_ISGEQ(a, b)    ((a)->l_i > (b)->l_i || \
  277.               ((a)->l_i == (b)->l_i && (a)->l_uf >= (b)->l_uf))
  278. #define    L_ISEQU(a, b)    M_ISEQU((a)->l_ui, (a)->l_uf, (b)->l_ui, (b)->l_uf)
  279.