g_fmt.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /****************************************************************
  2. *
  3. * The author of this software is David M. Gay.
  4. *
  5. * Copyright (c) 1991, 1996 by Lucent Technologies.
  6. *
  7. * Permission to use, copy, modify, and distribute this software for any
  8. * purpose without fee is hereby granted, provided that this entire notice
  9. * is included in all copies of any software which is or includes a copy
  10. * or modification of this software and in all copies of the supporting
  11. * documentation for such software.
  12. *
  13. * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
  14. * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
  15. * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
  16. * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
  17. *
  18. ***************************************************************/
  19. /* g_fmt(buf,x) stores the closest decimal approximation to x in buf;
  20. * it suffices to declare buf
  21. * char buf[32];
  22. */
  23. #if 0
  24. #ifdef __cplusplus
  25. extern "C" {
  26. #endif
  27. extern char *dtoa(double, int, int, int *, int *, char **);
  28. extern int g_fmt(char *, double, int);
  29. extern void freedtoa(char*);
  30. #ifdef __cplusplus
  31. }
  32. #endif
  33. int
  34. fpconv_g_fmt(char *b, double x, int precision)
  35. {
  36. register int i, k;
  37. register char *s;
  38. int decpt, j, sign;
  39. char *b0, *s0, *se;
  40. b0 = b;
  41. #ifdef IGNORE_ZERO_SIGN
  42. if (!x) {
  43. *b++ = '0';
  44. *b = 0;
  45. goto done;
  46. }
  47. #endif
  48. s = s0 = dtoa(x, 2, precision, &decpt, &sign, &se);
  49. if (sign)
  50. *b++ = '-';
  51. if (decpt == 9999) /* Infinity or Nan */ {
  52. while((*b++ = *s++));
  53. /* "b" is used to calculate the return length. Decrement to exclude the
  54. * Null terminator from the length */
  55. b--;
  56. goto done0;
  57. }
  58. if (decpt <= -4 || decpt > precision) {
  59. *b++ = *s++;
  60. if (*s) {
  61. *b++ = '.';
  62. while((*b = *s++))
  63. b++;
  64. }
  65. *b++ = 'e';
  66. /* sprintf(b, "%+.2d", decpt - 1); */
  67. if (--decpt < 0) {
  68. *b++ = '-';
  69. decpt = -decpt;
  70. }
  71. else
  72. *b++ = '+';
  73. for(j = 2, k = 10; 10*k <= decpt; j++, k *= 10);
  74. for(;;) {
  75. i = decpt / k;
  76. *b++ = i + '0';
  77. if (--j <= 0)
  78. break;
  79. decpt -= i*k;
  80. decpt *= 10;
  81. }
  82. *b = 0;
  83. }
  84. else if (decpt <= 0) {
  85. *b++ = '0';
  86. *b++ = '.';
  87. for(; decpt < 0; decpt++)
  88. *b++ = '0';
  89. while((*b++ = *s++));
  90. b--;
  91. }
  92. else {
  93. while((*b = *s++)) {
  94. b++;
  95. if (--decpt == 0 && *s)
  96. *b++ = '.';
  97. }
  98. for(; decpt > 0; decpt--)
  99. *b++ = '0';
  100. *b = 0;
  101. }
  102. done0:
  103. freedtoa(s0);
  104. #ifdef IGNORE_ZERO_SIGN
  105. done:
  106. #endif
  107. return b - b0;
  108. }
  109. #endif