free.c 12 KB

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