free.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. /* Free-format floating point printer */
  2. /*
  3. * All software (c) 1996 Robert G. Burger.
  4. * Permission is hereby granted, free of charge, to any person
  5. * obtaining a copy of this software, to deal in the software without
  6. * restriction, including without limitation the rights to use, copy,
  7. * modify, merge, publish, distribute, sublicense, and/or sell copies
  8. * of the software.
  9. * The software is provided "as is," without warranty of any kind,
  10. * express or implied, including but not limited to the warranties of
  11. * merchantability, fitness for a particular purpose and
  12. * noninfringement. In no event shall the author be liable for any
  13. * claim, damages or other liability, whether in an action of
  14. * contract, tort or otherwise, arising from, out of or in connection
  15. * with the software or the use or other dealings in the software.
  16. */
  17. /*
  18. * Modifications for Scheme 48 by Mike Sperber, Eric Knauel,
  19. * David Frese, Taylor Campbell
  20. */
  21. #include <stdio.h>
  22. #include <string.h>
  23. #ifndef _WIN32
  24. #include "sysdep.h"
  25. #endif
  26. /* It's a shame ... */
  27. #ifdef _WIN32
  28. typedef unsigned long word32_t;
  29. #define UNSIGNED64 unsigned _int64
  30. #else
  31. #define UNSIGNED64 unsigned long long
  32. #include <inttypes.h>
  33. typedef uint32_t word32_t;
  34. #endif
  35. #define U32 word32_t
  36. /* exponent stored + 1024, hidden bit to left of decimal point */
  37. #define bias 1023
  38. #define bitstoright 52
  39. #define m1mask 0xf
  40. #define hidden_bit 0x100000
  41. #define sign_mask 0x80000000
  42. #define exp_mask 0x7ff00000
  43. #define exp_max 0x7ff
  44. #define exp_shift1 20
  45. #define frac_mask 0xfffff
  46. typedef union { double d; word32_t word[2]; } double_overlay;
  47. #if ((defined(BUILD_UNIVERSAL_BINARY) && defined(__BIG_ENDIAN__)) || IEEE_MOST_FIRST)
  48. #define DOUBLE_WORD0(x) ((double_overlay*)&(x))->word[0]
  49. #define DOUBLE_WORD1(x) ((double_overlay*)&(x))->word[1]
  50. #else
  51. #define DOUBLE_WORD0(x) ((double_overlay*)&(x))->word[1]
  52. #define DOUBLE_WORD1(x) ((double_overlay*)&(x))->word[0]
  53. #endif
  54. #define float_radix 2.147483648e9
  55. typedef UNSIGNED64 Bigit;
  56. #define BIGSIZE 24
  57. #define MIN_E -1074
  58. #define MAX_FIVE 325
  59. #define B_P1 ((Bigit)1 << 52)
  60. typedef struct {
  61. int l;
  62. Bigit d[BIGSIZE];
  63. } Bignum;
  64. Bignum R, S, MP, MM, five[MAX_FIVE];
  65. Bignum S2, S3, S4, S5, S6, S7, S8, S9;
  66. int ruf, k, s_n, use_mp, qr_shift, sl, slr;
  67. static void mul10(Bignum *x);
  68. static void big_short_mul(Bignum *x, Bigit y, Bignum *z);
  69. static void print_big (Bignum *x);
  70. static int estimate(int n);
  71. static void one_shift_left(int y, Bignum *z);
  72. static void short_shift_left(Bigit x, int y, Bignum *z);
  73. static void big_shift_left(Bignum *x, int y, Bignum *z);
  74. static int big_comp(Bignum *x, Bignum *y);
  75. static int sub_big(Bignum *x, Bignum *y, Bignum *z);
  76. static void add_big(Bignum *x, Bignum *y, Bignum *z);
  77. static int add_cmp(void);
  78. static int qr(void);
  79. int s48_dragon(char *buf, double v);
  80. void s48_free_init(void);
  81. #define ADD(x, y, z, k) {\
  82. Bigit x_add, z_add;\
  83. x_add = (x);\
  84. if ((k))\
  85. z_add = x_add + (y) + 1, (k) = (z_add <= x_add);\
  86. else\
  87. z_add = x_add + (y), (k) = (z_add < x_add);\
  88. (z) = z_add;\
  89. }
  90. #define SUB(x, y, z, b) {\
  91. Bigit x_sub, y_sub;\
  92. x_sub = (x); y_sub = (y);\
  93. if ((b))\
  94. (z) = x_sub - y_sub - 1, b = (y_sub >= x_sub);\
  95. else\
  96. (z) = x_sub - y_sub, b = (y_sub > x_sub);\
  97. }
  98. #define MUL(x, y, z, k) {\
  99. Bigit x_mul, low, high;\
  100. x_mul = (x);\
  101. low = (x_mul & 0xffffffff) * (y) + (k);\
  102. high = (x_mul >> 32) * (y) + (low >> 32);\
  103. (k) = high >> 32;\
  104. (z) = (low & 0xffffffff) | (high << 32);\
  105. }
  106. #define SLL(x, y, z, k) {\
  107. Bigit x_sll = (x);\
  108. (z) = (x_sll << (y)) | (k);\
  109. (k) = x_sll >> (64 - (y));\
  110. }
  111. void mul10(x) Bignum *x; {
  112. int i, l;
  113. Bigit *p, k;
  114. l = x->l;
  115. for (i = l, p = &x->d[0], k = 0; i >= 0; i--)
  116. MUL(*p, 10, *p++, k);
  117. if (k != 0)
  118. *p = k, x->l = l+1;
  119. }
  120. void big_short_mul(x, y, z) Bignum *x, *z; Bigit y; {
  121. int i, xl, zl;
  122. Bigit *xp, *zp, k;
  123. U32 high, low;
  124. xl = x->l;
  125. xp = &x->d[0];
  126. zl = xl;
  127. zp = &z->d[0];
  128. high = y >> 32;
  129. low = y & 0xffffffff;
  130. for (i = xl, k = 0; i >= 0; i--, xp++, zp++) {
  131. Bigit xlow, xhigh, z0, t, c, z1;
  132. xlow = *xp & 0xffffffff;
  133. xhigh = *xp >> 32;
  134. z0 = (xlow * low) + k; /* Cout is (z0 < k) */
  135. t = xhigh * low;
  136. z1 = (xlow * high) + t;
  137. c = (z1 < t);
  138. t = z0 >> 32;
  139. z1 += t;
  140. c += (z1 < t);
  141. *zp = (z1 << 32) | (z0 & 0xffffffff);
  142. k = (xhigh * high) + (c << 32) + (z1 >> 32) + (z0 < k);
  143. }
  144. if (k != 0)
  145. *zp = k, zl++;
  146. z->l = zl;
  147. }
  148. void print_big(x) Bignum *x; {
  149. int i;
  150. Bigit *p;
  151. printf("#x");
  152. i = x->l;
  153. p = &x->d[i];
  154. for (p = &x->d[i]; i >= 0; i--) {
  155. Bigit b = *p--;
  156. printf("%08x%08x", (int)(b >> 32), (int)(b & 0xffffffff));
  157. }
  158. }
  159. int estimate(n) int n; {
  160. if (n < 0)
  161. return (int)(n*0.3010299956639812);
  162. else
  163. return 1+(int)(n*0.3010299956639811);
  164. }
  165. void one_shift_left(y, z) int y; Bignum *z; {
  166. int n, m, i;
  167. Bigit *zp;
  168. n = y / 64;
  169. m = y % 64;
  170. zp = &z->d[0];
  171. for (i = n; i > 0; i--) *zp++ = 0;
  172. *zp = (Bigit)1 << m;
  173. z->l = n;
  174. }
  175. void short_shift_left(x, y, z) Bigit x; int y; Bignum *z; {
  176. int n, m, i, zl;
  177. Bigit *zp;
  178. n = y / 64;
  179. m = y % 64;
  180. zl = n;
  181. zp = &(z->d[0]);
  182. for (i = n; i > 0; i--) *zp++ = 0;
  183. if (m == 0)
  184. *zp = x;
  185. else {
  186. Bigit high = x >> (64 - m);
  187. *zp = x << m;
  188. if (high != 0)
  189. *++zp = high, zl++;
  190. }
  191. z->l = zl;
  192. }
  193. void big_shift_left(x, y, z) Bignum *x, *z; int y; {
  194. int n, m, i, xl, zl;
  195. Bigit *xp, *zp, k;
  196. n = y / 64;
  197. m = y % 64;
  198. xl = x->l;
  199. xp = &(x->d[0]);
  200. zl = xl + n;
  201. zp = &(z->d[0]);
  202. for (i = n; i > 0; i--) *zp++ = 0;
  203. if (m == 0)
  204. for (i = xl; i >= 0; i--) *zp++ = *xp++;
  205. else {
  206. for (i = xl, k = 0; i >= 0; i--)
  207. SLL(*xp++, m, *zp++, k);
  208. if (k != 0)
  209. *zp = k, zl++;
  210. }
  211. z->l = zl;
  212. }
  213. int big_comp(x, y) Bignum *x, *y; {
  214. int i, xl, yl;
  215. Bigit *xp, *yp;
  216. xl = x->l;
  217. yl = y->l;
  218. if (xl > yl) return 1;
  219. if (xl < yl) return -1;
  220. xp = &x->d[xl];
  221. yp = &y->d[xl];
  222. for (i = xl; i >= 0; i--, xp--, yp--) {
  223. Bigit a = *xp;
  224. Bigit b = *yp;
  225. if (a > b) return 1;
  226. else if (a < b) return -1;
  227. }
  228. return 0;
  229. }
  230. int sub_big(x, y, z) Bignum *x, *y, *z; {
  231. int xl, yl, zl, b, i;
  232. Bigit *xp, *yp, *zp;
  233. xl = x->l;
  234. yl = y->l;
  235. if (yl > xl) return 1;
  236. xp = &x->d[0];
  237. yp = &y->d[0];
  238. zp = &z->d[0];
  239. for (i = yl, b = 0; i >= 0; i--)
  240. SUB(*xp++, *yp++, *zp++, b);
  241. for (i = xl-yl; b && i > 0; i--) {
  242. Bigit x_sub;
  243. x_sub = *xp++;
  244. *zp++ = x_sub - 1;
  245. b = (x_sub == 0);
  246. }
  247. for (; i > 0; i--) *zp++ = *xp++;
  248. if (b) return 1;
  249. zl = xl;
  250. while ((zl > 0) && (*--zp == 0)) zl--;
  251. z->l = zl;
  252. return 0;
  253. }
  254. void add_big(x, y, z) Bignum *x, *y, *z; {
  255. int xl, yl, k, i;
  256. Bigit *xp, *yp, *zp;
  257. xl = x->l;
  258. yl = y->l;
  259. if (yl > xl) {
  260. int tl;
  261. Bignum *tn;
  262. tl = xl; xl = yl; yl = tl;
  263. tn = x; x = y; y = tn;
  264. }
  265. xp = &x->d[0];
  266. yp = &y->d[0];
  267. zp = &z->d[0];
  268. for (i = yl, k = 0; i >= 0; i--)
  269. ADD(*xp++, *yp++, *zp++, k);
  270. for (i = xl-yl; k && i > 0; i--) {
  271. Bigit z_add;
  272. z_add = *xp++ + 1;
  273. k = (z_add == 0);
  274. *zp++ = z_add;
  275. }
  276. for (; i > 0; i--) *zp++ = *xp++;
  277. if (k)
  278. *zp = 1, z->l = xl+1;
  279. else
  280. z->l = xl;
  281. }
  282. int add_cmp() {
  283. int rl, ml, sl, suml;
  284. static Bignum sum;
  285. rl = R.l;
  286. ml = (use_mp ? MP.l : MM.l);
  287. sl = S.l;
  288. suml = rl >= ml ? rl : ml;
  289. if ((sl > suml+1) || ((sl == suml+1) && (S.d[sl] > 1))) return -1;
  290. if (sl < suml) return 1;
  291. add_big(&R, (use_mp ? &MP : &MM), &sum);
  292. return big_comp(&sum, &S);
  293. }
  294. int qr() {
  295. if (big_comp(&R, &S5) < 0)
  296. if (big_comp(&R, &S2) < 0)
  297. if (big_comp(&R, &S) < 0)
  298. return 0;
  299. else {
  300. sub_big(&R, &S, &R);
  301. return 1;
  302. }
  303. else if (big_comp(&R, &S3) < 0) {
  304. sub_big(&R, &S2, &R);
  305. return 2;
  306. }
  307. else if (big_comp(&R, &S4) < 0) {
  308. sub_big(&R, &S3, &R);
  309. return 3;
  310. }
  311. else {
  312. sub_big(&R, &S4, &R);
  313. return 4;
  314. }
  315. else if (big_comp(&R, &S7) < 0)
  316. if (big_comp(&R, &S6) < 0) {
  317. sub_big(&R, &S5, &R);
  318. return 5;
  319. }
  320. else {
  321. sub_big(&R, &S6, &R);
  322. return 6;
  323. }
  324. else if (big_comp(&R, &S9) < 0)
  325. if (big_comp(&R, &S8) < 0) {
  326. sub_big(&R, &S7, &R);
  327. return 7;
  328. }
  329. else {
  330. sub_big(&R, &S8, &R);
  331. return 8;
  332. }
  333. else {
  334. sub_big(&R, &S9, &R);
  335. return 9;
  336. }
  337. }
  338. #define OUTDIG(d) { *buf++ = (d) + '0'; *buf = 0; return k; }
  339. int s48_dragon(buf, v) char *buf; double v; {
  340. int sign, e, f_n, m_n, i, d, tc1, tc2;
  341. word32_t word0 = DOUBLE_WORD0(v);
  342. word32_t word1 = DOUBLE_WORD1(v);
  343. Bigit f;
  344. /* decompose float into sign, mantissa & exponent */
  345. sign = ((word0 & sign_mask) != 0);
  346. e = (int)(word0 >> exp_shift1 & (exp_mask>>exp_shift1));
  347. f = (((Bigit)(word0 & frac_mask)) << 32) | word1;
  348. if (e == exp_max) {
  349. /* infinity or NaN */
  350. if (f == 0)
  351. strcpy(buf, sign ? "-inf.0" : "+inf.0");
  352. else
  353. strcpy(buf, "+nan.0");
  354. return 0;
  355. }
  356. if (e != 0) {
  357. e = e - bias - bitstoright;
  358. f |= (Bigit)hidden_bit << 32;
  359. }
  360. else if (f != 0)
  361. /* denormalized */
  362. e = 1 - bias - bitstoright;
  363. if (sign) *buf++ = '-';
  364. if (f == 0) {
  365. *buf++ = '0';
  366. *buf = 0;
  367. return 0;
  368. }
  369. ruf = !(f & 1); /* ruf = (even? f) */
  370. /* Compute the scaling factor estimate, k */
  371. if (e > MIN_E)
  372. k = estimate(e+52);
  373. else {
  374. int n;
  375. Bigit y;
  376. for (n = e+52, y = (Bigit)1 << 52; f < y; n--) y >>= 1;
  377. k = estimate(n);
  378. }
  379. if (e >= 0)
  380. if (f != B_P1)
  381. use_mp = 0, f_n = e+1, s_n = 1, m_n = e;
  382. else
  383. use_mp = 1, f_n = e+2, s_n = 2, m_n = e;
  384. else
  385. if ((e == MIN_E) || (f != B_P1))
  386. use_mp = 0, f_n = 1, s_n = 1-e, m_n = 0;
  387. else
  388. use_mp = 1, f_n = 2, s_n = 2-e, m_n = 0;
  389. /* Scale it! */
  390. if (k == 0) {
  391. short_shift_left(f, f_n, &R);
  392. one_shift_left(s_n, &S);
  393. one_shift_left(m_n, &MM);
  394. if (use_mp) one_shift_left(m_n+1, &MP);
  395. qr_shift = 1;
  396. }
  397. else if (k > 0) {
  398. s_n += k;
  399. if (m_n >= s_n)
  400. f_n -= s_n, m_n -= s_n, s_n = 0;
  401. else
  402. f_n -= m_n, s_n -= m_n, m_n = 0;
  403. short_shift_left(f, f_n, &R);
  404. big_shift_left(&five[k-1], s_n, &S);
  405. one_shift_left(m_n, &MM);
  406. if (use_mp) one_shift_left(m_n+1, &MP);
  407. qr_shift = 0;
  408. }
  409. else {
  410. Bignum *power = &five[-k-1];
  411. s_n += k;
  412. big_short_mul(power, f, &S);
  413. big_shift_left(&S, f_n, &R);
  414. one_shift_left(s_n, &S);
  415. big_shift_left(power, m_n, &MM);
  416. if (use_mp) big_shift_left(power, m_n+1, &MP);
  417. qr_shift = 1;
  418. }
  419. /* fixup */
  420. if (add_cmp() <= -ruf) {
  421. k--;
  422. mul10(&R);
  423. mul10(&MM);
  424. if (use_mp) mul10(&MP);
  425. }
  426. /*
  427. printf("\nk = %d\n", k);
  428. printf("R = "); print_big(&R);
  429. printf("\nS = "); print_big(&S);
  430. printf("\nM- = "); print_big(&MM);
  431. if (use_mp) printf("\nM+ = "), print_big(&MP);
  432. putchar('\n');
  433. fflush(0);
  434. */
  435. if (qr_shift) {
  436. sl = s_n / 64;
  437. slr = s_n % 64;
  438. }
  439. else {
  440. big_shift_left(&S, 1, &S2);
  441. add_big(&S2, &S, &S3);
  442. big_shift_left(&S2, 1, &S4);
  443. add_big(&S4, &S, &S5);
  444. add_big(&S4, &S2, &S6);
  445. add_big(&S4, &S3, &S7);
  446. big_shift_left(&S4, 1, &S8);
  447. add_big(&S8, &S, &S9);
  448. }
  449. again:
  450. if (qr_shift) { /* Take advantage of the fact that S = (ash 1 s_n) */
  451. if (R.l < sl)
  452. d = 0;
  453. else if (R.l == sl) {
  454. Bigit *p;
  455. p = &R.d[sl];
  456. d = *p >> slr;
  457. *p &= ((Bigit)1 << slr) - 1;
  458. for (i = sl; (i > 0) && (*p == 0); i--) p--;
  459. R.l = i;
  460. }
  461. else {
  462. Bigit *p;
  463. p = &R.d[sl+1];
  464. d = *p << (64 - slr) | *(p-1) >> slr;
  465. p--;
  466. *p &= ((Bigit)1 << slr) - 1;
  467. for (i = sl; (i > 0) && (*p == 0); i--) p--;
  468. R.l = i;
  469. }
  470. }
  471. else /* We need to do quotient-remainder */
  472. d = qr();
  473. tc1 = big_comp(&R, &MM) < ruf;
  474. tc2 = add_cmp() > -ruf;
  475. if (!tc1)
  476. if (!tc2) {
  477. mul10(&R);
  478. mul10(&MM);
  479. if (use_mp) mul10(&MP);
  480. *buf++ = d + '0';
  481. goto again;
  482. }
  483. else
  484. OUTDIG(d+1)
  485. else
  486. if (!tc2)
  487. OUTDIG(d)
  488. else {
  489. big_shift_left(&R, 1, &MM);
  490. if (big_comp(&MM, &S) == -1)
  491. OUTDIG(d)
  492. else
  493. OUTDIG(d+1)
  494. }
  495. }
  496. void s48_free_init() {
  497. int n, i, l;
  498. Bignum *b;
  499. Bigit *xp, *zp, k;
  500. five[0].l = l = 0;
  501. five[0].d[0] = 5;
  502. for (n = MAX_FIVE-1, b = &five[0]; n > 0; n--) {
  503. xp = &b->d[0];
  504. b++;
  505. zp = &b->d[0];
  506. for (i = l, k = 0; i >= 0; i--)
  507. MUL(*xp++, 5, *zp++, k);
  508. if (k != 0)
  509. *zp = k, l++;
  510. b->l = l;
  511. }
  512. /*
  513. for (n = 1, b = &five[0]; n <= MAX_FIVE; n++) {
  514. big_shift_left(b++, n, &R);
  515. print_big(&R);
  516. putchar('\n');
  517. }
  518. fflush(0);
  519. */
  520. }