4

How could one "split" i.e. long long type, so that first part of it is in var of type long and second part is also in var of type long.

long long long_type = 0xaaaabbbbccccdddd;

and in first int I would like to have first half(doesn't matter from what side) of the long_type var and in second var int second half.

There is nothing we can do
  • 23,727
  • 30
  • 106
  • 194

3 Answers3

6

Your question is ambiguous. It depends on what you mean by "split". You can split the value representation of your original long long or you can split the object representation of your long long.

If you want to split the value representation, then your question is even more ambiguous due to the fact that your original value is signed. How do you intend to split a signed value? What kind of result do you expect? Signed? Unsigned? High-order part signed, low-order part unsigned? Or something else?

For an unsigned value it would look as follows (assuming that the recipient type long has the right size for your purposes)

unsigned long long long_type = ...;

unsigned long hi = long_type / ULONG_MAX;
unsigned long lo = long_type;

If you want to split the object representation, the proper way to do it would be to use memcpy (in this case the signedness of the original value is not of importance)

long long long_type = ...;

unsigned long hi, lo;

memcpy(&lo, &long_type, sizeof lo);
memcpy(&hi, (char *) &long_type + sizeof lo, sizeof hi);

In this case, of course, which part is actually the low-order one and which part is the high-order one will depend on the platform.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
5

I'd recommend using uint32_t and uint64_t or other fixed width types.

Then use bit operations to split it like:

uint64_t long_type = smthng;
uint32_t high = (long_type & 0xFFFFFFFF00000000ULL) >> 32;
uint32_t low = long_type & 0xFFFFFFFF;
piotr
  • 5,657
  • 1
  • 35
  • 60
1
long a = long_type;
long b = (static_cast<unsigned long long>(long_type) >> 32);
Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274
  • 4
    Because parentheses make everything better. – GWW Apr 12 '11 at 17:30
  • 1
    @TonyK: Because I like parentheses. They make things more clear to me. – Benjamin Lindley Apr 12 '11 at 17:31
  • UB! Right shift on signed type is undefined behaviour. – piotr Apr 12 '11 at 17:31
  • 1
    @piotr No it isn't. If the value is negative, the results are implementation defined, but only if the value is negative. And in practice only two variants exist: zero bits are inserted, or one bits are inserted. On the other hand, when assigning to a `long`, if the value doesn't fit in a `long`, the results are implementation defined, and may result in a signal, which if not caught may result in program termination. – James Kanze Apr 12 '11 at 18:00
  • @piotr: it's actually *left* shifts on signed types that might result in undefined behavior (basically it's undefined if you don't start with a non-negative value and end with a value that's small enough to still be). – Michael Burr Apr 13 '11 at 19:20
  • @Michael Burr: No, piotr's comment is (almost) correct. Right shift on signed type is *implementation-defined*. – TonyK Apr 13 '11 at 19:25
  • @TonyK, piotr: yup - there's a fine line between UB and IB. Sorry if I came across negatively. I was really just pointing out a bit of related trivia on the shift operator. – Michael Burr Apr 13 '11 at 19:37