やっぱ頭がいい人は違う

 1byteのデータのビットをMSB<->LSBでさかさまにする方法を探していた。ArduinoのshiftOut()だとMSBFIRSTとLSBFIRSTが選べる。けどこれをハードウエアSPIに置き換えたら選べない気がする。(と思ってたが、Arduinoだと選べる。mbedは指定でき無さそう。)

 で、探していると、javaのIntegerクラスのreverseというメソッドが引っかかった。その解説ページもあった。隣同士を入れ替えて、次は2つまとめて隣同士を入れえて、その次は4つまとめてとなり同士を入れ替えて。みたいな感じでbyteなら完了。Integerクラスの実装は32bitの様でもう1こ処理があります。

8bit版を所望していたので、ちょっと削ってみて、Cなので>>>演算子はないので>>に置き換えてみて

byte i = 0b10010111;

i = (i & 0x55) << 1 | (i >> 1) & 0x55;
i = (i & 0x33) << 2 | (i >> 2) & 0x33;
i = (i & 0x0f) << 4 | (i >> 4) & 0x0f;

上記を0bで書くと

i = (i & 0b01010101) << 1 | (i >> 1) & 0b01010101;
i = (i & 0b00110011) << 2 | (i >> 2) & 0b00110011;
i = (i & 0b00001111) << 4 | (i >> 4) & 0b00001111;

 とかで実際にreverse出来ました。すごいなぁ。頭が硬いとループ回したり、変換配列つくったりしてしまう。ただ、Cの場合は算術シフトと論理シフトは実装次第なので、全検証してみないとわからんですね。シフト演算子はわかってしまえば超ベンリかつ速いので下手なループかますより良いですね。
 で、「>>」はArduinoはavrgccなのでunsignedは論理シフト、signedの時は算術シフトみたいです。
 mbedでも大丈夫そう(byteはunsigned intに変えましたが)。ただ、mbedのコンパイラ 0bが通らないみたいでコンパイルエラーでて5分悩んだ。というか0b使えるのはGCCだけなのかも。

 mbedのコンパイラ。インストールしなくて楽ちんなのでオンラインコンパイラをずっとつかっていたけど、そろそろオフラインコンパイラも導入してみても良いかも。プログラムソースのExportをする際にzipファイル以外にいくつかパターンが選択できるのだけど、あれがオフラインコンパイラへのソースだったのかと。

シェアする

フォローする