アマプログラマーの独り言
コンピュータでの負の数 2002年01月08日 |
コンピュータ内で「負の数」はどうやって表しているのでしょうか? 例えばプログラミングで「負となる算術式」が出てきた場合です。 多少ハードウェアに通じている人は、 「あー、知っちょる知っちょる」 と思うかもしれませんが、あんまよく知らない人は、 「え・・・?どういう事?」 と思うでしょう。 実はデジタル回路で、「本当に負となる」数値は表現できません。 CPUの演算もデジタル処理なので、例に漏れません。 どんなものでも最小値は0(ゼロ)となります。(日常生活でもそうスね) でも実際電卓などでコンピュータ上で「負」を表現できているのですから、なんらかの表現方法があるハズです。 ではどうやって表現しているのか? 「-1」を表現してみましょう。 10進 → -1 2進 → 1111 1111 1バイト(8Bit)の場合です。 2進つまりコンピュータ内では上のように表現されています。 「1」を加算してみると、 0000 0001 1111 1111 ----------- 0000 0000 オーバーフローになりますが、とりあえず「0」になります。 しかしマイナス表現する場合、1バイト(8Bit)の場合、範囲が-128~127になります。 -129以下もしくは128以上の値は1バイトでは不可能になります。 これの理由は、マイナスを使う場合、最上位ビット7(1111 1111太字部分)は「符号」として扱われるからです。 つまりビット8に1が立っていれば「負」、0であれば「正」となります。 しかしまたここで問題。 1111 1111は負では「-1」ですが、正で「255」とも表現出来てしまいますね。 ビット7に1が立っていれば、必ずしも負になるとは限りません。 はい。とりあえずこんな感じです。 まとめると、 「負を表すには、最上位ビットに1を立てる」 という事になります。 でも最後に書いた「必ずしも負になるとは限りません」という台詞。 裏を返せば、「-1と255は論理式ではイコールとなる」と言えます。 なるんでしょうか? たろはクダラナイ事に興味を持ちます。 ちょっと実験用プログラムを組んでみました。 =================================================== union { char BYTE : 8; struct { unsigned char a : 1; unsigned char b : 1; unsigned char c : 1; unsigned char d : 1; unsigned char e : 1; unsigned char f : 1; unsigned char g : 1; unsigned char h : 1; } BIT; } aaa, bbb; int main(void) { int a; aaa.BYTE = 255; bbb.BYTE = -1; printf("変数A = %d\n", aaa.BYTE); printf("変数B = %d\n", bbb.BYTE); a = (aaa.BYTE == bbb.BYTE); printf("論理比較結果: %d", a); return 0; }; =================================================== こういう細かいビット処理の場合は、VBよりCのが楽です。 unionというのは共用体です。 これを実行すると、 変数A = -1 変数B = -1 論理比較結果 : 1 となります。 共用体の中にある構造体は、それぞれのビットです。 255を代入した時と、-1を代入した時、両方とも1111 1111になっているかデバッグで確認してみてください。(たろパソコンでは確認出来ました) さて「-1と255はイコールになるか?」という事ですが、、、 結果としては1(真)が返ってますので、「イコールになる」というのが答えです。 というか代入した時点で-1というのは255という数値になります。 これはunsined charで宣言しているからです。 但し! これはchar型での結果です。 short型などで比較した場合は、式は偽となります。 これはデータの範囲が2バイト(16Bit)となり、きちんと255と-1として比較されるからです。 あと、unsigned charではなく、charなどにすると-1同士で比較され、やはり結果はTrueとなります。 だからどーしたという今日のアマプログラマーの独り言でした。 |