g_fmt.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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. #ifdef __cplusplus
  24. extern "C" {
  25. #endif
  26. extern char *dtoa(double, int, int, int *, int *, char **);
  27. extern char *g_fmt(char *, double, int);
  28. extern void freedtoa(char*);
  29. #ifdef __cplusplus
  30. }
  31. #endif
  32. char *
  33. g_fmt(register char *b, double x, int echr)
  34. {
  35. register int i, k;
  36. register char *s;
  37. int decpt, j, sign;
  38. char *b0, *s0, *se;
  39. b0 = b;
  40. #ifdef IGNORE_ZERO_SIGN
  41. if (!x) {
  42. *b++ = '0';
  43. *b = 0;
  44. goto done;
  45. }
  46. #endif
  47. s = s0 = dtoa(x, 0, 0, &decpt, &sign, &se);
  48. if (sign)
  49. *b++ = '-';
  50. if (decpt == 9999) /* Infinity or Nan */ {
  51. while(*b++ = *s++);
  52. goto done0;
  53. }
  54. if (decpt <= -4 || decpt > se - s + 5) {
  55. *b++ = *s++;
  56. if (*s) {
  57. *b++ = '.';
  58. while(*b = *s++)
  59. b++;
  60. }
  61. *b++ = echr;
  62. /* sprintf(b, "%+.2d", decpt - 1); */
  63. if (--decpt < 0) {
  64. *b++ = '-';
  65. decpt = -decpt;
  66. }
  67. else
  68. *b++ = '+';
  69. for(j = 2, k = 10; 10*k <= decpt; j++, k *= 10);
  70. for(;;) {
  71. i = decpt / k;
  72. *b++ = i + '0';
  73. if (--j <= 0)
  74. break;
  75. decpt -= i*k;
  76. decpt *= 10;
  77. }
  78. *b = 0;
  79. }
  80. else if (decpt <= 0) {
  81. *b++ = '.';
  82. for(; decpt < 0; decpt++)
  83. *b++ = '0';
  84. while(*b++ = *s++);
  85. }
  86. else {
  87. while(*b = *s++) {
  88. b++;
  89. if (--decpt == 0 && *s)
  90. *b++ = '.';
  91. }
  92. for(; decpt > 0; decpt--)
  93. *b++ = '0';
  94. *b = 0;
  95. }
  96. done0:
  97. freedtoa(s0);
  98. #ifdef IGNORE_ZERO_SIGN
  99. done:
  100. #endif
  101. return b0;
  102. }