store a 256 bit number into 64 bits

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
You can't. You would lose precision whatever you did.
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.
if you want to store 256 in 64 bit you need 4 (=256/64) 64 bit variables/array
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
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
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.
Otherwise you will have to specifically bit-shift the numbers out:

 
#include <cstdint> 
1
2
uint32_t arr_1[8];
uint64_t arr_2[4];
1
2
3
4
for (unsigned n = 0; n < 4; n++)
{
  arr_2[n] = arr_1[n*2] | ((uint64_t)(arr_1[n*2+1]) << 32);
}

Good luck!
Topic archived. No new replies allowed.