3

私はもっ​​と長い機能を作ろうとしましたが、それは非常に奇妙な動作をしました。私は問題を切り分けようとしましたが、バグのある部分を見つけることができました。

このプログラムはArduino用に作成されましたが、この現象はおそらく他の環境でも発生します。たくさん検索してみましたが、解決策が見つかりません。

だから、私のバグのある部分:

これらの2つのコードで同じ結果が得られないのはなぜですか? 余分な変数なしで「コード1」のような同じ操作
で1行の関数を作成するにはどうすればよいですか?

結果:

  • コード1:0b00101100
  • コード2:0b01101100

ソースコード:


コード1:(正しい操作ですが、1行ではありません)

#include <binary.h>

const byte value=B00110110;
byte buffer,result;

void setup(){
  Serial.begin(115200);

  buffer = (value << 3);
  result = (buffer >> 2);

  Serial.println(result,BIN);
}

void loop(){
}

それは与える:0b00101100


コード2:(不正な操作ですが1行)

#include <binary.h>

const byte value=B00110110;
byte result;

void setup(){
  Serial.begin(115200);

  result = ((value << 3) >> 2);

  Serial.println(result,BIN);
}

void loop(){
}

それは与える:0b01101100


4

3 に答える 3

5

でマスキングして余分なビットを削除します0xFF

result = (((value << 3) & 0xFF) >> 2);

一連のシフトの後で、上位3ビットをトリミングすることもできます。

result = 0x1F & ((value << 3) >> 2);

言語仕様によれば、デフォルトの整数拡張はシフト前にシフトオペランドに適用され、演算の結果は最初のオペランドのプロモートされたタイプになります。

5.8.1オペランドは、整数型または列挙型でなければならず、汎整数拡張が実行されます。結果のタイプは、プロモートされた左オペランドのタイプです。

積分型がに収まる場合intint、昇格の結果です。左にシフトすると、最上位ビットがの上部に「こぼれ」intます。最初のスニペットはbyte、;に割り当てることでそれらを切り取ります。結果を。でマスクすることにより、同じ結果を得ることができます0xFF

ideoneへのリンク

于 2012-07-25T19:13:46.430 に答える
3

byteuint8_t(フェルナンデス氏に感謝します!)の場合、の結果は(value << 3)よりも広くなりbyteます。より正確にvalueは、シフトが発生する前に幅の広いタイプにプロモートされ、その結果、幅の広いタイプになります。コード1の動作を取得するには、コード2を変更して次のようにします。

result = (static_cast<byte>(value << 3) >> 2);

bufferこれは、キャストを使用したコード1の中間割り当てを模倣しています。

于 2012-07-25T19:11:59.920 に答える
2

あなたbyteは。よりも小さい符号なし積分型だと思いますint

C ++のほとんどの算術演算は、intすべての「小さい」オペランドが暗黙的に型に変換(プロモート)された後、型のドメインで実行されますint

このため、シフトの最初のグループは次のようになります。

buffer = (byte) ((int) value << 3);
result = (byte) ((int) buffer >> 2);

シフトが同等である場合、2番目のグループは

result = (byte) (((int) value << 3) >> 2);

最初のバリアントではbyte、シフトによってタイプの範囲外にシフトされたビットは<< 3、中間変換およびへの割り当て中に失われbufferます。2番目のバリアントでは、すべての計算がの範囲内で実行されるintため、何も失われません。

2番目のバリアントで最初のバリアントと同じ結果を生成する場合は、中間シフトの結果を明示的に「切り捨て」る必要があります。

result = ((byte) (value << 3) >> 2);
于 2012-07-25T19:15:44.323 に答える