double_to_string.c 2.0 KB

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