を切り捨てるためにどのように私は、同様の質問をしてきましたが、より多くの研究の後、私は理解できない何かに出くわした、とうまくいけば、誰かがこの動作を引き起こしているかを説明することができます正しく整数型
// We wish to store a integral type, in this case 2 bytes long.
signed short Short = -390;
// In this case, signed short is required to be 2 bytes:
assert(sizeof(Short) == 2);
cout << "Short: " << Short << endl; // output: -390
signed long long Long = Short;
// in this case, signed long long is required to be 8 bytes long
assert(sizeof(Long) == 8);
cout << "Long: " << Long << endl; // output: -390
// enough bytes to store the signed short:
unsigned char Bytes[sizeof(Short)];
// Store Long in the byte array:
for (unsigned int i = 0; i < sizeof(Short); ++i)
Bytes[i] = (Long >> (i * 8)) & 0xff;
// Read the value from the byte array:
signed long long Long2 = (Bytes[0] << 0) + (Bytes[1] << 8);
cout << Long2 << endl; // output: 65146
signed short Short2 = static_cast<signed short>(Long2);
cout << Short2 << endl; // output: -390
は出力:
-390
-390
65146
-390
誰かがここで何が起こっているのか説明できますか?これは未定義の動作ですか?どうして?
正式には、実装の詳細である整数の正確な表現に依存しているため、プログラムの動作は明示されていません(おそらくは未定義です)。実際には、典型的な2の補数表現を仮定すると、あなたは符号拡張を失っています: 'Long2'は、' Long'が '0xFF'を持つ上位バイトでゼロを持っています –
@IgorTandetnikこうして整数を格納する理由は、私はどこかでそれを安全に行う方法を読んでいます。ソースは素晴らしくなかったと思いますか?整数をバイト配列に適切に格納する方法を詳しく説明できますか?または自分のフォーマットを定義する必要がありますか? –
「Long >> 8」は、「Long」が負で、実装定義の振る舞いです。 – aschepler