floatscan.c 7.9 KB

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