floatscan.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. #include <stdint.h>
  2. #include <stdio.h>
  3. #include <math.h>
  4. #include <float.h>
  5. #include <limits.h>
  6. #include <errno.h>
  7. #include "shgetc.h"
  8. #include "floatscan.h"
  9. #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
  10. #define LD_B1B_DIG 2
  11. #define LD_B1B_MAX 9007199, 254740991
  12. #define KMAX 128
  13. #else /* LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 */
  14. #define LD_B1B_DIG 3
  15. #define LD_B1B_MAX 18, 446744073, 709551615
  16. #define KMAX 2048
  17. #endif
  18. #define MASK (KMAX-1)
  19. static long long scanexp(FILE *f, int pok)
  20. {
  21. int c;
  22. int x;
  23. long long y;
  24. int neg = 0;
  25. c = shgetc(f);
  26. if (c=='+' || c=='-') {
  27. neg = (c=='-');
  28. c = shgetc(f);
  29. if (c-'0'>=10U && pok) shunget(f);
  30. }
  31. if (c-'0'>=10U) {
  32. shunget(f);
  33. return LLONG_MIN;
  34. }
  35. for (x=0; c-'0'<10U && x<INT_MAX/10; c = shgetc(f))
  36. x = 10*x + c-'0';
  37. for (y=x; c-'0'<10U && x<LLONG_MAX/100; c = shgetc(f))
  38. y = 10*y + c-'0';
  39. for (; c-'0'<10U; c = shgetc(f));
  40. shunget(f);
  41. return neg ? -y : y;
  42. }
  43. static long double decfloat(FILE *f, int bits, int emin, int sign, int pok)
  44. {
  45. uint32_t x[KMAX];
  46. static const uint32_t th[] = { LD_B1B_MAX };
  47. int i, j, k, a, z;
  48. long long lrp=-1, dc=0;
  49. long long e10=0;
  50. int gotdig = 0;
  51. int rp;
  52. int e2;
  53. long double y;
  54. long double frac=0;
  55. long double bias=0;
  56. int c;
  57. j=0;
  58. k=0;
  59. c = shgetc(f);
  60. /* Don't let leading zeros consume buffer space */
  61. for (; c=='0'; c = shgetc(f)) gotdig=1;
  62. x[0] = 0;
  63. for (; c-'0'<10U || c=='.'; c = shgetc(f)) {
  64. if (c == '.') {
  65. if (lrp!=-1) break;
  66. lrp = dc;
  67. } else if (k < KMAX) {
  68. dc++;
  69. if (j) x[k] = x[k]*10 + c-'0';
  70. else x[k] = c-'0';
  71. if (++j==9) {
  72. k++;
  73. j=0;
  74. }
  75. gotdig=1;
  76. } else {
  77. dc++;
  78. x[KMAX-1] |= c-'0';
  79. }
  80. }
  81. if (lrp==-1) lrp=dc;
  82. if (gotdig && (c|32)=='e') {
  83. e10 = scanexp(f, pok);
  84. if (e10 == LLONG_MIN) {
  85. if (pok) {
  86. shunget(f);
  87. } else {
  88. shlim(f, 0);
  89. return 0;
  90. }
  91. e10 = 0;
  92. }
  93. lrp += e10;
  94. } else if (c>=0) {
  95. shunget(f);
  96. }
  97. if (!gotdig) {
  98. errno = EINVAL;
  99. shlim(f, 0);
  100. return 0;
  101. }
  102. if (!x[0])
  103. return sign * 0.0;
  104. if (lrp==dc && (!k || (k==1 && !j)) && (bits>30 || x[0]>>bits==0))
  105. return sign * (long double)x[0];
  106. if (lrp > -emin/2) {
  107. errno = ERANGE;
  108. return sign * LDBL_MAX * LDBL_MAX;
  109. }
  110. if (lrp < emin-2*LDBL_MANT_DIG) {
  111. errno = ERANGE;
  112. return sign * LDBL_MIN * LDBL_MIN;
  113. }
  114. if (k<KMAX && j) {
  115. for (; j<9; j++) x[k]*=10;
  116. k++;
  117. j=0;
  118. }
  119. a = 0;
  120. z = k;
  121. e2 = 0;
  122. rp = lrp;
  123. while (rp < 18+9*LD_B1B_DIG) {
  124. uint32_t carry = 0;
  125. e2 -= 29;
  126. for (k=(z-1 & MASK); ; k=(k-1 & MASK)) {
  127. uint64_t tmp = ((uint64_t)x[k] << 29) + carry;
  128. if (tmp > 1000000000) {
  129. carry = tmp / 1000000000;
  130. x[k] = tmp % 1000000000;
  131. } else {
  132. carry = 0;
  133. x[k] = tmp;
  134. }
  135. if (k==(z-1 & MASK) && k!=a && !x[k]) z = k;
  136. if (k==a) break;
  137. }
  138. if (carry) {
  139. rp += 9;
  140. if (a == z) {
  141. z = (z-1 & MASK);
  142. x[z-1 & MASK] |= x[z];
  143. }
  144. a = (a-1 & MASK);
  145. x[a] = carry;
  146. }
  147. }
  148. if (rp % 9) {
  149. static const int p10s[] = {
  150. 100000000, 10000000, 1000000, 100000,
  151. 10000, 1000, 100, 10
  152. };
  153. int rpm9 = rp % 9;
  154. int p10 = p10s[rpm9-1];
  155. uint32_t carry = 0;
  156. for (k=a; k!=z; k=(k+1 & MASK)) {
  157. uint32_t tmp = x[k] % p10;
  158. x[k] = x[k]/p10 + carry;
  159. carry = 1000000000/p10 * tmp;
  160. if (k==a && !x[k]) {
  161. a = (a+1 & MASK);
  162. rp -= 9;
  163. }
  164. }
  165. if (carry) {
  166. if ((z+1 & MASK) != a) {
  167. x[z] = carry;
  168. z = (z+1 & MASK);
  169. } else x[z-1 & MASK] |= 1;
  170. }
  171. rp += 9-rpm9;
  172. }
  173. for (;;) {
  174. uint32_t carry = 0;
  175. int sh = 1;
  176. for (i=0; i<LD_B1B_DIG; i++) {
  177. k = (a+i & MASK);
  178. if (k == z || x[k] < th[i]) {
  179. i=LD_B1B_DIG;
  180. break;
  181. }
  182. if (x[a+i & MASK] > th[i]) break;
  183. }
  184. if (i==LD_B1B_DIG && rp==9*LD_B1B_DIG) break;
  185. /* FIXME: find a way to compute optimal sh */
  186. if (rp > 9+9*LD_B1B_DIG) sh = 9;
  187. e2 += sh;
  188. for (k=a; k!=z; k=(k+1 & MASK)) {
  189. uint32_t tmp = x[k] & (1<<sh)-1;
  190. x[k] = (x[k]>>sh) + carry;
  191. carry = (1000000000>>sh) * tmp;
  192. if (k==a && !x[k]) {
  193. a = (a+1 & MASK);
  194. rp -= 9;
  195. }
  196. }
  197. if (carry) {
  198. if ((z+1 & MASK) != a) {
  199. x[z] = carry;
  200. z = (z+1 & MASK);
  201. } else x[z-1 & MASK] |= 1;
  202. }
  203. }
  204. for (y=i=0; i<LD_B1B_DIG; i++) {
  205. if ((a+i & MASK)==z) x[z=(z+1 & MASK)] = 0;
  206. y = 1000000000.0L * y + x[a+i & MASK];
  207. }
  208. y *= sign;
  209. if (bits > LDBL_MANT_DIG+e2-emin) {
  210. bits = LDBL_MANT_DIG+e2-emin;
  211. if (bits<0) bits=0;
  212. }
  213. if (bits < LDBL_MANT_DIG) {
  214. bias = copysignl(scalbn(1, 2*LDBL_MANT_DIG-bits-1), y);
  215. frac = fmodl(y, scalbn(1, LDBL_MANT_DIG-bits));
  216. y -= frac;
  217. y += bias;
  218. }
  219. if ((a+i & MASK) != z) {
  220. uint32_t t = x[a+i & MASK];
  221. if (t < 500000000 && (t || (a+i+1 & MASK) != z))
  222. frac += 0.25*sign;
  223. else if (t > 500000000)
  224. frac += 0.75*sign;
  225. else if (t == 500000000) {
  226. if ((a+i+1 & MASK) == z)
  227. frac += 0.5*sign;
  228. else
  229. frac += 0.75*sign;
  230. }
  231. if (LDBL_MANT_DIG-bits >= 2 && !fmodl(frac, 1))
  232. frac++;
  233. }
  234. y += frac;
  235. y -= bias;
  236. y = scalbnl(y, e2);
  237. if (!y) errno = ERANGE;
  238. return y;
  239. }
  240. static long double hexfloat(FILE *f, int bits, int emin, int sign, int pok)
  241. {
  242. uint32_t x = 0;
  243. long double y = 0;
  244. long double scale = 1;
  245. long double bias = 0;
  246. int gottail = 0, gotrad = 0, gotdig = 0;
  247. long long rp = 0;
  248. long long dc = 0;
  249. long long e2 = 0;
  250. int d;
  251. int c;
  252. c = shgetc(f);
  253. /* Skip leading zeros */
  254. for (; c=='0'; c = shgetc(f)) gotdig = 1;
  255. if (c=='.') {
  256. gotrad = 1;
  257. c = shgetc(f);
  258. /* Count zeros after the radix point before significand */
  259. for (rp=0; c=='0'; c = shgetc(f), rp--) gotdig = 1;
  260. }
  261. for (; c-'0'<10U || (c|32)-'a'<6U || c=='.'; c = shgetc(f)) {
  262. if (c=='.') {
  263. if (gotrad) break;
  264. rp = dc;
  265. gotrad = 1;
  266. } else {
  267. gotdig = 1;
  268. if (c > '9') d = (c|32)+10-'a';
  269. else d = c-'0';
  270. if (dc<8) {
  271. x = x*16 + d;
  272. } else if (dc < LDBL_MANT_DIG/4+1) {
  273. y += d*(scale/=16);
  274. } else if (d && !gottail) {
  275. y += 0.5*scale;
  276. gottail = 1;
  277. }
  278. dc++;
  279. }
  280. }
  281. if (!gotdig) {
  282. shunget(f);
  283. if (pok) {
  284. shunget(f);
  285. if (gotrad) shunget(f);
  286. } else {
  287. shlim(f, 0);
  288. }
  289. return 0;
  290. }
  291. if (!gotrad) rp = dc;
  292. while (dc<8) x *= 16, dc++;
  293. if ((c|32)=='p') {
  294. e2 = scanexp(f, pok);
  295. if (e2 == LLONG_MIN) {
  296. if (pok) {
  297. shunget(f);
  298. } else {
  299. shlim(f, 0);
  300. return 0;
  301. }
  302. e2 = 0;
  303. }
  304. }
  305. e2 += 4*rp - 32;
  306. if (!x) return sign * 0.0;
  307. if (e2 > -emin) {
  308. errno = ERANGE;
  309. return sign * LDBL_MAX * LDBL_MAX;
  310. }
  311. if (e2 < emin-2*LDBL_MANT_DIG) {
  312. errno = ERANGE;
  313. return sign * LDBL_MIN * LDBL_MIN;
  314. }
  315. while (x < 0x80000000) {
  316. if (y>=0.5) {
  317. x += x + 1;
  318. y += y - 1;
  319. } else {
  320. x += x;
  321. y += y;
  322. }
  323. e2--;
  324. }
  325. if (bits > 32+e2-emin) {
  326. bits = 32+e2-emin;
  327. if (bits<0) bits=0;
  328. }
  329. if (bits < LDBL_MANT_DIG)
  330. bias = copysignl(scalbn(1, 32+LDBL_MANT_DIG-bits-1), sign);
  331. if (bits<32 && y && !(x&1)) x++, y=0;
  332. y = bias + sign*(long double)x + sign*y;
  333. y -= bias;
  334. if (!y) errno = ERANGE;
  335. return scalbnl(y, e2);
  336. }
  337. long double __floatscan(FILE *f, int c, int prec, int pok)
  338. {
  339. int sign = 1;
  340. int i;
  341. int bits;
  342. int emin;
  343. switch (prec) {
  344. case 0:
  345. bits = 24;
  346. emin = -149;
  347. break;
  348. case 1:
  349. bits = 53;
  350. emin = -1074;
  351. break;
  352. case 2:
  353. bits = LDBL_MANT_DIG;
  354. emin = -16445;
  355. break;
  356. default:
  357. return 0;
  358. }
  359. if (c<0) c = shgetc(f);
  360. if (c=='+' || c=='-') {
  361. sign -= 2*(c=='-');
  362. c = shgetc(f);
  363. }
  364. for (i=0; i<8 && (c|32)=="infinity"[i]; i++)
  365. if (i<7) c = shgetc(f);
  366. if (i==3 || i==8 || (i>3 && pok)) {
  367. if (i==3) shunget(f);
  368. if (pok) for (; i>3; i--) shunget(f);
  369. else shlim(f, 0);
  370. return sign * INFINITY;
  371. }
  372. if (!i) for (i=0; i<3 && (c|32)=="nan"[i]; i++)
  373. if (i<3) c = shgetc(f);
  374. if (i==3) {
  375. return NAN;
  376. }
  377. if (i) {
  378. shunget(f);
  379. errno = EINVAL;
  380. shlim(f, 0);
  381. return 0;
  382. }
  383. if (c=='0') {
  384. c = shgetc(f);
  385. if ((c|32) == 'x')
  386. return hexfloat(f, bits, emin, sign, pok);
  387. c = '0';
  388. }
  389. shunget(f);
  390. return decfloat(f, bits, emin, sign, pok);
  391. }