Guest User

Untitled

a guest
Jan 22nd, 2018
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.40 KB | None | 0 0
  1. #include <sstream>
  2. #include <iostream>
  3. #include <iomanip>
  4.  
  5. #include <cstdio>
  6. #include <cctype>
  7. #include <cstdint>
  8. #include <cassert>
  9. #include <cmath>
  10.  
  11. namespace io
  12. {
  13. namespace
  14. {
  15.  
  16. char input[1 << 24];
  17. auto cursor = input;
  18. auto size = []
  19. {
  20. char x[] = "+1.5E+1";
  21. for (auto s : {"", "-", "+"}) {
  22. auto y = x;
  23. while (*s) {
  24. *y++ = *s++;
  25. }
  26. for (auto m : {"1", "1.", ".1", "1.1"}) {
  27. auto z = y;
  28. while (*m) {
  29. *z++ = *m++;
  30. }
  31. cursor = std::copy(x, z, cursor);
  32. *cursor++ = ' ';
  33. for (auto E : {'E', 'e'}) {
  34. *z = E;
  35. for (auto S : {"", "-", "+"}) {
  36. auto t = z + 1;
  37. if (*S) {
  38. *t++ = *S++;
  39. }
  40. *t++ = '1';
  41. assert(t < x + sizeof x);
  42. cursor = std::copy(x, t, cursor);
  43. *cursor++ = ' ';
  44. }
  45. }
  46. }
  47. }
  48. return cursor;
  49. }() - input;
  50.  
  51. using i32 = std::int32_t;
  52. using i64 = std::int64_t;
  53. using u32 = std::uint32_t;
  54. using u64 = std::uint64_t;
  55.  
  56. void skip_ws()
  57. {
  58. for (;;) {
  59. switch (*++cursor) {
  60. case ' ' :
  61. case 't' :
  62. case 'r' :
  63. case 'n' : {
  64. break;
  65. }
  66. default : {
  67. return;
  68. }
  69. }
  70. }
  71. }
  72.  
  73. template< typename F = float >
  74. F read_float()
  75. {
  76. char c = *cursor;
  77. char significand[18];
  78. auto s = significand;
  79. i32 after = 0;
  80. i32 before = 0;
  81. char sign = c;
  82. switch (c) {
  83. case '-' :
  84. case '+' :
  85. c = *++cursor;
  86. break;
  87. default : {
  88. break;
  89. }
  90. }
  91. [&]
  92. {
  93. for (;;) {
  94. switch (c) {
  95. case '.' :
  96. before = -1;
  97. break;
  98. case '0' ... '9' : {
  99. *s++ = c;
  100. if (before < 0) {
  101. --before;
  102. }
  103. if (s == significand + sizeof significand) {
  104. i32 a = 0;
  105. for (;;) {
  106. switch ((c = *++cursor)) {
  107. case '0' ... '9' :
  108. ++a;
  109. break;
  110. case '.' : {
  111. after = a;
  112. break;
  113. }
  114. default : {
  115. if ((before == 0) && (after == 0)) {
  116. after = a;
  117. }
  118. return;
  119. }
  120. }
  121. }
  122. }
  123. break;
  124. }
  125. default : {
  126. return;
  127. }
  128. }
  129. c = *++cursor;
  130. }
  131. }();
  132. if (before < 0) {
  133. ++before;
  134. }
  135. u32 exponent = 0;
  136. switch (c) {
  137. case 'e' :
  138. case 'E' : {
  139. c = *++cursor;
  140. char esign = c;
  141. switch (c) {
  142. case '-' :
  143. case '+' :
  144. c = *++cursor;
  145. break;
  146. }
  147. [&]
  148. {
  149. for (;;) {
  150. switch (c) {
  151. case '0' ... '9' :
  152. exponent = (exponent << 3) + (exponent << 1) + (c - '0');
  153. break;
  154. default : {
  155. return;
  156. }
  157. }
  158. c = *++cursor;
  159. }
  160. }();
  161. if (esign == '-') {
  162. after -= exponent;
  163. } else {
  164. after += exponent;
  165. }
  166. break;
  167. }
  168. default : {
  169. break;
  170. }
  171. }
  172. after += before;
  173.  
  174. std::uint8_t bcd[10] = {};
  175. i32 b = 0;
  176. do {
  177. --s;
  178. if ((b % 2) == 0) {
  179. bcd[b / 2] = std::uint8_t(*s - '0');
  180. } else {
  181. bcd[b / 2] |= (std::uint8_t(*s - '0') << 4);
  182. }
  183. ++b;
  184. } while (s != significand);
  185. if (sign == '-') {
  186. bcd[9] |= (1 << 7);
  187. }
  188.  
  189. F result;
  190. asm(
  191. "fldl2tn"
  192. "fildl %2n"
  193. "fmulpn"
  194. "fld %%stn"
  195. "frndintn"
  196. "fxchn"
  197. "fsub %%st(1), %%stn"
  198. "f2xm1n"
  199. "fld1n"
  200. "faddpn"
  201. "fscalen"
  202. "fstp %%st(1)n"
  203. "fbld %1n"
  204. "fmulpn"
  205. : "=t"(result) : "m"(bcd), "m"(after) : "memory", "st(1)", "st(2)");
  206. return result;
  207. }
  208.  
  209. }
  210. }
  211.  
  212. int main()
  213. {
  214. using namespace io;
  215. //size = std::fread(input, 1, sizeof input, stdin);
  216. //*cursor = '';
  217. //cursor = input;
  218.  
  219. {
  220. static const char l[] = "-.999999999999999999E-124";
  221. cursor = std::copy(l, l + sizeof l - 1, cursor);
  222. *cursor++ = ' ';
  223. }
  224.  
  225. {
  226. static const char h[] = "0.999999999999999999187";
  227. cursor = std::copy(h, h + sizeof h - 1, cursor);
  228. *cursor++ = ' ';
  229. }
  230.  
  231. {
  232. static const char g[] = "9999999999999999999999999999999999999999";
  233. cursor = std::copy(g, g + sizeof g - 1, cursor);
  234. *cursor++ = ' ';
  235. }
  236.  
  237. *cursor++ = '';
  238.  
  239. //std::cout << input << std::endl;
  240.  
  241. cursor = input;
  242. switch (*cursor) {
  243. case ' ' :
  244. case 't' :
  245. case 'r' :
  246. case 'n' :
  247. skip_ws();
  248. break;
  249. case '' :
  250. return EXIT_SUCCESS;
  251. }
  252. std::istringstream is{input};
  253. std::stringstream ss{input};
  254. std::cout << std::setprecision(std::numeric_limits< long double >::digits10 + 1);
  255. for (;;) {
  256. std::string x;
  257. if (!(is >> x)) {
  258. break;
  259. }
  260. long double y = std::numeric_limits< long double >::quiet_NaN();
  261. if (!(ss >> y)) {
  262. assert(false);
  263. }
  264. long double z = read_float< long double >();
  265. if (std::abs(z - y) > 9E-18 * std::max(std::abs(z), std::abs(y))) {
  266. std::cout << x << ":t" << y << 't' << z << std::endl;
  267. }
  268. skip_ws();
  269. }
  270. #if 0
  271. using c8 = char [8];
  272. const auto s2u32 = [] (const char s[]) -> std::uint32_t
  273. {
  274. static c8 z = {'0', '0', '0', '0', '0', '0', '0', '0'};
  275. auto string = reinterpret_cast< const std::uint64_t & >(*s) - reinterpret_cast< const std::uint64_t & >(z);
  276. string = (((string >> 4) & 0x00F000F000F000F0LL) | (string & 0x000F000F000F000FLL));
  277. c8 & c = reinterpret_cast< c8 & >(string);
  278. c[1] = c[2];
  279. c[2] = c[4];
  280. c[3] = c[6];
  281. return reinterpret_cast< const std::uint32_t & >(c);
  282. };
  283. auto bcd = s2u32("01234567");
  284. std::cout << std::hex << bcd << std::endl;
  285. // fbld
  286. #endif
  287. }
Add Comment
Please, Sign In to add comment