I am having trouble converting a int64_t to a char array and back. I don\'t know what is wrong with the code below, it makes complete logical sense to me. The code works for
This is rather simple, the problem is that you are shifting bits in the char array but size of a[i]
is 4 byes (upcast to int
), so your shift just goes over range. Try replacing this in your code:
int64_t charTo64bitNum(char a[]) {
int64_t n = 0;
n = (((int64_t)a[0] << 56) & 0xFF00000000000000U)
| (((int64_t)a[1] << 48) & 0x00FF000000000000U)
| (((int64_t)a[2] << 40) & 0x0000FF0000000000U)
| (((int64_t)a[3] << 32) & 0x000000FF00000000U)
| ((a[4] << 24) & 0x00000000FF000000U)
| ((a[5] << 16) & 0x0000000000FF0000U)
| ((a[6] << 8) & 0x000000000000FF00U)
| (a[7] & 0x00000000000000FFU);
return n;
}
In this way you'll cast the char
to a 64bit number before doing the shift and you won't go over range. You'll obtain correct results:
entity:Dev jack$ ./a.out
aNum = 123456789
bNum = 51544720029426255
Just a side note, I think this would work fine too, assuming you don't need to peek inside the char array:
#include <string.h>
void int64ToChar(char a[], int64_t n) {
memcpy(a, &n, 8);
}
int64_t charTo64bitNum(char a[]) {
int64_t n = 0;
memcpy(&n, a, 8);
return n;
}
Are you on a 32bit machine? IIRC I think that the U suffix only means either 'unsigned int' or 'unsigned long', both of which are 32bits on a 32bit machine. I think you want a 'unsigned long long' (64bit) literal in your bit shifts, or 0xFF00000000000000ULL
http://en.kioskea.net/faq/978-c-language-handling-64-bit-integers#unsigned-64-bit-integer
void int64ToChar(char mesg[], int64_t num) {
*(int64_t *)mesg = num; //or *(int64_t *)mesg = htonl(num);
}
In charTo64bitNum
you need to cast the char to 64-bit before you shift it:
(((int64_t)a[0] << 56) & 0xFF00000000000000U)