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

SCSI/ASPI

开发平台:

MultiPlatform

  1. /* @(#)fconv.c 1.22 00/01/22 Copyright 1985 J. Schilling */
  2. /*
  3.  * Convert floating point numbers to strings for format.c
  4.  * Should rather use the MT-safe routines [efg]convert()
  5.  *
  6.  * Copyright (c) 1985 J. Schilling
  7.  */
  8. /*
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2, or (at your option)
  12.  * any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; see the file COPYING.  If not, write to
  21.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23. #include <mconfig.h> /* <- may define NO_FLOATINGPOINT */
  24. #ifndef NO_FLOATINGPOINT
  25. #include <stdxlib.h>
  26. #include <standard.h>
  27. #include <strdefs.h>
  28. #if !defined(HAVE_STDLIB_H) || defined(HAVE_DTOA)
  29. extern char *ecvt __PR((double, int, int *, int *));
  30. extern char *fcvt __PR((double, int, int *, int *));
  31. #endif
  32. #include <math.h>
  33. #if defined(__hpux) || defined(VMS) || defined(_SCO_DS) || defined(__QNX__)
  34. #ifndef isnan
  35. #define isnan(val) (0)
  36. #endif
  37. #ifndef isinf
  38. #define isinf(val) (0)
  39. #endif
  40. #endif
  41. #ifdef SVR4
  42. #include <ieeefp.h>
  43. #define isnan isnand
  44. #define isinf !finite
  45. #endif
  46. #if defined(__osf__) || defined(_IBMR2) || defined(_AIX)
  47. #include <fp.h> 
  48. #define isinf !FINITE
  49. /*#define isinf IS_INF*/
  50. #define isnan IS_NAN
  51. #endif 
  52. #if !defined(HAVE_ECVT) || !defined(HAVE_FCVT) || !defined(HAVE_GCVT)
  53. #include "cvt.c"
  54. #endif
  55. static char _nan[] = "(NaN)";
  56. static char _inf[] = "(Infinity)";
  57. static int _ferr __PR((char *, double));
  58. #ifdef abs
  59. # undef abs
  60. #endif
  61. #define abs(i) ((i) < 0 ? -(i) : (i))
  62. EXPORT int
  63. ftoes(s, val, fieldwidth, ndigits)
  64. register char  *s;
  65. double val;
  66. register int fieldwidth;
  67. register int ndigits;
  68. {
  69. register char *b;
  70. register char *rs;
  71. register int len;
  72. register int rdecpt;
  73. int  decpt;
  74. int sign;
  75. if ((len = _ferr(s, val)) > 0)
  76. return len;
  77. rs = s;
  78. #ifdef V7_FLOATSTYLE
  79. b = ecvt(val, ndigits, &decpt, &sign);
  80. rdecpt = decpt;
  81. #else
  82. b = ecvt(val, ndigits+1, &decpt, &sign);
  83. rdecpt = decpt-1;
  84. #endif
  85. len = ndigits + 6; /* Punkt e +/- nnn */
  86. if (sign)
  87. len++;
  88. if (fieldwidth > len)
  89. while (fieldwidth-- > len)
  90. *rs++ = ' ';
  91. if (sign)
  92. *rs++ = '-';
  93. #ifndef V7_FLOATSTYLE
  94. if (*b)
  95. *rs++ = *b++;
  96. #endif
  97. *rs++ = '.';
  98. while (*b && ndigits-- > 0)
  99. *rs++ = *b++;
  100. *rs++ = 'e';
  101. *rs++ = rdecpt >= 0 ? '+' : '-';
  102. rdecpt = abs(rdecpt);
  103. #ifndef V7_FLOATSTYLE
  104. if (rdecpt >= 100)
  105. #endif
  106. {
  107. *rs++ = rdecpt / 100 + '0';
  108. rdecpt %= 100;
  109. }
  110. *rs++ = rdecpt / 10 + '0';
  111. *rs++ = rdecpt % 10 + '0';
  112. *rs = '';
  113. return rs - s;
  114. }
  115. /*
  116.  * fcvt() from Cygwin32 is buggy.
  117.  */
  118. #if !defined(HAVE_FCVT) && defined(HAVE_ECVT)
  119. #define USE_ECVT
  120. #endif
  121. EXPORT int
  122. ftofs(s, val, fieldwidth, ndigits)
  123. register char  *s;
  124. double val;
  125. register int fieldwidth;
  126. register int ndigits;
  127. {
  128. register char *b;
  129. register char *rs;
  130. register int len;
  131. register int rdecpt;
  132. int  decpt;
  133. int sign;
  134. if ((len = _ferr(s, val)) > 0)
  135. return len;
  136. rs = s;
  137. #ifdef USE_ECVT
  138. b = ecvt(val, ndigits, &decpt, &sign);
  139. #else
  140. b = fcvt(val, ndigits, &decpt, &sign);
  141. #endif
  142. rdecpt = decpt;
  143. len = rdecpt + ndigits + 1;
  144. if (rdecpt < 0)
  145. len -= rdecpt;
  146. if (sign)
  147. len++;
  148. if (fieldwidth > len)
  149. while (fieldwidth-- > len)
  150. *rs++ = ' ';
  151. if (sign)
  152. *rs++ = '-';
  153. if (rdecpt > 0) {
  154. len = rdecpt;
  155. while (*b && len-- > 0)
  156. *rs++ = *b++;
  157. }
  158. #ifndef V7_FLOATSTYLE
  159. else {
  160. *rs++ = '0';
  161. }
  162. #endif
  163. *rs++ = '.';
  164. if (rdecpt < 0) {
  165. len = rdecpt;
  166. while (len++ < 0 && ndigits-- > 0)
  167. *rs++ = '0';
  168. }
  169. while (*b && ndigits-- > 0)
  170. *rs++ = *b++;
  171. #ifdef USE_ECVT
  172. while (ndigits-- > 0)
  173. *rs++ = '0';
  174. #endif
  175. *rs = '';
  176. return rs - s;
  177. }
  178. LOCAL int
  179. _ferr(s, val)
  180. char *s;
  181. double val;
  182. {
  183. if (isnan(val)){
  184. strcpy(s, _nan);
  185. return (sizeof (_nan) - 1);
  186. }
  187. /*
  188.  * Check first for NaN because finite() will return 1 on Nan too.
  189.  */
  190. if (isinf(val)){
  191. strcpy(s, _inf);
  192. return (sizeof (_inf) - 1);
  193. }
  194. return 0;
  195. }
  196. #endif /* NO_FLOATINGPOINT */