3

在 C# 中

var buffer = new byte[] {71, 20, 0, 0, 9, 0, 0, 0};

var g = (ulong) ((uint) (buffer[0] | buffer[1] << 8 | buffer[2] << 16 | buffer[3] << 24) |
                    (long) (buffer[4] | buffer[5] << 8 | buffer[6] << 16 | buffer[7] << 24) << 32);

在 C++ 中

#define byte unsigned char
#define uint unsigned int
#define ulong unsigned long long

byte buffer[8] = {71, 20, 0, 0, 9, 0, 0, 0};

ulong g = (ulong) ((uint) (buffer[0] | buffer[1] << 8 | buffer[2] << 16 | buffer[3] << 24) |
                    (long) (buffer[4] | buffer[5] << 8 | buffer[6] << 16 | buffer[7] << 24) << 32);

C# 输出38654710855,C++ 输出5199

为什么?我已经为此挠头好几个小时了……

编辑:C# 有正确的输出。

感谢大家的帮助:) Jack Aidley 的答案是第一个,所以我将其标记为已接受的答案。其他答案也是正确的,但我不能接受多个答案:\

4

4 回答 4

6

C++ 不起作用,因为您正在转换为long在大多数当前 C++ 实现中通常是 32 位的,但其确切长度留给实现者。你想要long long

另外,请阅读下面 Bikeshedder 的更完整答案。他非常正确,固定大小的 typedef 是一种更可靠的方法。

于 2013-02-02T12:47:19.170 回答
4

问题是 long 类型C++仍然是 4 字节或 32 位(在大多数编译器上),因此您的计算会溢出它。C#然而inlong等效于C++'slong long并且是 64 位的,因此表达式的结果适合类型。

于 2013-02-02T12:48:28.597 回答
2

unsigned long的长度不是 64 位。sizeof(unsigned long)您可以使用which 应该返回 4(=32 位)而不是 8(=64 位)轻松检查这一点。

如果您希望它们具有特定大小,请不要使用 int/short/long。该标准只是这么说short <= int <= long <= long long并定义了最小尺寸。它们实际上可以是相同的大小。long保证至少为 32 位,并long long保证至少为 64 位。(请参阅C++ 标准的第 22 页)如果您真的想使用特定大小,我仍然强烈建议您不要这样做并坚持使用 stdint。

使用<cstdint>(C++11) 或<cstdint.h>(C++98) 和定义的类型uint8_t, uint16_t, uint32_t,uint64_t代替。

更正了 C++ 代码

#include <stdint.h>
#include <iostream>

int main(int argc, char *argv[]) {
    uint8_t buffer[8] = {71, 20, 0, 0, 9, 0, 0, 0};
    uint64_t g = (uint64_t) ((uint32_t) (buffer[0] | buffer[1] << 8 | buffer[2] << 16 | buffer[3] << 24) |
                              (int64_t) (buffer[4] | buffer[5] << 8 | buffer[6] << 16 | buffer[7] << 24) << 32);
    std::cout << g << std::endl;
    return 0;
}

带输出的演示: http: //codepad.org/e8GOuvMp

于 2013-02-02T12:54:04.423 回答
1

您的铸件中有一个细微的错误。

C# 中的 long 是一个 64 位整数。C++ 中的 long 通常是一个 32 位整数。

因此(long) (buffer[4] | buffer[5] << 8 | buffer[6] << 16 | buffer[7] << 24) << 32),当您在 C# 或 C++ 中执行它时,您的含义会有所不同。

于 2013-02-02T12:49:30.627 回答