スポンサーリンク

PICのプログラムで使っているXC8でハマった、float型の符号反転の方法、
今回は備忘録として記事にしました。

モニターに表示された1と0

float型以外のビット演算andを使った符号反転の方法

float以外のint型であれば、最上位のビットが符号用ビットと
なっている2の補数となっているので、1バイトの変数でビット操作で符号判別と
符号を正の値に直すことが出来ます。

if(data & 0x80){
data = data & 0x7F; 
}

これはifの0x80は2進数では0b10000000で
記号の&はand演算となっていて、変数dataがマイナスの値
最上位のビットが立っている場合data & 0x80 = 1となり、if文に入ります。

if内の0x7Fは2進数で0b01111111となっていて、
最上位ビットのみをマスク、0にします。

AM2321の気温がマイナスの時の判別も、この方法で行っていました。

ビット演算が使えないfloat型の符号反転の方法

float型(浮動小数点数型)は4バイトの変数で小数点以下も計算出来るのが特徴。
詳しくは理解していないので詳しい事はこちら

浮動小数点数 - Wikipedia
浮動小数点数型と誤差

4バイトなので0x80000000でマスクして0x7FFFFFFFで反転出来ると
思っていましたが、ダメでした。

何度やってもコンパイルエラーが出るので調べたら
なんと、float型の変数にはビット演算が使えない様です。

ただ、抜け道はあるみたいで、
共同体を使えば、float型に直接ではなく、間接的に代入する事が出来るみたいです。
【参考】2006-09-23 浮動小数点型でビット演算

ただ、符号反転の為ならわざわざ共同体を使ってまでビット演算をしなくても良いみたいです。

なんと、普通の計算式で符号反転させる方法がありました。
それがこれです。

data = data * -1;

そう、マイナス1を掛ければ符号が反転します。
【参考】猿でも解る C言語講座 - STEP 1

このままだと正の値まで反転されてしまうので以下の様にします。

if(data < 0){
data = data * -1;
}

これで、0.00以下になった場合は、値が反転される様になりました!

まとめ

C言語には色々な変数型があるので少し面倒ですがアセンブラで書く事を考えたら
かなり楽です。

ただ、プログラムは楽になりますが、プログラムメモリとの戦いにはなります。

コンパイルログにはこんな文があります。
Running this compiler in PRO mode, with Omniscient Code Generation enabled,
produces code which is typically 40% smaller than in Free mode.
The MPLAB XC8 PRO compiler output for this code could be 1613 words smaller.
See http://microchip.com for more information.

PROモードでコンパイルすれば40%フリーモードより削減できますよ、との内容です。
ちなみに、現在プログラム中の気圧計はプログラムメモリ99.7%使用と致命的な状態です。

ただし、XC8のPRO版は13万円もするので個人の趣味の用途では無いので
大きなプログラムを書くならArduinoの方が良いのかもしれません。
ちなみにXC8のスタンダード版は約7万円です!

Arduinoもライブラリを入れすぎると容量がヤバイです。