I would like to convert a 64 bit unsigned int into an array of uint8_t in C.
Asked
Active
Viewed 724 times
1
-
its a nice task. please post your code so we can review and try to help. are you familiar with big/little endian and bitwise c operators ? post what you have already tried and what problems uve faced – Adam May 24 '20 at 07:04
-
A *bitfield* comes to mind... or a `union` between `uint8_t[8]` and `uint64_t` would also work. – David C. Rankin May 24 '20 at 07:06
-
What do you mean by "breaking down"? Example: If the value is 12345 (hex: 0x3039) will the array be {1, 2, 3, 4, 5} or will it be {0x30 , 0x39} or somethin different? – Support Ukraine May 24 '20 at 07:54
-
I'm surprised that this Q got 3 upvotes. SO users must be in a real good mood today – Support Ukraine May 24 '20 at 07:56
3 Answers
2
Use a union
:
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int main(int argc, char *argv[])
{
union
{
uint64_t t_var;
uint8_t a_var[8];
} u_var;
u_var.t_var = 0x1122334455667788;
printf("u_var.t_var = 0x%"PRIx64"\n", u_var.t_var);
for(int i = 0 ; i < 8 ; ++i)
printf("u_var.a_var[%d] = 0x%"PRIx8"\n", i, u_var.a_var[i]);
return 0;
}
which outputs
u_var.t_var = 0x1122334455667788
u_var.a_var[0] = 0x88
u_var.a_var[1] = 0x77
u_var.a_var[2] = 0x66
u_var.a_var[3] = 0x55
u_var.a_var[4] = 0x44
u_var.a_var[5] = 0x33
u_var.a_var[6] = 0x22
u_var.a_var[7] = 0x11

Bob Jarvis - Слава Україні
- 48,992
- 9
- 77
- 110
1
One solution is to use bitwise AND in conjunction with the bitshift operator:
#include <stdio.h>
#include <stdint.h>
int main() {
uint64_t var = 0x1122334455667788;
uint8_t array[8] = {
(var & 0x00000000000000FFull) >> 0,
(var & 0x000000000000FF00ull) >> 8,
(var & 0x0000000000FF0000ull) >> 16,
(var & 0x00000000FF000000ull) >> 24,
(var & 0x000000FF00000000ull) >> 32,
(var & 0x0000FF0000000000ull) >> 40,
(var & 0x00FF000000000000ull) >> 48,
(var & 0xFF00000000000000ull) >> 56
};
for (uint8_t i = 0; i < 8; ++i) {
printf("%d %2.2x\n", i, array[i]);
}
return 0;
}

Marco
- 7,007
- 2
- 19
- 49
-
1why you have answered him? we are just waiting for him to post his try! i doubt if he or she tried to solve this problem. i think in such cases we need to wait and to see if the OP did something at all – Adam May 24 '20 at 07:12
-
@Adam I wanted to comment `What have you tried?` but SO wouldn't let me and suggested to flag, downvote or move on. So I answered and moved on ;) – Marco May 24 '20 at 07:30
-
i just want to see his or her try! but i am going with you i will post an answer. since you did it with bit wise shif operator i will doit with bitfields. i wiil voteup your answer. hope you will up vote my answer as well :) – Adam May 24 '20 at 08:36
-
4`(var>>0) & 0xff, ..., (var >> 24) & 0xff, ... (var >> 56) & 0xff` has simpler constants, but using a loop like `for (int i = 0; i < 8; i++) array[i] = (var >> (8 * i)) & 0xff;` is easiest to read (leaving the compiler free to choose to unroll it). – Paul Hankin May 24 '20 at 08:53
0
solving the problem with Bitfields, since bitwise shift already covered.
typedef unsigned char uint8_t;
typedef unsigned long long uint64_t; /*assuming that long long is 64 bit on your machine*/
typedef struct SPLITER{
uint64_t Byte0 : 8;
uint64_t Byte1 : 8;
uint64_t Byte2 : 8;
uint64_t Byte3 : 8;
uint64_t Byte4 : 8;
uint64_t Byte5 : 8;
uint64_t Byte6 : 8;
uint64_t Byte7 : 8;
}SPLITER;
int main()
{
uint64_t f = 0xffffff;
uint8_t arr[8];
SPLITER X = {f,f>>8,f>>16,f>>24,f>>32,f>>40,f>>48,f>>56};
/*fill array elements with the bitfields we already splited*/
memcpy(arr, &f, 8); /*we can doit with memcpy its more ilegant and efficient*/
for(uint8_t j =0; j < 8; ++j)
{
printf("%X\n",arr[j]); /*print the array in hex format*/
}
return 0;
}
-
1`memcpy(arr, &f, 8);` is an easier way to write this code. (Also note that `uint8_t` and `uint64_t` are defined in `stdint.h`). – Paul Hankin May 24 '20 at 08:49
-
@PaulHankin - great comment. thank you. i will fix it. hope that you find my answer useful. – Adam May 24 '20 at 08:51
-
1