Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <sstream>
- #include <iostream>
- #include <iomanip>
- #include <cstdio>
- #include <cctype>
- #include <cstdint>
- #include <cassert>
- #include <cmath>
- namespace io
- {
- namespace
- {
- char input[1 << 24];
- auto cursor = input;
- auto size = []
- {
- char x[] = "+1.5E+1";
- for (auto s : {"", "-", "+"}) {
- auto y = x;
- while (*s) {
- *y++ = *s++;
- }
- for (auto m : {"1", "1.", ".1", "1.1"}) {
- auto z = y;
- while (*m) {
- *z++ = *m++;
- }
- cursor = std::copy(x, z, cursor);
- *cursor++ = ' ';
- for (auto E : {'E', 'e'}) {
- *z = E;
- for (auto S : {"", "-", "+"}) {
- auto t = z + 1;
- if (*S) {
- *t++ = *S++;
- }
- *t++ = '1';
- assert(t < x + sizeof x);
- cursor = std::copy(x, t, cursor);
- *cursor++ = ' ';
- }
- }
- }
- }
- return cursor;
- }() - input;
- using i32 = std::int32_t;
- using i64 = std::int64_t;
- using u32 = std::uint32_t;
- using u64 = std::uint64_t;
- void skip_ws()
- {
- for (;;) {
- switch (*++cursor) {
- case ' ' :
- case 't' :
- case 'r' :
- case 'n' : {
- break;
- }
- default : {
- return;
- }
- }
- }
- }
- template< typename F = float >
- F read_float()
- {
- char c = *cursor;
- char significand[18];
- auto s = significand;
- i32 after = 0;
- i32 before = 0;
- char sign = c;
- switch (c) {
- case '-' :
- case '+' :
- c = *++cursor;
- break;
- default : {
- break;
- }
- }
- [&]
- {
- for (;;) {
- switch (c) {
- case '.' :
- before = -1;
- break;
- case '0' ... '9' : {
- *s++ = c;
- if (before < 0) {
- --before;
- }
- if (s == significand + sizeof significand) {
- i32 a = 0;
- for (;;) {
- switch ((c = *++cursor)) {
- case '0' ... '9' :
- ++a;
- break;
- case '.' : {
- after = a;
- break;
- }
- default : {
- if ((before == 0) && (after == 0)) {
- after = a;
- }
- return;
- }
- }
- }
- }
- break;
- }
- default : {
- return;
- }
- }
- c = *++cursor;
- }
- }();
- if (before < 0) {
- ++before;
- }
- u32 exponent = 0;
- switch (c) {
- case 'e' :
- case 'E' : {
- c = *++cursor;
- char esign = c;
- switch (c) {
- case '-' :
- case '+' :
- c = *++cursor;
- break;
- }
- [&]
- {
- for (;;) {
- switch (c) {
- case '0' ... '9' :
- exponent = (exponent << 3) + (exponent << 1) + (c - '0');
- break;
- default : {
- return;
- }
- }
- c = *++cursor;
- }
- }();
- if (esign == '-') {
- after -= exponent;
- } else {
- after += exponent;
- }
- break;
- }
- default : {
- break;
- }
- }
- after += before;
- std::uint8_t bcd[10] = {};
- i32 b = 0;
- do {
- --s;
- if ((b % 2) == 0) {
- bcd[b / 2] = std::uint8_t(*s - '0');
- } else {
- bcd[b / 2] |= (std::uint8_t(*s - '0') << 4);
- }
- ++b;
- } while (s != significand);
- if (sign == '-') {
- bcd[9] |= (1 << 7);
- }
- F result;
- asm(
- "fldl2tn"
- "fildl %2n"
- "fmulpn"
- "fld %%stn"
- "frndintn"
- "fxchn"
- "fsub %%st(1), %%stn"
- "f2xm1n"
- "fld1n"
- "faddpn"
- "fscalen"
- "fstp %%st(1)n"
- "fbld %1n"
- "fmulpn"
- : "=t"(result) : "m"(bcd), "m"(after) : "memory", "st(1)", "st(2)");
- return result;
- }
- }
- }
- int main()
- {
- using namespace io;
- //size = std::fread(input, 1, sizeof input, stdin);
- //*cursor = '