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

SCSI/ASPI

开发平台:

MultiPlatform

  1. /* @(#)fconv.c 1.20 99/09/08 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)
  34. #define isnan(val) (0)
  35. #define isinf(val) (0)
  36. #endif
  37. #ifdef SVR4
  38. #include <ieeefp.h>
  39. #define isnan isnand
  40. #define isinf !finite
  41. #endif
  42. #if defined(__osf__) || defined(_IBMR2) || defined(_AIX)
  43. #include <fp.h> 
  44. #define isinf !FINITE
  45. /*#define isinf IS_INF*/
  46. #define isnan IS_NAN
  47. #endif 
  48. #if !defined(HAVE_ECVT) || !defined(HAVE_FCVT) || !defined(HAVE_GCVT)
  49. #include "cvt.c"
  50. #endif
  51. static char _nan[] = "(NaN)";
  52. static char _inf[] = "(Infinity)";
  53. static int _ferr __PR((char *, double));
  54. #ifdef abs
  55. # undef abs
  56. #endif
  57. #define abs(i) ((i) < 0 ? -(i) : (i))
  58. EXPORT int
  59. ftoes(s, val, fieldwidth, ndigits)
  60. register char  *s;
  61. double val;
  62. register int fieldwidth;
  63. register int ndigits;
  64. {
  65. register char *b;
  66. register char *rs;
  67. register int len;
  68. register int rdecpt;
  69. int  decpt;
  70. int sign;
  71. if ((len = _ferr(s, val)) > 0)
  72. return len;
  73. rs = s;
  74. #ifdef V7_FLOATSTYLE
  75. b = ecvt(val, ndigits, &decpt, &sign);
  76. rdecpt = decpt;
  77. #else
  78. b = ecvt(val, ndigits+1, &decpt, &sign);
  79. rdecpt = decpt-1;
  80. #endif
  81. len = ndigits + 6; /* Punkt e +/- nnn */
  82. if (sign)
  83. len++;
  84. if (fieldwidth > len)
  85. while (fieldwidth-- > len)
  86. *rs++ = ' ';
  87. if (sign)
  88. *rs++ = '-';
  89. #ifndef V7_FLOATSTYLE
  90. if (*b)
  91. *rs++ = *b++;
  92. #endif
  93. *rs++ = '.';
  94. while (*b && ndigits-- > 0)
  95. *rs++ = *b++;
  96. *rs++ = 'e';
  97. *rs++ = rdecpt >= 0 ? '+' : '-';
  98. rdecpt = abs(rdecpt);
  99. #ifndef V7_FLOATSTYLE
  100. if (rdecpt >= 100)
  101. #endif
  102. {
  103. *rs++ = rdecpt / 100 + '0';
  104. rdecpt %= 100;
  105. }
  106. *rs++ = rdecpt / 10 + '0';
  107. *rs++ = rdecpt % 10 + '0';
  108. *rs = '';
  109. return rs - s;
  110. }
  111. /*
  112.  * fcvt() from Cygwin32 is buggy.
  113.  */
  114. #if !defined(HAVE_FCVT) && defined(HAVE_ECVT)
  115. #define USE_ECVT
  116. #endif
  117. EXPORT int
  118. ftofs(s, val, fieldwidth, ndigits)
  119. register char  *s;
  120. double val;
  121. register int fieldwidth;
  122. register int ndigits;
  123. {
  124. register char *b;
  125. register char *rs;
  126. register int len;
  127. register int rdecpt;
  128. int  decpt;
  129. int sign;
  130. if ((len = _ferr(s, val)) > 0)
  131. return len;
  132. rs = s;
  133. #ifdef USE_ECVT
  134. b = ecvt(val, ndigits, &decpt, &sign);
  135. #else
  136. b = fcvt(val, ndigits, &decpt, &sign);
  137. #endif
  138. rdecpt = decpt;
  139. len = rdecpt + ndigits + 1;
  140. if (rdecpt < 0)
  141. len -= rdecpt;
  142. if (sign)
  143. len++;
  144. if (fieldwidth > len)
  145. while (fieldwidth-- > len)
  146. *rs++ = ' ';
  147. if (sign)
  148. *rs++ = '-';
  149. if (rdecpt > 0) {
  150. len = rdecpt;
  151. while (*b && len-- > 0)
  152. *rs++ = *b++;
  153. }
  154. #ifndef V7_FLOATSTYLE
  155. else {
  156. *rs++ = '0';
  157. }
  158. #endif
  159. *rs++ = '.';
  160. if (rdecpt < 0) {
  161. len = rdecpt;
  162. while (len++ < 0 && ndigits-- > 0)
  163. *rs++ = '0';
  164. }
  165. while (*b && ndigits-- > 0)
  166. *rs++ = *b++;
  167. #ifdef USE_ECVT
  168. while (ndigits-- > 0)
  169. *rs++ = '0';
  170. #endif
  171. *rs = '';
  172. return rs - s;
  173. }
  174. LOCAL int
  175. _ferr(s, val)
  176. char *s;
  177. double val;
  178. {
  179. if (isnan(val)){
  180. strcpy(s, _nan);
  181. return (sizeof (_nan) - 1);
  182. }
  183. /*
  184.  * Check first for NaN because finite() will return 1 on Nan too.
  185.  */
  186. if (isinf(val)){
  187. strcpy(s, _inf);
  188. return (sizeof (_inf) - 1);
  189. }
  190. return 0;
  191. }
  192. #endif /* NO_FLOATINGPOINT */