double_to_string.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /* Copyright (c) 1993-2007 by Richard Kelsey and Jonathan Rees.
  2. See file COPYING. */
  3. #include <stdlib.h>
  4. #include <string.h>
  5. extern int s48_dragon(char *buf, double v);
  6. extern void s48_free_init(void);
  7. size_t
  8. s48_double_to_string(char *dest, double v)
  9. {
  10. char raw[33];
  11. char *buf = dest;
  12. char *digits = raw;
  13. int exponent = s48_dragon(raw, v);
  14. int digit_count = strlen(raw);
  15. if (*digits == '#') /* infinity or NaN */
  16. {
  17. strcpy(dest, digits);
  18. return digit_count;
  19. }
  20. if (*digits == '-')
  21. {
  22. *buf++ = '-';
  23. ++digits;
  24. --digit_count;
  25. }
  26. if ((exponent <= -4) || (exponent > (digit_count + 7)))
  27. /* print with explicit exponent */
  28. {
  29. int decimal_point = exponent;
  30. *buf++ = *digits++;
  31. if (*digits)
  32. {
  33. *buf++ = '.';
  34. while (*digits)
  35. *buf++ = *digits++;
  36. }
  37. /* exponent */
  38. *buf++ = 'e';
  39. if (decimal_point < 0)
  40. {
  41. *buf++ = '-';
  42. decimal_point = -decimal_point;
  43. }
  44. {
  45. int power_of_10 = 1;
  46. while (decimal_point >= (10*power_of_10))
  47. power_of_10 *= 10;
  48. while (power_of_10 > 0)
  49. {
  50. int digit = decimal_point / power_of_10;
  51. *buf++ = digit + '0';
  52. decimal_point -= digit * power_of_10;
  53. power_of_10 /= 10;
  54. }
  55. }
  56. *buf = '\0';
  57. }
  58. else if (exponent < 0)
  59. /* 0.<something> */
  60. {
  61. *buf++ = '0';
  62. *buf++ = '.';
  63. ++exponent;
  64. while (exponent < 0)
  65. {
  66. *buf++ = '0';
  67. ++exponent;
  68. }
  69. while (*digits)
  70. *buf++ = *digits++;
  71. *buf = '\0';
  72. }
  73. else
  74. /* <something>.<something> */
  75. {
  76. while (*digits)
  77. {
  78. *buf++ = *digits++;
  79. if (exponent == 0)
  80. *buf++ = '.';
  81. --exponent;
  82. }
  83. if (exponent >= 0)
  84. {
  85. while (exponent >= 0)
  86. {
  87. *buf++ = '0';
  88. --exponent;
  89. }
  90. *buf++ = '.';
  91. *buf++ = '0';
  92. }
  93. else
  94. {
  95. if (exponent == -1)
  96. *buf++ = '0';
  97. }
  98. *buf = '\0';
  99. }
  100. return buf - dest;
  101. }