web-dev-qa-db-ja.com

Cの左シフト演算子

考えてみましょう:

#include <stdio.h>
#define macro(a) a=a<<4;

main()
{
    int a = 0x59;
    printf("%x", a);
    printf("\n");
    macro(a)
    printf("%x", a);
}

上記のコードの場合、次の出力が得られます。

59
590

左シフト操作として以下の出力が得られないのはなぜですか?

59
90
6
rvp

左シフトは[〜#〜] not [〜#〜]元の長さに合うように数値を切り捨てます。 _90_を取得するには、次を使用します。

_(a<<4) & 0xff
_

_0x59_はintであり、おそらくお使いのプラットフォームではsizeof(int)==4があります。次に、それは_0x00000059_です。左に4シフトすると、_0x00000590_になります。

また、ビット単位の演算子を扱うときは、何をしているのかわからない限り、_unsigned int_型を使用する良い習慣を身に付けてください。右シフトなどの状況では、動作が異なります。

9
phoeagon

16進数を4桁左にシフトしたので、590が得られます。これは正しいです。

持っていた

000001011001    

4ビット左にシフト

010110010000

16進数で590です

10010000

は16進数で90なので、 phoeagon で示されているように0101を削除することをお勧めします。

6
user1944441

Printfで%xを%dに変更すると、= 89になり、左シフト後にa = 1424になります。

一般に10進数(基数10)の場合

a = a<< n  is  a = a*2^n
a = a>> n  is  a = a/2^n

16進数(基数16)の場合、

N(左または右)によるシフトは、同等の2進数の対応する桁のシフトと見なすことができます。ただし、これは、特定のコンパイラで使用されるsizeof(int)によって異なります。

4

あなたはintを使用しているので、次のようになります。

 000001011001  

左に4シフトすると、次のようになります。

010110010000

最初の8ビットだけを使用したい場合は、「int」ではなくunsigned char(またはchar)を使用する必要はありません。

#include<stdio.h>
#define macro(a) a=a<<4;
main()
{
   unsigned char a=0x59;
   printf("%x",a);
   printf("\n");
   macro(a)
   printf("%x",a);            
}

それでもintを使用したいが、最初の8ビットのみを保持したい場合は、マスクを使用できます。

#define macro(a) a=(a<<4) & 0xFF
1
Joze

では、出力を0x90にするために何をすればよいか教えていただけますか? 最後の4ビットを最初の4ビットにシフトする最後に0を追加する必要があります

最後の4ビットを4ビット左にシフトし、最初の4ビットの代わりにそれを取得できる唯一の方法は、タイプに8ビットしかない場合です。通常、これはintではなくunsigned charの場合です。 0x90を取得します

unsigned char a=0x59;
macro(a)

ただし、intを使用すると、結果は0x590になります。<<を使用した場合のエラーではなく、タイプの選択によるものです。 (またはマクロの誤用?)

0
qPCR4vir