gcvt.c 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. /* $Id$ */
  2. #ifndef NOFLOAT
  3. extern char *ecvt();
  4. #define NDIGINEXP(exp) (((exp) >= 100 || (exp) <= -100) ? 3 : 2)
  5. char *
  6. gcvt(value, ndigit, buf)
  7. double value;
  8. char *buf;
  9. int ndigit;
  10. {
  11. int sign, dp;
  12. register char *s1, *s2;
  13. register int i;
  14. register int nndigit = ndigit;
  15. s1 = ecvt(value, ndigit, &dp, &sign);
  16. s2 = buf;
  17. if (sign) *s2++ = '-';
  18. for (i = nndigit - 1; i > 0 && s1[i] == '0'; i--) nndigit--;
  19. if (dp > ndigit || dp < -(NDIGINEXP(dp)+1)) {
  20. /* Use E format, otherwise we need too many '0''s */
  21. dp--;
  22. *s2++ = *s1++;
  23. *s2++ = '.';
  24. while (--nndigit > 0) *s2++ = *s1++;
  25. *s2++ = 'e';
  26. if (dp < 0) {
  27. *s2++ = '-';
  28. dp = -dp;
  29. }
  30. else *s2++ = '+';
  31. s2 += NDIGINEXP(dp);
  32. *s2 = 0;
  33. for (i = NDIGINEXP(dp); i > 0; i--) {
  34. *--s2 = dp % 10 + '0';
  35. dp /= 10;
  36. }
  37. return buf;
  38. }
  39. if (dp <= 0) {
  40. if (*s1 != '0') {
  41. /* otherwise the whole number is 0 */
  42. *s2++ = '0';
  43. *s2++ = '.';
  44. }
  45. while (dp < 0) {
  46. dp++;
  47. *s2++ = '0';
  48. }
  49. }
  50. for (i = 1; i <= nndigit; i++) {
  51. *s2++ = *s1++;
  52. if (i == dp) *s2++ = '.';
  53. }
  54. if (i <= dp) {
  55. while (i++ <= dp) *s2++ = '0';
  56. *s2++ = '.';
  57. }
  58. if (s2[-1]=='.') s2--;
  59. *s2 = '\0';
  60. return buf;
  61. }
  62. #endif