/contrib/ntp/libntp/dofptoa.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 118 lines · 76 code · 14 blank · 28 comment · 19 complexity · b309316361095223b07b057512250910 MD5 · raw file

  1. /*
  2. * dofptoa - do the grunge work to convert an fp number to ascii
  3. */
  4. #include <stdio.h>
  5. #include "ntp_fp.h"
  6. #include "lib_strbuf.h"
  7. #include "ntp_string.h"
  8. #include "ntp_stdlib.h"
  9. char *
  10. dofptoa(
  11. u_fp fpv,
  12. int neg,
  13. short ndec,
  14. int msec
  15. )
  16. {
  17. register u_char *cp, *cpend;
  18. register u_long val;
  19. register short dec;
  20. u_char cbuf[12];
  21. u_char *cpdec;
  22. char *buf;
  23. char *bp;
  24. /*
  25. * Get a string buffer before starting
  26. */
  27. LIB_GETBUF(buf);
  28. /*
  29. * Zero out the buffer
  30. */
  31. memset((char *)cbuf, 0, sizeof cbuf);
  32. /*
  33. * Set the pointers to point at the first
  34. * decimal place. Get a local copy of the value.
  35. */
  36. cp = cpend = &cbuf[5];
  37. val = fpv;
  38. /*
  39. * If we have to, decode the integral part
  40. */
  41. if (!(val & 0xffff0000))
  42. cp--;
  43. else {
  44. register u_short sv = (u_short)(val >> 16);
  45. register u_short tmp;
  46. register u_short ten = 10;
  47. do {
  48. tmp = sv;
  49. sv = (u_short) (sv/ten);
  50. *(--cp) = (u_char)(tmp - ((sv<<3) + (sv<<1)));
  51. } while (sv != 0);
  52. }
  53. /*
  54. * Figure out how much of the fraction to do
  55. */
  56. if (msec) {
  57. dec = (short)(ndec + 3);
  58. if (dec < 3)
  59. dec = 3;
  60. cpdec = &cbuf[8];
  61. } else {
  62. dec = ndec;
  63. cpdec = cpend;
  64. }
  65. if (dec > 6)
  66. dec = 6;
  67. if (dec > 0) {
  68. do {
  69. val &= 0xffff;
  70. val = (val << 3) + (val << 1);
  71. *cpend++ = (u_char)(val >> 16);
  72. } while (--dec > 0);
  73. }
  74. if (val & 0x8000) {
  75. register u_char *tp;
  76. /*
  77. * Round it. Ick.
  78. */
  79. tp = cpend;
  80. *(--tp) += 1;
  81. while (*tp >= 10) {
  82. *tp = 0;
  83. *(--tp) += 1;
  84. }
  85. }
  86. /*
  87. * Remove leading zeroes if necessary
  88. */
  89. while (cp < (cpdec -1) && *cp == 0)
  90. cp++;
  91. /*
  92. * Copy it into the buffer, asciizing as we go.
  93. */
  94. bp = buf;
  95. if (neg)
  96. *bp++ = '-';
  97. while (cp < cpend) {
  98. if (cp == cpdec)
  99. *bp++ = '.';
  100. *bp++ = (char)(*cp++ + '0');
  101. }
  102. *bp = '\0';
  103. return buf;
  104. }