1 // -*- c++ -*- 2 #include <stdio.h> 3 template<unsigned int N> 4 class Integral { 5 6 unsigned char bytes[N]; 7 8 public: Integral()9 Integral() { 10 for (unsigned int i=0; i<N; i++) 11 bytes[i] = 0; 12 } Integral(const Integral & I)13 Integral(const Integral &I) { 14 for (unsigned int i=0; i<N; i++) 15 bytes[i] = I.bytes[i]; 16 } Integral(long long value)17 Integral(long long value) { 18 resize_signed_int((unsigned char*)&value, sizeof(value), bytes, N); 19 } 20 21 operator long long() const { 22 long long value; 23 resize_signed_int(bytes, N, (unsigned char*)&value, sizeof(value)); 24 return value; 25 } 26 27 Integral& operator=(const Integral &I) { 28 for (unsigned int i=0; i<N; i++) 29 bytes[i] = I.bytes[i]; 30 return *this; 31 } 32 bool operator<(const Integral &I) const 33 { return cmp(I) < 0; } 34 bool operator>(const Integral &I) const 35 { return cmp(I) > 0; } 36 bool operator<=(const Integral &I) const 37 { return cmp(I) <= 0; } 38 bool operator>=(const Integral &I) const 39 { return cmp(I) >= 0; } 40 bool operator==(const Integral &I) const 41 { return cmp(I) == 0; } 42 bool operator!=(const Integral &I) const 43 { return cmp(I) != 0; } 44 45 bool operator==(const long long value) const { 46 size_t len = sizeof(long long) > N ? sizeof(long long) : N; 47 unsigned char* extended = new unsigned char[len]; 48 unsigned char* other; 49 if (sizeof(long long) < N) { 50 resize_signed_int((unsigned char*)&value, sizeof(value), extended, len); 51 other = bytes; 52 } else { 53 resize_signed_int(bytes, N, extended, len); 54 } 55 bool res = memcmp(extended, other, len); 56 delete extended; 57 return res; 58 } 59 bool operator!=(const long long val) const 60 { return !(*this == val); } 61 62 private: is_le()63 static bool is_le() { 64 int one = 1; 65 int b = (int)*(unsigned char *)&one; 66 return b ? true : false; 67 } lsb()68 static unsigned int lsb() { 69 return is_le() ? 0 : N-1; 70 } msb()71 static unsigned int msb() { 72 return is_le() ? N-1 : 0; 73 } cmp(const Integral & J)74 int cmp(const Integral& J) const { 75 const Integral& I = *this; 76 unsigned char sI = I.bytes[msb()] & 0x80; 77 unsigned char sJ = J.bytes[msb()] & 0x80; 78 if (sI > sJ) return -1; 79 if (sI < sJ) return +1; 80 unsigned char bI = I.bytes[msb()] & 0x7F; 81 unsigned char bJ = J.bytes[msb()] & 0x7F; 82 int cmpabs = 0; 83 if (bI < bJ) 84 cmpabs = -1; 85 else if (bI > bJ) 86 cmpabs = +1; 87 else { 88 int incr = is_le() ? -1 : 1; 89 unsigned int i = msb() + incr; 90 while (i != lsb()) { 91 if (I.bytes[i] < J.bytes[i]) 92 { cmpabs = -1; break; } 93 if (I.bytes[i] > J.bytes[i]) 94 { cmpabs = +1; break; } 95 i += incr; 96 } 97 } 98 if (sI) return -cmpabs; 99 else return +cmpabs; 100 } 101 resize_signed_int(const unsigned char * src,size_t src_len,unsigned char * dst,size_t dst_len)102 static void resize_signed_int(const unsigned char* src, size_t src_len, unsigned char* dst, size_t dst_len) { 103 unsigned char msb; 104 size_t dst_offset = 0; 105 size_t src_offset = 0; 106 if (is_le()) { 107 dst_offset = 0; 108 src_offset = 0; 109 msb = ((unsigned char*) src)[src_len - 1]; 110 if (src_len > dst_len) { 111 src_len = dst_len; 112 } 113 } else { 114 if (dst_len > src_len) { 115 dst_offset = dst_len - src_len; 116 } else { 117 src_offset = src_len - dst_len; 118 src_len = dst_len; 119 } 120 msb = ((unsigned char*) src)[0]; 121 } 122 if (msb & 0x80) { 123 memset(dst, 0xFF, dst_len); 124 } else { 125 memset(dst, 0, dst_len); 126 } 127 memcpy(dst + dst_offset, src + src_offset, src_len); 128 } 129 }; 130 131 typedef Integral<3> Int24; 132 typedef Integral<7> Int56; 133 typedef Integral<11> Int88; 134 typedef Integral<64> Int512; 135