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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 05:09:57  来源:igfitidea点击:

How do I convert a 64bit integer to a char array and back?

clinux

提问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);

}