#include <bits/stdc++.h>
using namespace std;
const int id_max = 7e7, s_max = (1 << 17)-1, x_max = 2;
class data_tuple
{
struct bit_fields
{
uint64_t id: 27;
uint64_t s1: 17;
uint64_t s2: 17;
uint64_t x: 2;
uint64_t u: 1;
};
union
{
uint64_t key;
bit_fields data;
};
static inline uint64_t score_to_int(double s)
{
return round(s *= s_max);
}
static inline double int_to_score(int s)
{
return double(s)/s_max;
}
public:
void set_id(int id)
{
data.id = id;
}
void set_score1(double x)
{
data.s1 = score_to_int(x);
}
void set_score2(double x)
{
data.s2 = score_to_int(x);
}
void set_x(int x)
{
data.x = x;
}
int get_id() const
{
return data.id;
}
double get_score1() const
{
return int_to_score(data.s1);
}
double get_score2() const
{
return int_to_score(data.s2);
}
int get_x() const
{
return data.x;
}
data_tuple(int id = 0, double s1 = 0, double s2 = 0, int x = 0, int u = 0)
{
data.id = id,
data.s1 = score_to_int(s1),
data.s2 = score_to_int(s2),
data.x = x,
data.u = u;
}
friend istream& operator>>(istream& in, data_tuple& a)
{
int id, x; double s1, s2;
in >> id >> s1 >> s2 >> x,
a.data.id = id,
a.set_score1(s1),
a.set_score2(s2),
a.data.x = x;
return in;
}
static inline ostream&
write(ostream& out, int id, double s1, double s2, int x)
{
out << id << ' ',
out << fixed << setprecision(5) << s1 << ' ',
out << fixed << setprecision(5) << s2 << ' ',
out << x;
return out;
}
friend ostream& operator<<(ostream& out, const data_tuple& a)
{
return write(out,a.data.id,a.get_score1(),a.get_score2(),a.data.x);
}
uint64_t hash_key() const
{
return key;
}
};
int main()
{
srand(time(NULL));
int id = 1+(rand()%id_max);
double s1 = double(rand()%(s_max+1))/s_max;
double s2 = double(rand()%(s_max+1))/s_max;
int x = rand()%(x_max+1);
data_tuple a(id,s1,s2,x), b;
cin >> b,
cout << "testing 64-bit data_tuple" << endl,
cout << "randomly generated tuple" << endl,
data_tuple::write(cout,id,s1,s2,x), cout << endl,
cout << a << endl,
cout << a.hash_key() << endl,
cout << "input tuple" << endl,
cout << b << endl,
cout << b.hash_key() << endl,
cout << "data_tuple size = " << 8*sizeof(a) << " bits";
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKY29uc3QgaW50IGlkX21heCA9IDdlNywgc19tYXggPSAoMSA8PCAxNyktMSwgeF9tYXggPSAyOwoKY2xhc3MgZGF0YV90dXBsZQp7CglzdHJ1Y3QgYml0X2ZpZWxkcwoJewoJCXVpbnQ2NF90IGlkOiAyNzsKCQl1aW50NjRfdCBzMTogMTc7CgkJdWludDY0X3QgczI6IDE3OwoJCXVpbnQ2NF90ICB4OiAgMjsKCQl1aW50NjRfdCAgdTogIDE7IAoJfTsKCgl1bmlvbiAKCXsKCQl1aW50NjRfdCAgICAgIGtleTsKCQliaXRfZmllbGRzICAgZGF0YTsKCX07CgoJc3RhdGljIGlubGluZSB1aW50NjRfdCBzY29yZV90b19pbnQoZG91YmxlIHMpCgl7CgkJcmV0dXJuIHJvdW5kKHMgKj0gc19tYXgpOwoJfQoKCXN0YXRpYyBpbmxpbmUgZG91YmxlIGludF90b19zY29yZShpbnQgcykKCXsKCQlyZXR1cm4gZG91YmxlKHMpL3NfbWF4OyAKCX0KCnB1YmxpYzoKCXZvaWQgc2V0X2lkKGludCBpZCkKCXsKCQlkYXRhLmlkID0gaWQ7Cgl9CgkKCXZvaWQgc2V0X3Njb3JlMShkb3VibGUgeCkKCXsKCQlkYXRhLnMxID0gc2NvcmVfdG9faW50KHgpOwoJfQoJCgl2b2lkIHNldF9zY29yZTIoZG91YmxlIHgpCgl7CgkJZGF0YS5zMiA9IHNjb3JlX3RvX2ludCh4KTsKCX0KCQoJdm9pZCBzZXRfeChpbnQgeCkKCXsKCQlkYXRhLnggPSB4OyAKCX0KCQoJaW50IGdldF9pZCgpIGNvbnN0IAoJewoJCXJldHVybiBkYXRhLmlkOyAKCX0KCQoJZG91YmxlIGdldF9zY29yZTEoKSBjb25zdAoJewoJCXJldHVybiBpbnRfdG9fc2NvcmUoZGF0YS5zMSk7IAoJfQoJCglkb3VibGUgZ2V0X3Njb3JlMigpIGNvbnN0Cgl7CgkJcmV0dXJuIGludF90b19zY29yZShkYXRhLnMyKTsKCX0KCQoJaW50IGdldF94KCkgY29uc3QKCXsKCQlyZXR1cm4gZGF0YS54OwoJfQoJCglkYXRhX3R1cGxlKGludCBpZCA9IDAsIGRvdWJsZSBzMSA9IDAsIGRvdWJsZSBzMiA9IDAsIGludCB4ID0gMCwgaW50IHUgPSAwKSAKCXsKCQlkYXRhLmlkID0gaWQsIAoJCWRhdGEuczEgPSBzY29yZV90b19pbnQoczEpLCAKCQlkYXRhLnMyID0gc2NvcmVfdG9faW50KHMyKSwgCgkJZGF0YS54ICA9IHgsCgkJZGF0YS51ICA9IHU7Cgl9CgkKCWZyaWVuZCBpc3RyZWFtJiBvcGVyYXRvcj4+KGlzdHJlYW0mIGluLCBkYXRhX3R1cGxlJiBhKQoJewoJCWludCBpZCwgeDsgZG91YmxlIHMxLCBzMjsKCgkJaW4gPj4gaWQgPj4gczEgPj4gczIgPj4geCwKCQlhLmRhdGEuaWQgPSBpZCwKCQlhLnNldF9zY29yZTEoczEpLAoJCWEuc2V0X3Njb3JlMihzMiksCgkJYS5kYXRhLnggPSB4OwoJCQoJCXJldHVybiBpbjsgCgl9CgoJc3RhdGljIGlubGluZSBvc3RyZWFtJiAKCQl3cml0ZShvc3RyZWFtJiBvdXQsIGludCBpZCwgZG91YmxlIHMxLCBkb3VibGUgczIsIGludCB4KQoJewoJCW91dCA8PCBpZCA8PCAnICcsCgkJb3V0IDw8IGZpeGVkIDw8IHNldHByZWNpc2lvbig1KSA8PCBzMSA8PCAnICcsCgkJb3V0IDw8IGZpeGVkIDw8IHNldHByZWNpc2lvbig1KSA8PCBzMiA8PCAnICcsCgkJb3V0IDw8IHg7CQoJCgkJcmV0dXJuIG91dDsgCgl9CgkKCWZyaWVuZCBvc3RyZWFtJiBvcGVyYXRvcjw8KG9zdHJlYW0mIG91dCwgY29uc3QgZGF0YV90dXBsZSYgYSkKCXsKCQlyZXR1cm4gd3JpdGUob3V0LGEuZGF0YS5pZCxhLmdldF9zY29yZTEoKSxhLmdldF9zY29yZTIoKSxhLmRhdGEueCk7Cgl9CgkKCXVpbnQ2NF90IGhhc2hfa2V5KCkgY29uc3QKCXsKCQlyZXR1cm4ga2V5OyAKCX0KfTsKCmludCBtYWluKCkgCnsKCXNyYW5kKHRpbWUoTlVMTCkpOwoJCglpbnQgCWlkID0gMSsocmFuZCgpJWlkX21heCk7Cglkb3VibGUJczEgPSBkb3VibGUocmFuZCgpJShzX21heCsxKSkvc19tYXg7Cglkb3VibGUJczIgPSBkb3VibGUocmFuZCgpJShzX21heCsxKSkvc19tYXg7CglpbnQJCXggID0gcmFuZCgpJSh4X21heCsxKTsKCglkYXRhX3R1cGxlIGEoaWQsczEsczIseCksIGI7IAoJCQoJY2luID4+IGIsCgljb3V0IDw8ICJ0ZXN0aW5nIDY0LWJpdCBkYXRhX3R1cGxlIiA8PCBlbmRsLAoJY291dCA8PCAicmFuZG9tbHkgZ2VuZXJhdGVkIHR1cGxlIiAgPDwgZW5kbCwKCWRhdGFfdHVwbGU6OndyaXRlKGNvdXQsaWQsczEsczIseCksIGNvdXQgPDwgZW5kbCwgCgljb3V0IDw8IGEgPDwgZW5kbCwKCWNvdXQgPDwgYS5oYXNoX2tleSgpIDw8IGVuZGwsCgljb3V0IDw8ICJpbnB1dCB0dXBsZSIgPDwgZW5kbCwgCgljb3V0IDw8IGIgPDwgZW5kbCwKCWNvdXQgPDwgYi5oYXNoX2tleSgpIDw8IGVuZGwsIAoJY291dCA8PCAiZGF0YV90dXBsZSBzaXplID0gIiA8PCA4KnNpemVvZihhKSA8PCAiIGJpdHMiOwp9