0

Is there a simple way to split one 64-bit (unsigned long long) variable into eight int8_t values?

For example:

//1001000100011001100100010001100110010001000110011001000110011111
unsigned long long bigNumber = 10455547548911899039;
int8_t parts[8] = splitULongLong(bigNumber);

parts would be something along the lines of:

[0] 10011111

[1] 10010001

[2] 00011001

...

[7] 10010001

Community
  • 1
  • 1
JohnWO
  • 203
  • 3
  • 13

4 Answers4

2

First you shouldn't play such games with signed values, this only complicates the issue. Then you shouldn't use unsigned long long directly, but the appropriate fixed width type uint64_t. This may be unsigned long long, but not necessarily.

Any byte (assuming 8 bit) in such an integer you may obtain by shifting and masking the value:

#define byteOf(V, I) (((V) >> (I)*8)&UINT64_C(0xFF))

To initialize your array you would place calls to that macro inside an initializer.

BTW there is no standard "binary" format for integers as you seem to be assuming.

luser droog
  • 18,988
  • 3
  • 53
  • 105
Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
2
 {
   uint64_t v= _64bitVariable;
   uint8_t i=0,parts[8]={0};
   do parts[i++]=v&0xFF; while (v>>=8);
 }
AShelly
  • 34,686
  • 15
  • 91
  • 152
1

You should be able to use a Union to split the data up without any movement or processing.

This leaves you with the problem of the resulting table being in hte wrong order which can be easily solved with a macro (if you have lots of hard coded values) or a simple "8-x" subscript calculation.

#define rv(ss) = 8 - ss;


union SameSpace {
unsigned long long _64bitVariable;
int8_t _8bit[8];
} samespace;

_64bitVariable = 0x1001000100011001100100010001100110010001000110011001000110011111;

if (_8bit[rv(1)] == 0x10011111) {
   printf("\n correct");
}
Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
James Anderson
  • 27,109
  • 7
  • 50
  • 78
  • 1
    This answer adopts the question’s use of `0x` notation for binary, which does not work in C. – Eric Postpischil Nov 18 '13 at 09:53
  • The `rv` macro definition has three problems: Function-like macros must not have a space after the macro name and before the parenthesis, occurrences of the parameter name in the replacement list should be parenthesized, and it is not portable (does not account for different endianness in different implementations). – Eric Postpischil Nov 18 '13 at 09:57
  • @Eric Postpischil - thanks for the syntax check. I have not got a C compiler available at the moment :-) – James Anderson Nov 19 '13 at 01:59
  • Beware, I suggested the use of a union [previously](http://stackoverflow.com/a/2747324/329079) and @Nils Pipenbrinck was astute enough to note that unions are undefined by the c-standard. – Justin Muller Nov 19 '13 at 20:03
  • This method will work different on little and big endian machines ? – PaulHK Jan 17 '20 at 02:49
1

I think if it can be this: 64bit num %8 ,save this result,and then minus the result then divide the result by 8 last save divided num and save (64bit num %8) num, and last you get two 8bit num , and you can use this two num to replace 64bit num 。 but when you need to operate , you may need to operate 8bit num to 64 bit mun

HotTunes
  • 11
  • 1
  • %8 preserves the lowest 3 bits, not 8 bits, you need %256 (or & 255) to mask off the lowest 8 bits. – PaulHK Jan 17 '20 at 02:48