cvt.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /* $Id$ */
  2. #ifndef NOFLOAT
  3. #if __STDC__
  4. #include <float.h>
  5. #else
  6. #include <math.h>
  7. #define DBL_MAX M_MAX_D
  8. #endif
  9. static char *cvt();
  10. #define NDIGITS 128
  11. char *
  12. _ecvt(value, ndigit, decpt, sign)
  13. double value;
  14. int ndigit, *decpt, *sign;
  15. {
  16. return cvt(value, ndigit, decpt, sign, 1);
  17. }
  18. char *
  19. _fcvt(value, ndigit, decpt, sign)
  20. double value;
  21. int ndigit, *decpt, *sign;
  22. {
  23. return cvt(value, ndigit, decpt, sign, 0);
  24. }
  25. static struct powers_of_10 {
  26. double pval;
  27. double rpval;
  28. int exp;
  29. } p10[] = {
  30. 1.0e32, 1.0e-32, 32,
  31. 1.0e16, 1.0e-16, 16,
  32. 1.0e8, 1.0e-8, 8,
  33. 1.0e4, 1.0e-4, 4,
  34. 1.0e2, 1.0e-2, 2,
  35. 1.0e1, 1.0e-1, 1,
  36. 1.0e0, 1.0e0, 0
  37. };
  38. static char *
  39. cvt(value, ndigit, decpt, sign, ecvtflag)
  40. double value;
  41. int ndigit, *decpt, *sign;
  42. {
  43. static char buf[NDIGITS+1];
  44. register char *p = buf;
  45. register char *pe;
  46. if (ndigit < 0) ndigit = 0;
  47. if (ndigit > NDIGITS) ndigit = NDIGITS;
  48. pe = &buf[ndigit];
  49. buf[0] = '\0';
  50. *sign = 0;
  51. if (value < 0) {
  52. *sign = 1;
  53. value = -value;
  54. }
  55. *decpt = 0;
  56. if (value >= DBL_MAX) {
  57. value = DBL_MAX;
  58. }
  59. if (value != 0.0) {
  60. register struct powers_of_10 *pp = &p10[0];
  61. if (value >= 10.0) do {
  62. while (value >= pp->pval) {
  63. value *= pp->rpval;
  64. *decpt += pp->exp;
  65. }
  66. } while ((++pp)->exp > 0);
  67. pp = &p10[0];
  68. if (value < 1.0) do {
  69. while (value * pp->pval < 10.0) {
  70. value *= pp->pval;
  71. *decpt -= pp->exp;
  72. }
  73. } while ((++pp)->exp > 0);
  74. (*decpt)++; /* because now value in [1.0, 10.0) */
  75. }
  76. if (! ecvtflag) {
  77. /* for fcvt() we need ndigit digits behind the dot */
  78. pe += *decpt;
  79. if (pe > &buf[NDIGITS]) pe = &buf[NDIGITS];
  80. }
  81. while (p <= pe) {
  82. *p++ = (int)value + '0';
  83. value = 10.0 * (value - (int)value);
  84. }
  85. if (pe >= buf) {
  86. p = pe;
  87. *p += 5; /* round of at the end */
  88. while (*p > '9') {
  89. *p = '0';
  90. if (p > buf) ++*--p;
  91. else {
  92. *p = '1';
  93. ++*decpt;
  94. if (! ecvtflag) {
  95. /* maybe add another digit at the end,
  96. because the point was shifted right
  97. */
  98. if (pe > buf) *pe = '0';
  99. pe++;
  100. }
  101. }
  102. }
  103. *pe = '\0';
  104. }
  105. return buf;
  106. }
  107. #endif