strtod.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. /*
  2. * The authors of this software are Rob Pike and Ken Thompson.
  3. * Copyright (c) 2002 by Lucent Technologies.
  4. * Permission to use, copy, modify, and distribute this software for any
  5. * purpose without fee is hereby granted, provided that this entire notice
  6. * is included in all copies of any software which is or includes a copy
  7. * or modification of this software and in all copies of the supporting
  8. * documentation for such software.
  9. * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
  10. * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
  11. * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
  12. * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
  13. */
  14. #include <stdlib.h>
  15. #include <math.h>
  16. #include <ctype.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <errno.h>
  20. #include "fmt.h"
  21. #include "nan.h"
  22. #ifndef nelem
  23. #define nelem(x) (sizeof(x)/sizeof *(x))
  24. #endif
  25. #define nil ((void*)0)
  26. #define ulong _fmtulong
  27. typedef unsigned long ulong;
  28. static ulong
  29. umuldiv(ulong a, ulong b, ulong c)
  30. {
  31. double d;
  32. d = ((double)a * (double)b) / (double)c;
  33. if(d >= 4294967295.)
  34. d = 4294967295.;
  35. return (ulong)d;
  36. }
  37. /*
  38. * This routine will convert to arbitrary precision
  39. * floating point entirely in multi-precision fixed.
  40. * The answer is the closest floating point number to
  41. * the given decimal number. Exactly half way are
  42. * rounded ala ieee rules.
  43. * Method is to scale input decimal between .500 and .999...
  44. * with external power of 2, then binary search for the
  45. * closest mantissa to this decimal number.
  46. * Nmant is is the required precision. (53 for ieee dp)
  47. * Nbits is the max number of bits/word. (must be <= 28)
  48. * Prec is calculated - the number of words of fixed mantissa.
  49. */
  50. enum
  51. {
  52. Nbits = 28, /* bits safely represented in a ulong */
  53. Nmant = 53, /* bits of precision required */
  54. Prec = (Nmant+Nbits+1)/Nbits, /* words of Nbits each to represent mantissa */
  55. Sigbit = 1<<(Prec*Nbits-Nmant), /* first significant bit of Prec-th word */
  56. Ndig = 1500,
  57. One = (ulong)(1<<Nbits),
  58. Half = (ulong)(One>>1),
  59. Maxe = 310,
  60. Fsign = 1<<0, /* found - */
  61. Fesign = 1<<1, /* found e- */
  62. Fdpoint = 1<<2, /* found . */
  63. S0 = 0, /* _ _S0 +S1 #S2 .S3 */
  64. S1, /* _+ #S2 .S3 */
  65. S2, /* _+# #S2 .S4 eS5 */
  66. S3, /* _+. #S4 */
  67. S4, /* _+#.# #S4 eS5 */
  68. S5, /* _+#.#e +S6 #S7 */
  69. S6, /* _+#.#e+ #S7 */
  70. S7, /* _+#.#e+# #S7 */
  71. };
  72. static int xcmp(char*, char*);
  73. static int fpcmp(char*, ulong*);
  74. static void frnorm(ulong*);
  75. static void divascii(char*, int*, int*, int*);
  76. static void mulascii(char*, int*, int*, int*);
  77. typedef struct Tab Tab;
  78. struct Tab
  79. {
  80. int bp;
  81. int siz;
  82. char* cmp;
  83. };
  84. double
  85. fmtstrtod(const char *as, char **aas)
  86. {
  87. int na, ex, dp, bp, c, i, flag, state;
  88. ulong low[Prec], hig[Prec], mid[Prec];
  89. double d;
  90. char *s, a[Ndig];
  91. flag = 0; /* Fsign, Fesign, Fdpoint */
  92. na = 0; /* number of digits of a[] */
  93. dp = 0; /* na of decimal point */
  94. ex = 0; /* exonent */
  95. state = S0;
  96. for(s=(char*)as;; s++) {
  97. c = *s;
  98. if(c >= '0' && c <= '9') {
  99. switch(state) {
  100. case S0:
  101. case S1:
  102. case S2:
  103. state = S2;
  104. break;
  105. case S3:
  106. case S4:
  107. state = S4;
  108. break;
  109. case S5:
  110. case S6:
  111. case S7:
  112. state = S7;
  113. ex = ex*10 + (c-'0');
  114. continue;
  115. }
  116. if(na == 0 && c == '0') {
  117. dp--;
  118. continue;
  119. }
  120. if(na < Ndig-50)
  121. a[na++] = c;
  122. continue;
  123. }
  124. switch(c) {
  125. case '\t':
  126. case '\n':
  127. case '\v':
  128. case '\f':
  129. case '\r':
  130. case ' ':
  131. if(state == S0)
  132. continue;
  133. break;
  134. case '-':
  135. if(state == S0)
  136. flag |= Fsign;
  137. else
  138. flag |= Fesign;
  139. case '+':
  140. if(state == S0)
  141. state = S1;
  142. else
  143. if(state == S5)
  144. state = S6;
  145. else
  146. break; /* syntax */
  147. continue;
  148. case '.':
  149. flag |= Fdpoint;
  150. dp = na;
  151. if(state == S0 || state == S1) {
  152. state = S3;
  153. continue;
  154. }
  155. if(state == S2) {
  156. state = S4;
  157. continue;
  158. }
  159. break;
  160. case 'e':
  161. case 'E':
  162. if(state == S2 || state == S4) {
  163. state = S5;
  164. continue;
  165. }
  166. break;
  167. }
  168. break;
  169. }
  170. /*
  171. * clean up return char-pointer
  172. */
  173. switch(state) {
  174. case S0:
  175. if(xcmp(s, "nan") == 0) {
  176. if(aas != nil)
  177. *aas = s+3;
  178. goto retnan;
  179. }
  180. case S1:
  181. if(xcmp(s, "infinity") == 0) {
  182. if(aas != nil)
  183. *aas = s+8;
  184. goto retinf;
  185. }
  186. if(xcmp(s, "inf") == 0) {
  187. if(aas != nil)
  188. *aas = s+3;
  189. goto retinf;
  190. }
  191. case S3:
  192. if(aas != nil)
  193. *aas = (char*)as;
  194. goto ret0; /* no digits found */
  195. case S6:
  196. s--; /* back over +- */
  197. case S5:
  198. s--; /* back over e */
  199. break;
  200. }
  201. if(aas != nil)
  202. *aas = s;
  203. if(flag & Fdpoint)
  204. while(na > 0 && a[na-1] == '0')
  205. na--;
  206. if(na == 0)
  207. goto ret0; /* zero */
  208. a[na] = 0;
  209. if(!(flag & Fdpoint))
  210. dp = na;
  211. if(flag & Fesign)
  212. ex = -ex;
  213. dp += ex;
  214. if(dp < -Maxe){
  215. errno = ERANGE;
  216. goto ret0; /* underflow by exp */
  217. } else
  218. if(dp > +Maxe)
  219. goto retinf; /* overflow by exp */
  220. /*
  221. * normalize the decimal ascii number
  222. * to range .[5-9][0-9]* e0
  223. */
  224. bp = 0; /* binary exponent */
  225. while(dp > 0)
  226. divascii(a, &na, &dp, &bp);
  227. while(dp < 0 || a[0] < '5')
  228. mulascii(a, &na, &dp, &bp);
  229. /* close approx by naive conversion */
  230. mid[0] = 0;
  231. mid[1] = 1;
  232. for(i=0; c=a[i]; i++) {
  233. mid[0] = mid[0]*10 + (c-'0');
  234. mid[1] = mid[1]*10;
  235. if(i >= 8)
  236. break;
  237. }
  238. low[0] = umuldiv(mid[0], One, mid[1]);
  239. hig[0] = umuldiv(mid[0]+1, One, mid[1]);
  240. for(i=1; i<Prec; i++) {
  241. low[i] = 0;
  242. hig[i] = One-1;
  243. }
  244. /* binary search for closest mantissa */
  245. for(;;) {
  246. /* mid = (hig + low) / 2 */
  247. c = 0;
  248. for(i=0; i<Prec; i++) {
  249. mid[i] = hig[i] + low[i];
  250. if(c)
  251. mid[i] += One;
  252. c = mid[i] & 1;
  253. mid[i] >>= 1;
  254. }
  255. frnorm(mid);
  256. /* compare */
  257. c = fpcmp(a, mid);
  258. if(c > 0) {
  259. c = 1;
  260. for(i=0; i<Prec; i++)
  261. if(low[i] != mid[i]) {
  262. c = 0;
  263. low[i] = mid[i];
  264. }
  265. if(c)
  266. break; /* between mid and hig */
  267. continue;
  268. }
  269. if(c < 0) {
  270. for(i=0; i<Prec; i++)
  271. hig[i] = mid[i];
  272. continue;
  273. }
  274. /* only hard part is if even/odd roundings wants to go up */
  275. c = mid[Prec-1] & (Sigbit-1);
  276. if(c == Sigbit/2 && (mid[Prec-1]&Sigbit) == 0)
  277. mid[Prec-1] -= c;
  278. break; /* exactly mid */
  279. }
  280. /* normal rounding applies */
  281. c = mid[Prec-1] & (Sigbit-1);
  282. mid[Prec-1] -= c;
  283. if(c >= Sigbit/2) {
  284. mid[Prec-1] += Sigbit;
  285. frnorm(mid);
  286. }
  287. goto out;
  288. ret0:
  289. return 0;
  290. retnan:
  291. return __NaN();
  292. retinf:
  293. /*
  294. * Unix strtod requires these. Plan 9 would return Inf(0) or Inf(-1). */
  295. errno = ERANGE;
  296. if(flag & Fsign)
  297. return -HUGE_VAL;
  298. return HUGE_VAL;
  299. out:
  300. d = 0;
  301. for(i=0; i<Prec; i++)
  302. d = d*One + mid[i];
  303. if(flag & Fsign)
  304. d = -d;
  305. d = ldexp(d, bp - Prec*Nbits);
  306. if(d == 0){ /* underflow */
  307. errno = ERANGE;
  308. }
  309. return d;
  310. }
  311. static void
  312. frnorm(ulong *f)
  313. {
  314. int i, c;
  315. c = 0;
  316. for(i=Prec-1; i>0; i--) {
  317. f[i] += c;
  318. c = f[i] >> Nbits;
  319. f[i] &= One-1;
  320. }
  321. f[0] += c;
  322. }
  323. static int
  324. fpcmp(char *a, ulong* f)
  325. {
  326. ulong tf[Prec];
  327. int i, d, c;
  328. for(i=0; i<Prec; i++)
  329. tf[i] = f[i];
  330. for(;;) {
  331. /* tf *= 10 */
  332. for(i=0; i<Prec; i++)
  333. tf[i] = tf[i]*10;
  334. frnorm(tf);
  335. d = (tf[0] >> Nbits) + '0';
  336. tf[0] &= One-1;
  337. /* compare next digit */
  338. c = *a;
  339. if(c == 0) {
  340. if('0' < d)
  341. return -1;
  342. if(tf[0] != 0)
  343. goto cont;
  344. for(i=1; i<Prec; i++)
  345. if(tf[i] != 0)
  346. goto cont;
  347. return 0;
  348. }
  349. if(c > d)
  350. return +1;
  351. if(c < d)
  352. return -1;
  353. a++;
  354. cont:;
  355. }
  356. }
  357. static void
  358. divby(char *a, int *na, int b)
  359. {
  360. int n, c;
  361. char *p;
  362. p = a;
  363. n = 0;
  364. while(n>>b == 0) {
  365. c = *a++;
  366. if(c == 0) {
  367. while(n) {
  368. c = n*10;
  369. if(c>>b)
  370. break;
  371. n = c;
  372. }
  373. goto xx;
  374. }
  375. n = n*10 + c-'0';
  376. (*na)--;
  377. }
  378. for(;;) {
  379. c = n>>b;
  380. n -= c<<b;
  381. *p++ = c + '0';
  382. c = *a++;
  383. if(c == 0)
  384. break;
  385. n = n*10 + c-'0';
  386. }
  387. (*na)++;
  388. xx:
  389. while(n) {
  390. n = n*10;
  391. c = n>>b;
  392. n -= c<<b;
  393. *p++ = c + '0';
  394. (*na)++;
  395. }
  396. *p = 0;
  397. }
  398. static Tab tab1[] =
  399. {
  400. 1, 0, "",
  401. 3, 1, "7",
  402. 6, 2, "63",
  403. 9, 3, "511",
  404. 13, 4, "8191",
  405. 16, 5, "65535",
  406. 19, 6, "524287",
  407. 23, 7, "8388607",
  408. 26, 8, "67108863",
  409. 27, 9, "134217727",
  410. };
  411. static void
  412. divascii(char *a, int *na, int *dp, int *bp)
  413. {
  414. int b, d;
  415. Tab *t;
  416. d = *dp;
  417. if(d >= (int)(nelem(tab1)))
  418. d = (int)(nelem(tab1))-1;
  419. t = tab1 + d;
  420. b = t->bp;
  421. if(memcmp(a, t->cmp, t->siz) > 0)
  422. d--;
  423. *dp -= d;
  424. *bp += b;
  425. divby(a, na, b);
  426. }
  427. static void
  428. mulby(char *a, char *p, char *q, int b)
  429. {
  430. int n, c;
  431. n = 0;
  432. *p = 0;
  433. for(;;) {
  434. q--;
  435. if(q < a)
  436. break;
  437. c = *q - '0';
  438. c = (c<<b) + n;
  439. n = c/10;
  440. c -= n*10;
  441. p--;
  442. *p = c + '0';
  443. }
  444. while(n) {
  445. c = n;
  446. n = c/10;
  447. c -= n*10;
  448. p--;
  449. *p = c + '0';
  450. }
  451. }
  452. static Tab tab2[] =
  453. {
  454. 1, 1, "", /* dp = 0-0 */
  455. 3, 3, "125",
  456. 6, 5, "15625",
  457. 9, 7, "1953125",
  458. 13, 10, "1220703125",
  459. 16, 12, "152587890625",
  460. 19, 14, "19073486328125",
  461. 23, 17, "11920928955078125",
  462. 26, 19, "1490116119384765625",
  463. 27, 19, "7450580596923828125", /* dp 8-9 */
  464. };
  465. static void
  466. mulascii(char *a, int *na, int *dp, int *bp)
  467. {
  468. char *p;
  469. int d, b;
  470. Tab *t;
  471. d = -*dp;
  472. if(d >= (int)(nelem(tab2)))
  473. d = (int)(nelem(tab2))-1;
  474. t = tab2 + d;
  475. b = t->bp;
  476. if(memcmp(a, t->cmp, t->siz) < 0)
  477. d--;
  478. p = a + *na;
  479. *bp -= b;
  480. *dp += d;
  481. *na += d;
  482. mulby(a, p+d, p, b);
  483. }
  484. static int
  485. xcmp(char *a, char *b)
  486. {
  487. int c1, c2;
  488. while(c1 = *b++) {
  489. c2 = *a++;
  490. if(isupper(c2))
  491. c2 = tolower(c2);
  492. if(c1 != c2)
  493. return 1;
  494. }
  495. return 0;
  496. }