wref.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. #include "f2c.h"
  2. #include "fio.h"
  3. #ifndef KR_headers
  4. #undef abs
  5. #undef min
  6. #undef max
  7. #include "stdlib.h"
  8. #include "string.h"
  9. #endif
  10. #include "fmt.h"
  11. #include "fp.h"
  12. #ifndef VAX
  13. #include "ctype_.h"
  14. #ifdef __cplusplus
  15. extern "C" {
  16. #endif
  17. #endif
  18. int
  19. #ifdef KR_headers
  20. wrt_E(p,w,d,e,len) ufloat *p; ftnlen len;
  21. #else
  22. wrt_E(ufloat *p, int w, int d, int e, ftnlen len)
  23. #endif
  24. {
  25. char buf[FMAX+EXPMAXDIGS+4], *s, *se;
  26. int d1, delta, e1, i, sign, signspace;
  27. double dd;
  28. #ifdef WANT_LEAD_0
  29. int insert0 = 0;
  30. #endif
  31. #ifndef VAX
  32. int e0 = e;
  33. #endif
  34. if(e <= 0)
  35. e = 2;
  36. if(f__scale) {
  37. if(f__scale >= d + 2 || f__scale <= -d)
  38. goto nogood;
  39. }
  40. if(f__scale <= 0)
  41. --d;
  42. if (len == sizeof(real))
  43. dd = p->pf;
  44. else
  45. dd = p->pd;
  46. if (dd < 0.) {
  47. signspace = sign = 1;
  48. dd = -dd;
  49. }
  50. else {
  51. sign = 0;
  52. signspace = (int)f__cplus;
  53. #ifndef VAX
  54. if (!dd) {
  55. #ifdef SIGNED_ZEROS
  56. if (signbit_f2c(&dd))
  57. signspace = sign = 1;
  58. #endif
  59. dd = 0.; /* avoid -0 */
  60. }
  61. #endif
  62. }
  63. delta = w - (2 /* for the . and the d adjustment above */
  64. + 2 /* for the E+ */ + signspace + d + e);
  65. #ifdef WANT_LEAD_0
  66. if (f__scale <= 0 && delta > 0) {
  67. delta--;
  68. insert0 = 1;
  69. }
  70. else
  71. #endif
  72. if (delta < 0) {
  73. nogood:
  74. while(--w >= 0)
  75. PUT('*');
  76. return(0);
  77. }
  78. if (f__scale < 0)
  79. d += f__scale;
  80. if (d > FMAX) {
  81. d1 = d - FMAX;
  82. d = FMAX;
  83. }
  84. else
  85. d1 = 0;
  86. sprintf(buf,"%#.*E", d, dd);
  87. #ifndef VAX
  88. /* check for NaN, Infinity */
  89. if (!isdigit(buf[0])) {
  90. switch(buf[0]) {
  91. case 'n':
  92. case 'N':
  93. signspace = 0; /* no sign for NaNs */
  94. }
  95. delta = w - strlen(buf) - signspace;
  96. if (delta < 0)
  97. goto nogood;
  98. while(--delta >= 0)
  99. PUT(' ');
  100. if (signspace)
  101. PUT(sign ? '-' : '+');
  102. for(s = buf; *s; s++)
  103. PUT(*s);
  104. return 0;
  105. }
  106. #endif
  107. se = buf + d + 3;
  108. #ifdef GOOD_SPRINTF_EXPONENT /* When possible, exponent has 2 digits. */
  109. if (f__scale != 1 && dd)
  110. sprintf(se, "%+.2d", atoi(se) + 1 - f__scale);
  111. #else
  112. if (dd)
  113. sprintf(se, "%+.2d", atoi(se) + 1 - f__scale);
  114. else
  115. strcpy(se, "+00");
  116. #endif
  117. s = ++se;
  118. if (e < 2) {
  119. if (*s != '0')
  120. goto nogood;
  121. }
  122. #ifndef VAX
  123. /* accommodate 3 significant digits in exponent */
  124. if (s[2]) {
  125. #ifdef Pedantic
  126. if (!e0 && !s[3])
  127. for(s -= 2, e1 = 2; s[0] = s[1]; s++);
  128. /* Pedantic gives the behavior that Fortran 77 specifies, */
  129. /* i.e., requires that E be specified for exponent fields */
  130. /* of more than 3 digits. With Pedantic undefined, we get */
  131. /* the behavior that Cray displays -- you get a bigger */
  132. /* exponent field if it fits. */
  133. #else
  134. if (!e0) {
  135. for(s -= 2, e1 = 2; s[0] = s[1]; s++)
  136. #ifdef CRAY
  137. delta--;
  138. if ((delta += 4) < 0)
  139. goto nogood
  140. #endif
  141. ;
  142. }
  143. #endif
  144. else if (e0 >= 0)
  145. goto shift;
  146. else
  147. e1 = e;
  148. }
  149. else
  150. shift:
  151. #endif
  152. for(s += 2, e1 = 2; *s; ++e1, ++s)
  153. if (e1 >= e)
  154. goto nogood;
  155. while(--delta >= 0)
  156. PUT(' ');
  157. if (signspace)
  158. PUT(sign ? '-' : '+');
  159. s = buf;
  160. i = f__scale;
  161. if (f__scale <= 0) {
  162. #ifdef WANT_LEAD_0
  163. if (insert0)
  164. PUT('0');
  165. #endif
  166. PUT('.');
  167. for(; i < 0; ++i)
  168. PUT('0');
  169. PUT(*s);
  170. s += 2;
  171. }
  172. else if (f__scale > 1) {
  173. PUT(*s);
  174. s += 2;
  175. while(--i > 0)
  176. PUT(*s++);
  177. PUT('.');
  178. }
  179. if (d1) {
  180. se -= 2;
  181. while(s < se) PUT(*s++);
  182. se += 2;
  183. do PUT('0'); while(--d1 > 0);
  184. }
  185. while(s < se)
  186. PUT(*s++);
  187. if (e < 2)
  188. PUT(s[1]);
  189. else {
  190. while(++e1 <= e)
  191. PUT('0');
  192. while(*s)
  193. PUT(*s++);
  194. }
  195. return 0;
  196. }
  197. int
  198. #ifdef KR_headers
  199. wrt_F(p,w,d,len) ufloat *p; ftnlen len;
  200. #else
  201. wrt_F(ufloat *p, int w, int d, ftnlen len)
  202. #endif
  203. {
  204. int d1, sign, n;
  205. double x;
  206. char *b, buf[MAXINTDIGS+MAXFRACDIGS+4], *s;
  207. x= (len==sizeof(real)?p->pf:p->pd);
  208. if (d < MAXFRACDIGS)
  209. d1 = 0;
  210. else {
  211. d1 = d - MAXFRACDIGS;
  212. d = MAXFRACDIGS;
  213. }
  214. if (x < 0.)
  215. { x = -x; sign = 1; }
  216. else {
  217. sign = 0;
  218. #ifndef VAX
  219. if (!x) {
  220. #ifdef SIGNED_ZEROS
  221. if (signbit_f2c(&x))
  222. sign = 2;
  223. #endif
  224. x = 0.;
  225. }
  226. #endif
  227. }
  228. if (n = f__scale)
  229. if (n > 0)
  230. do x *= 10.; while(--n > 0);
  231. else
  232. do x *= 0.1; while(++n < 0);
  233. #ifdef USE_STRLEN
  234. sprintf(b = buf, "%#.*f", d, x);
  235. n = strlen(b) + d1;
  236. #else
  237. n = sprintf(b = buf, "%#.*f", d, x) + d1;
  238. #endif
  239. #ifndef WANT_LEAD_0
  240. if (buf[0] == '0' && d)
  241. { ++b; --n; }
  242. #endif
  243. if (sign == 1) {
  244. /* check for all zeros */
  245. for(s = b;;) {
  246. while(*s == '0') s++;
  247. switch(*s) {
  248. case '.':
  249. s++; continue;
  250. case 0:
  251. sign = 0;
  252. }
  253. break;
  254. }
  255. }
  256. if (sign || f__cplus)
  257. ++n;
  258. if (n > w) {
  259. #ifdef WANT_LEAD_0
  260. if (buf[0] == '0' && --n == w)
  261. ++b;
  262. else
  263. #endif
  264. {
  265. while(--w >= 0)
  266. PUT('*');
  267. return 0;
  268. }
  269. }
  270. for(w -= n; --w >= 0; )
  271. PUT(' ');
  272. if (sign)
  273. PUT('-');
  274. else if (f__cplus)
  275. PUT('+');
  276. while(n = *b++)
  277. PUT(n);
  278. while(--d1 >= 0)
  279. PUT('0');
  280. return 0;
  281. }
  282. #ifdef __cplusplus
  283. }
  284. #endif