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 a
as shown, but not the second number b
which 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 char
to 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 charTo64bitNum
you 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);
}