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#には正しい出力があります。

みんな助けてくれてありがとう:)ジャックエイドリーの答えが最初だったので、それを受け入れられた答えとしてマークします。他の回答も正解でしたが、複数回答はできません :\

4

4 に答える 4

6

long現在のほとんどの C++ 実装では通常 32 ビットですが、正確な長さは実装者に任されているため、C++ は機能していません。あなたがしたいlong long

また、以下のBikeshedderのより完全な回答をお読みください。彼は、固定サイズの typedef がこれを行うためのより信頼できる方法であるということはまったく正しいです。

于 2013-02-02T12:47:19.170 に答える
4

問題は、(ほとんどのコンパイラで) long 型C++がまだ 4 バイトまたは 32 ビットであるため、計算でオーバーフローすることです。ただしC#longは と同等であり、64 ビットであるため、式C++long long結果は型に適合します。

于 2013-02-02T12:48:28.597 に答える
2

あなたunsigned longは64ビット長ではありません。sizeof(unsigned long)これは、8(= 64ビット)ではなく4(= 32ビット)を返すものを使用して簡単に確認できます。

特定のサイズであることが予想される場合は、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_tuint32_tuint64_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 に答える