2017-11-11 8 views
0

私は考えることができるすべてを試してきましたが、下のバイナリ数学ロジックが機能しないようです。なぜこれが失敗しているのか分かりませんが、おそらく私のバイナリ数学やCの誤解を示しているでしょう。最終的な目的は、大きな整数(unsigned long)を8ビットFRAMメモリモジュールに直接4バイトワードとして保存し、 Arduino)は、停電後に値を回復することができます。したがって、unsigned longは、4バイトのワード部分からアセンブルされなければならず、これらのワードバイトをアセンブルする演算は正しく機能しません。00000001を追加すると、なぜこのバイナリ計算が失敗するのですか?そうでなければ正しく動作しますか?

以下のコードスニペットでは、ロング値はA、B、C、Dの4バイト(4つの8ビットメモリブロックをプル形式にシミュレート)として定義され、10進表記に変換されて配列DDDDDDDDCCCCCCCCBBBBBBBBAAAAAAAAの符号なしlong A < 256とB、C、D all == 0の場合、数学は正しく機能します。 A == 0の場合は、B、C、Dのいずれの値に対しても正しく計算されます。 B、C、D> 0、A == 1の場合、Aの1の値は算術演算時に加算されません。 2の値は動作しますが、1の値は動作しません。これには何らかの理由がありますか?あるいは、バイナリ計算が間違っていますか?回避策が必要な既知の問題ですか?正常(コードで

// ---- FUNCTIONS 

unsigned long fourByte_word_toDecimal(uint8_t byte0 = B00000000, uint8_t byte1 = B00000000, uint8_t byte2 = B00000000, uint8_t byte3 = B00000000){ 
    return (byte0 + (byte1 * 256) + (byte2 * pow(256, 2)) + (byte3 * pow(256, 3))); 
} 

// ---- MAIN 
void setup() { 

    Serial.begin(9600); 

    uint8_t addressAval = B00000001; 
    uint8_t addressBval = B00000001; 
    uint8_t addressCval = B00000001; 
    uint8_t addressDval = B00000001; 

    uint8_t addressValArray[4]; 
    addressValArray[0] = addressAval; 
    addressValArray[1] = addressBval; 
    addressValArray[2] = addressCval; 
    addressValArray[3] = addressDval; 

    unsigned long decimalVal = fourByte_word_toDecimal(addressValArray[0], addressValArray[1], addressValArray[2], addressValArray[3]); 

    // Print out resulting decimal value 
    Serial.println(decimalVal); 

} 

は、上記のバイナリ値はAKA 00000001000000010000000100000001、16843009. の10進値としてもたらすべきであるが、コードはまた、評価00000000にaddressAvalの値を変更16843008.に10進値を評価します)を16843008に変更し、addressAvalを00000010に変更すると、正しく16843010と評価されます。

私は困惑しています。

+0

は、正方形や立方体として、整数演算のための 'pow'を使用しないでください。 ** square **には 'long long'が必要かもしれませんが、** cube **では十分ではないかもしれません。 –

+0

数式を使用する代わりに配列をキャスティングすることを検討しましたか? –

答えて

0

問題はpow()を使用していることです。この原因となっているすべてのものを保持するのに十分な精度を持っていないbinary32、として計算することが16843009.

>>> numpy.float32(16843009) 
16843008.0 

修正は、整数、特に65536と16777216ULを使用することです。

0

これにはpow()を使用しないでください。

これを行うための通常の方法は、シフト演算子である:

uint32_t result = uint32_t(byte3 << 24 | byte2 << 16 | byte1 << 8 | byte0); 
関連する問題