gcvt.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. /*
  2. * gcvt.c - conversion for printing a floating point number
  3. */
  4. /* $Header$ */
  5. #ifndef NOFLOAT
  6. #include "loc_incl.h"
  7. #define NDIGINEXP(exp) (((exp) >= 100 || (exp) <= -100) ? 3 : 2)
  8. #define LOW_EXP -4
  9. #define USE_EXP(exp, ndigits) (((exp) < LOW_EXP + 1) || (exp >= ndigits + 1))
  10. char *
  11. _gcvt(long double value, int ndigit, char *s, int flags)
  12. {
  13. int sign, dp;
  14. register char *s1, *s2;
  15. register int i;
  16. register int nndigit = ndigit;
  17. s1 = _ecvt(value, ndigit, &dp, &sign);
  18. s2 = s;
  19. if (sign) *s2++ = '-';
  20. else if (flags & FL_SIGN)
  21. *s2++ = '+';
  22. else if (flags & FL_SPACE)
  23. *s2++ = ' ';
  24. if (!(flags & FL_ALT))
  25. for (i = nndigit - 1; i > 0 && s1[i] == '0'; i--)
  26. nndigit--;
  27. if (USE_EXP(dp,ndigit)) {
  28. /* Use E format */
  29. dp--;
  30. *s2++ = *s1++;
  31. if ((nndigit > 1) || (flags & FL_ALT)) *s2++ = '.';
  32. while (--nndigit > 0) *s2++ = *s1++;
  33. *s2++ = 'e';
  34. if (dp < 0) {
  35. *s2++ = '-';
  36. dp = -dp;
  37. }
  38. else *s2++ = '+';
  39. s2 += NDIGINEXP(dp);
  40. *s2 = 0;
  41. for (i = NDIGINEXP(dp); i > 0; i--) {
  42. *--s2 = dp % 10 + '0';
  43. dp /= 10;
  44. }
  45. return s;
  46. }
  47. /* Use f format */
  48. if (dp <= 0) {
  49. if (*s1 != '0') {
  50. /* otherwise the whole number is 0 */
  51. *s2++ = '0';
  52. *s2++ = '.';
  53. }
  54. while (dp < 0) {
  55. dp++;
  56. *s2++ = '0';
  57. }
  58. }
  59. for (i = 1; i <= nndigit; i++) {
  60. *s2++ = *s1++;
  61. if (i == dp) *s2++ = '.';
  62. }
  63. if (i <= dp) {
  64. while (i++ <= dp) *s2++ = '0';
  65. *s2++ = '.';
  66. }
  67. if ((s2[-1]=='.') && !(flags & FL_ALT)) s2--;
  68. *s2 = '\0';
  69. return s;
  70. }
  71. #endif /* NOFLOAT */