cvt.c
上传用户:xiejiait
上传日期:2007-01-06
资源大小:881k
文件大小:5k
源码类别:

SCSI/ASPI

开发平台:

MultiPlatform

  1. /* @(#)cvt.c 1.3 99/09/08 Copyright 1998 J. Schilling */
  2. /*
  3.  * Compatibility routines for 4.4BSD based C-libraries ecvt()/fcvt()
  4.  * and a working gcvt() that is needed on 4.4BSD and GNU libc systems.
  5.  *
  6.  * On 4.4BSD, gcvt() is missing, the gcvt() implementation from GNU libc
  7.  * is not working correctly.
  8.  *
  9.  * Neither __dtoa() nor [efg]cvt() are MT safe.
  10.  *
  11.  * Copyright (c) 1998 J. Schilling
  12.  */
  13. /*
  14.  * This program is free software; you can redistribute it and/or modify
  15.  * it under the terms of the GNU General Public License as published by
  16.  * the Free Software Foundation; either version 2, or (at your option)
  17.  * any later version.
  18.  *
  19.  * This program is distributed in the hope that it will be useful,
  20.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22.  * GNU General Public License for more details.
  23.  *
  24.  * You should have received a copy of the GNU General Public License
  25.  * along with this program; see the file COPYING.  If not, write to
  26.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  27.  */
  28. #include <stdxlib.h>
  29. #include <utypes.h>
  30. #include <standard.h>
  31. #ifdef HAVE_DTOA /* 4.4BSD floating point implementation */
  32. extern char *__dtoa __PR((double value, int mode, int ndigit, int *decpt, int *sign, char **ep));
  33. #endif
  34. #ifndef HAVE_ECVT
  35. EXPORT char *ecvt __PR((double value, int ndigit, int *decpt, int *sign));
  36. #endif
  37. #ifndef HAVE_FCVT
  38. EXPORT char *fcvt __PR((double value, int ndigit, int *decpt, int *sign));
  39. #endif
  40. #ifndef HAVE_GCVT
  41. EXPORT char *gcvt __PR((double value, int ndigit, char *buf));
  42. #endif
  43. #if !defined(HAVE_ECVT) && defined(HAVE_DTOA)
  44. #define HAVE_ECVT
  45. char *
  46. ecvt(value, ndigit, decpt, sign)
  47. double value;
  48. int ndigit;
  49. int *decpt;
  50. int *sign;
  51. {
  52. static Uint bufsize;
  53. static char *buf;
  54. char *bufend;
  55. char *ep;
  56. char *bp = __dtoa(value, 2, ndigit, decpt, sign, &ep);
  57. if (value == 0.0) {
  58. /*
  59.  * Handle __dtoa()'s deviation from ecvt():
  60.  * 0.0 is converted to "0" instead of 'ndigit' zeroes.
  61.  * The string "0" is not allocated, so
  62.  * we need to allocate buffer to hold 'ndigit' zeroes.
  63.  */
  64. if (bufsize < ndigit + 1) {
  65. if (buf != (char *)0)
  66. free(buf);
  67. bufsize = ndigit + 1;
  68. buf = malloc(bufsize);
  69. }
  70. ep = bp = buf;
  71. }
  72. /*
  73.  * Fill up trailing zeroes suppressed by __dtoa()
  74.  * From an internal __dtoa() comment:
  75.  * Sufficient space is allocated to the return value
  76.  * to hold the suppressed trailing zeros.
  77.  */
  78. for (bufend = &bp[ndigit]; ep < bufend; )
  79. *ep++ = '0';
  80. *ep = '';
  81. return (bp);
  82. }
  83. #endif
  84. #if !defined(HAVE_FCVT) && defined(HAVE_DTOA)
  85. #define HAVE_FCVT
  86. char *
  87. fcvt(value, ndigit, decpt, sign)
  88. double value;
  89. int ndigit;
  90. int *decpt;
  91. int *sign;
  92. {
  93. static Uint bufsize;
  94. static char *buf;
  95. char *bufend;
  96. char *ep;
  97. char *bp = __dtoa(value, 3, ndigit, decpt, sign, &ep);
  98. if (value == 0.0) {
  99. /*
  100.  * Handle __dtoa()'s deviation from fcvt():
  101.  * 0.0 is converted to "0" instead of 'ndigit' zeroes.
  102.  * The string "0" is not allocated, so
  103.  * we need to allocate buffer to hold 'ndigit' zeroes.
  104.  */
  105. if (bufsize < ndigit + 1) {
  106. if (buf != (char *)0)
  107. free(buf);
  108. bufsize = ndigit + 1;
  109. buf = malloc(bufsize);
  110. }
  111. ep = bp = buf;
  112. *decpt = 0;
  113. }
  114. /*
  115.  * Fill up trailing zeroes suppressed by __dtoa()
  116.  * From an internal __dtoa() comment:
  117.  * Sufficient space is allocated to the return value
  118.  * to hold the suppressed trailing zeros.
  119.  */
  120. for (bufend = &bp[*decpt + ndigit]; ep < bufend; )
  121. *ep++ = '0';
  122. *ep = '';
  123. return (bp);
  124. }
  125. #endif
  126. #ifndef HAVE_GCVT
  127. #define HAVE_GCVT
  128. char *
  129. gcvt(number, ndigit, buf)
  130. double number;
  131. int ndigit;
  132. char *buf;
  133. {
  134.  int sign;
  135.  int decpt;
  136. register char *b;
  137. register char *rs;
  138. register int i;
  139. b = ecvt(number, ndigit, &decpt, &sign);
  140. rs = buf;
  141. if (sign)
  142. *rs++ = '-';
  143. for (i = ndigit-1; i > 0 && b[i] == '0'; i--)
  144. ndigit--;
  145. #ifdef V7_FLOATSTYLE
  146. if ((decpt >= 0 && decpt-ndigit > 4) ||
  147. #else
  148. if ((decpt >= 0 && decpt-ndigit > 0) ||
  149. #endif
  150.     (decpt < 0 && decpt < -3)) { /* e-format */
  151. decpt--;
  152. *rs++ = *b++;
  153. *rs++ = '.';
  154. for (i = 1; i < ndigit; i++)
  155. *rs++ = *b++;
  156. *rs++ = 'e';
  157. if (decpt < 0) {
  158. decpt = -decpt;
  159. *rs++ = '-';
  160. } else {
  161. *rs++ = '+';
  162. }
  163. if (decpt >= 100) {
  164. *rs++ = decpt / 100 + '0';
  165. decpt %= 100;
  166. }
  167. *rs++ = decpt / 10 + '0';
  168. *rs++ = decpt % 10 + '0';
  169. } else { /* f-format */
  170. if (decpt <= 0) {
  171. if (*b != '0') {
  172. #ifndef V7_FLOATSTYLE
  173. *rs++ = '0';
  174. #endif
  175. *rs++ = '.';
  176. }
  177. while (decpt < 0) {
  178. decpt++;
  179. *rs++ = '0';
  180. }
  181. }
  182. for (i = 1; i <= ndigit; i++) {
  183. *rs++ = *b++;
  184. if (i == decpt)
  185. *rs++ = '.';
  186. }
  187. if (ndigit < decpt) {
  188. while (ndigit++ < decpt)
  189. *rs++ = '0';
  190. *rs++ = '.';
  191. }
  192. }
  193. if (rs[-1] == '.')
  194. rs--;
  195. *rs = '';
  196. return (buf);
  197. }
  198. #endif