Linux 如何将 64 位整数转换为字符数组并返回?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9695720/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I convert a 64bit integer to a char array and back?
提问by user1161604
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 aas shown, but not the second number bwhich clearly falls into the range of int64_t.
我在将 int64_t 转换为 char 数组并返回时遇到问题。我不知道下面的代码有什么问题,这对我来说完全合乎逻辑。该代码适用于a如图所示,但不适b用于显然属于 int64_t 范围的第二个数字。
#include <stdio.h>
#include <stdint.h>
void int64ToChar(char mesg[], int64_t num) {
for(int i = 0; i < 8; i++) mesg[i] = num >> (8-1-i)*8;
}
int64_t charTo64bitNum(char a[]) {
int64_t n = 0;
n = ((a[0] << 56) & 0xFF00000000000000U)
| ((a[1] << 48) & 0x00FF000000000000U)
| ((a[2] << 40) & 0x0000FF0000000000U)
| ((a[3] << 32) & 0x000000FF00000000U)
| ((a[4] << 24) & 0x00000000FF000000U)
| ((a[5] << 16) & 0x0000000000FF0000U)
| ((a[6] << 8) & 0x000000000000FF00U)
| ( a[7] & 0x00000000000000FFU);
return n;
}
int main(int argc, char *argv[]) {
int64_t a = 123456789;
char *aStr = new char[8];
int64ToChar(aStr, a);
int64_t aNum = charTo64bitNum(aStr);
printf("aNum = %lld\n",aNum);
int64_t b = 51544720029426255;
char *bStr = new char[8];
int64ToChar(bStr, b);
int64_t bNum = charTo64bitNum(bStr);
printf("bNum = %lld\n",bNum);
return 0;
}
output is
输出是
aNum = 123456789
bNum = 71777215744221775
The code also gives two warnings that I don't know how to get rid of.
该代码还给出了两个我不知道如何摆脱的警告。
warning: integer constant is too large for ‘unsigned long' type
warning: left shift count >= width of type
采纳答案by Hyman
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:
这相当简单,问题在于您正在移动 char 数组中的位,但大小a[i]为 4 个字节(向上转换为int),因此您的移位只是超出了范围。尝试在您的代码中替换它:
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 charto a 64bit number before doing the shift and you won't go over range. You'll obtain correct results:
通过这种方式,您将char在进行移位之前将 转换为 64 位数字,并且不会超出范围。您将获得正确的结果:
entity:Dev Hyman$ ./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:
只是附带说明,我认为这也可以正常工作,假设您不需要查看 char 数组内部:
#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;
}
回答by Tim
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
你是32位机器吗?IIRC 我认为 U 后缀仅表示 'unsigned int' 或 'unsigned long',它们在 32 位机器上都是 32 位。我认为您在位移位中想要一个“无符号长长”(64 位)文字,或者0xFF00000000000000ULL
http://en.kioskea.net/faq/978-c-language-handling-64-bit-integers#unsigned-64-bit-integer
http://en.kioskea.net/faq/978-c-language-handling-64-bit-integers#unsigned-64-bit-integer
回答by Andrew Cooper
In charTo64bitNumyou need to cast the char to 64-bit before you shift it:
在charTo64bitNum你移动它之前,你需要将字符转换为 64 位:
(((int64_t)a[0] << 56) & 0xFF00000000000000U)
回答by gdj
void int64ToChar(char mesg[], int64_t num) {
*(int64_t *)mesg = num; //or *(int64_t *)mesg = htonl(num);
}

