将 64 位 Int 转换为 Char[](以及反之)

标签 c arrays hex endianness

我编写了一个程序,希望将大尾数(我相信因为我在 Mac 上,整数将是小尾数)字符数组(或者更确切地说 uint8_ts)转换为 int64_t 并返回。这是我的代码:

int64_t CharsToInt(uint8_t* chars) {
    return chars[0] + (chars[1] * 0x100) + (chars[2] * 0x10000) + (chars[3] * 0x1000000) + (chars[4] * 0x100000000) + (chars[5] * 0x10000000000) + (chars[6] * 0x1000000000000) + (chars[7] * 0x100000000000000);
}

void IntToChars(int64_t i, uint8_t* chars) {
    for(int k = 0; k < 8; k++) {
        chars[k] = i >> k*8;
    }
}

int main() {

    int64_t x;

    unsigned char chars[8];

    IntToChars(x, chars);

    for (int k = 0; k < 8; k++) {
        printf("%0x\n", chars[k]);
    }

    // little endian
    int64_t rv = CharsToInt(chars);

    printf("%lld\n", rv);
}

如果x是12,或者任何其他零或正数,代码工作得很好,但是如果x是负数,它就无法工作。

x = 12 的输出:

c
0
0
0
0
0
0
0
value: 12

输出为x = -12:

f4
ff
ff
ff
ff
ff
ff
ff
value: -4294967308

这似乎与符号的存储和转换方式有关,因为我认为英特尔(我在 Mac 上)使用 2s-compliment 而不是普通的旧符号位。但是,我真的不知道如何确定这是否属实,如果是,如何弥补它(最好以可移植的方式)。

我知道还有很多像这样的其他问题,并且我已经阅读了它们(实际上大部分代码都来自它们),但我仍然无法让它工作,所以我问我的拥有。

最佳答案

你是对的。 Intel 64 和 IA-32 使用 2 补码表示有符号数。请参阅Intel 64 and IA-32 Architectures Software Developer’s Manual第 4.2.1 节。因此,读取 FFFFFFFFFFFFFFF4 为 -12 是正确的。在2补码表示法中,负数的表示方法是取相应的正数,将所有位反转并加1:

12 = 000000000000000C -> FFFFFFFFFFFFFFF3 -> FFFFFFFFFFFFFFF4 = -12

如果我可以添加一些内容,您也可以通过执行以下操作将 char 数组转换为 uint64_t:

int64_t CharsToInt(uint8_t* chars) {
    return *(int64_t*)chars;
}

关于将 64 位 Int 转换为 Char[](以及反之),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31170567/

相关文章:

javascript - 如何要求用户输入并反转该输入

arrays - Swift Realm [[String]] 对象

JavaScript 将 RGB 整数转换为十六进制

c - 如何从文件或输入中去除除十六进制以外的所有内容?

audio - 在 .wav 文件和十六进制编辑器中查找样本数

c - C 中的指针作用域

c++ - 为 c 而不是 c++ 设置 visual studio 2008 编译器

c - 如果你必须在 if 语句中放置 break,为什么我们需要在 while 操作中为条件操心?

被 rpcgen 示例代码搞糊涂了

javascript - d3.js:在数组中的对象中提取数组