2017-04-09 4 views
1

現在、バイナリメモリを含むプログラムを作成しています。符号なしlong long intに特定のビットシーケンスが必要です。C予期せずビット単位のOR値を変更する

現在、このコードブロックを4回ループして32ビットシーケンスを作成しようとしています。

unsigned long long int currentEntry = 0; 
for (int j = 0; j < 4; ++j){ 
    currentEntry = (currentEntry << 8); 
    currentEntry = (currentEntry | (unsigned long long int)entryBuffer[i][j]); 
} 

entrybuffer私は奇妙なを取得するまで、[i]は、[j]は、私は符号なしlong long int型にキャストバイトの値が含まれている文字であり、それは私の知る限り動作しているようですバグ。例えば は、ここcurrentEntry変数はバイナリ形式である:

//goal bit sequence: 00001000000001001010000011000000 

currentEntry = (currentEntry << 8); 
//00000000 
currentEntry = (currentEntry | (unsigned long long int)entryBuffer[i][j]); //entrybuffer[i][j] = 00001000 
//00001000 
currentEntry = (currentEntry << 8); 
//0000100000000000 
currentEntry = (currentEntry | (unsigned long long int)entryBuffer[i][j]); //entrybuffer[i][j] = 00000100 
//0000100000000100 
currentEntry = (currentEntry << 8); 
//000010000000010000000000 
currentEntry = (currentEntry | (unsigned long long int)entryBuffer[i][j]); //entrybuffer[i][j] = 10100000 
//111111111111111110100000 (what?)***** 
currentEntry = (currentEntry << 8); 
//11111111111111111010000000000000 
currentEntry = (currentEntry | (unsigned long long int)entryBuffer[i][j]); //entrybuffer[i][j] = 11000000 
//11111111111111111111111111000000 

私はここで何かを明らかに不足しているようだ、と誰もが私はこれを理解することができます場合、私は思ったんだけど。コードが十分理解できることを願っています。

明らかに、ビット単位のORが何かを変えているか、何かがどこかでオーバーフローしています。そのため、currentEntryを符号なしlong long intにしました。私は明らかに4バイトの記憶域しか必要としませんが、これはマシンによって異なることを理解していますが、私は未署名のlong long intで十分であると思いました。 さらに情報とコンテキストが必要な場合は、私にお知らせください。

ありがとうございます!

+0

あなたは警告付きでコンパイルしていません(たとえば、-Wall -Wextra')? * strict-aliasing *ルール? –

+0

*は 'entryBuffer'ですか?その*型*とは何ですか? –

+0

@一部のプログラマーの方は、entryBufferはcharです。私も警告でコンパイルしていますが、厳密なエイリアシングルールではないと思います。 – storm143

答えて

2

タイプcharは、コンパイラに応じて、unsignedまたはsignedのいずれかです。あなたの場合はsignedと思われます。

つまり、より大きなタイプにキャストすると、という符号拡張が発生します。あなたがバイナリナンバーで見るものはすべてそれが原因であり、どのようにしてtwo's complement(負の数を扱う最も一般的な方法)が機能するのですか?

符号なしの小さい8ビット値を格納する場合は、代わりにuint8_t型を明示的に使用します(unsignedのプレフィックスuに注意してください)。例えば、詳細についてはthis fixed-width integer referenceをご覧ください。

+2

実際には、longlongへの拡張後のcharが0xFFに対してマスクされていれば、それはうまくいくでしょう。 – davidbak

+0

@一部のプログラマおいてありがとう!それは動作します。今日何か新しいことを学びました。私はそれが何かの2の補完と関係していたことを知っていましたが、char型が符号付きか符号なしかを知ることはできませんでした。私はちょうど非常に醜いが、迅速な修正である(unsigned long long int)(uint8_t)entryBuffer [i] [j])としてentryBufferをキャストしてしまった。 – storm143

関連する問題