4

16 進バイトを解釈し、それらを有用な情報に統合しようとしています。

void processData(){
  signed char data;
  unsigned long a;//holds four bytes
  unsigned long b;
  unsigned int c;//holds two bytes
  unsigned char d;//holds one byte

  a=readA();//readA,readB,readC,readD return one unsigned byte;
  b=readB();
  c=readC();
  d=readD();

  data=(signed char) ((0xffffffff-((a<<24)|(b<<16)|(c<<8)|(d)))/1000);

}

シナリオでは、受信したパッケージ全体に 4 バイトの情報 (たとえば、値 0xAABBCCDD) が含まれています。readA() は、パッケージの最上位バイト、つまり 0xAA を返します。readD() は 0xDD を返します。したがって、「|」を使用する前にそれらをシフトする必要があります それらをまとめるには:(a<<24)|(b<<16)|(c<<8)|(d)

だから私の質問は、この文の右側についてです

data=(signed char) ((0xffffffff-((a<<24)|(b<<16)|(c<<8)|(d)))/1000);

結果を符号付き char にキャストしているときに char が返されないのはなぜですか? 私がそれを印刷すると、すべてが間違っています。ただし、datasigned long として設定すると、すべてが正しくなります。signed char がすべての情報を保持するのに十分な大きさではなく、オーバーフローが発生したためだと思います。

間違っている場合は訂正してください。変数((a<<24)|(b<<16)|(c<<8)|(d)))はすべて暗黙的に unsigned long にキャストされ、この式の結果も同様です。((a<<24)|(b<<16)|(c<<8)|(d)))/1000符号なしの長い数値も返します。ただし、1000 で除算されるため、結果は大幅に小さくなります。

4 バイトの情報は 0xFFFF5037 から 0xFFFFFFFF の範囲であり、この式の結果の範囲でもあります((a<<24)|(b<<16)|(c<<8)|(d)))

したがって、除算後の式の右辺は 0 から 45 の間である必要があります。しかし、結果を印刷すると、すべて飛び回っています。

4

3 に答える 3

0

データの種類を に変更し、 のlongようなもので印刷しますprintf("%lx", data)。そうすれば、より良い手がかりが得られます。

于 2013-04-05T04:00:14.010 に答える