#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";
}