Feb 4, 2014 at 9:31am UTC
I have to store a 256 bit number into 64 bits
like a number in 256 bit array to 64 bit array
1 2 3 4 5
unsigned int arr_1[8]; //each location containing 32 bits
I have to store data of 256 bits in above array arr_1 into arr_2 of 64 bits? How it would be?
unsigned int arr_2[2];
Last edited on Feb 4, 2014 at 9:32am UTC
Feb 4, 2014 at 12:18pm UTC
You can't. You would lose precision whatever you did.
Feb 4, 2014 at 12:21pm UTC
Either we are missing some significant information or whoever asked you to do this is either clueless or a jerk. It can't be done. For example, I can't fit 24 eggs in a dozen (not without irrevocably losing a lot of eggs).
Hope this helps.
Feb 4, 2014 at 2:04pm UTC
if you want to store 256 in 64 bit you need 4 (=256/64) 64 bit variables/array
Feb 4, 2014 at 9:58pm UTC
Just curious. Would something like this work?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
class uint256
{
union Data_u256
{
struct
{
unsigned long halfLongHi;
unsigned long long halfword[3];
unsigned long halfLongLo;
};
unsigned long long word[4];
} m_data;
public :
uint256& operator +=(const uint256& other)
{
// add halfLongLo to word[0] to halfword[0] to word[1] to halfword[1]...
return *this ;
}
};
Last edited on Feb 4, 2014 at 10:01pm UTC
Feb 4, 2014 at 10:26pm UTC
Best I could do is 256 bits in 32 bit containers. Then I use 64 bit containers to handle overflows. Can be safely converted to 64-bit containers with a union though:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
class uint256
{
typedef unsigned long u32;
typedef unsigned long long u64;
union
{
u64 full[4]; // <-- access 64-bit word array here.
u32 half[8];
};
u32 overflow(u32 a, u32 b)
{
u64 total = (u64)a + (u64)b;
return (u32)((total >> 32) & 0x00000000ffffffff);
}
u32 underflow(u32 a, u32 b)
{
u64 total = (u64)a + (u64)b;
return (u32)(total & 0x00000000ffffffff); // truncating is implicit, but for clarity:
}
public :
uint256& operator +=(const uint256& other)
{
u32 oflow = 0, uflow = 0;
for (int i = 0; i < 8; ++i)
{
uflow = underflow( half[i], oflow );
oflow = overflow( half[i], oflow );
half[i] = underflow( other.half[i], uflow );
oflow += overflow( other.half[i], uflow );
}
// if (oflow) throw something;
return *this ;
}
uint256 operator +(const uint256& other) const
{
uint256 retval = *this ;
retval += other;
return retval;
}
};
Last edited on Feb 4, 2014 at 10:35pm UTC
Feb 4, 2014 at 10:41pm UTC
Actually, an easier solution now that I've re-read your question:
to store:
unsigned int arr_1[8];
into
unsigned long int arr_2[4];
I think you can just: memcpy(arr_2, arr_1, 32);
But I'm not sure if the endian will mess things up.