2014年09月14日

C#で2進数の記述を容易に

   このエントリーをはてなブックマークに追加 Clip to Evernote
どう書く?orgに感謝を込めて」シリーズ その41

■問題 (出題者:yappy さん)
コンピューターの原理は2進数だというのに、多くのプログラミング言語で8進数や16進数しか記述できないのは少し変だとは思いませんか?
そこで、ソース中に2進数を定数として書く方法、またはその代替手段を考えてください。

ある程度の評価基準を示します(できるところまでで構いません)。
・2進数の表示方法は0と1 
・桁数は可変長 
・コンパイル等の後に最適化等によって定数に変換されることが見込まれる 
Cで関数として実装したものを示しておきます。
1
2
3
4
5

int bin(int b1, int b2, int b3, int b4, int b5, int b6, int b7, int b8){
    return b1<<7 | b2 <<6 | b3<<5 | b4<<4 | b5<<3 | b6<<2 | b7<<1 | b8;}

int byte = bin(0, 1, 1, 0, 1, 0, 0, 1);


上記問題の3つ目の基準は無視します。
Convert.Int32, Convert.ToString() を使えば、文字列からintへ、intから文字列への変換は 簡単に行えるのですが、せっかくなので、C#らしくBinaryNumberという構造体を作成。
演算子のオーバーロード、暗黙の型変換、明示的な型変換などの機能を利用しています。
文字列からBinarryNumberへの変換はもちろん、int と BinarryNumberとの相互変換が可能。
使い方は、コードのMainメソッドを見てください。

using System;

namespace Doukaku.Org {
    class Program {
        static void Main(string[] args) {
            var bn1 = new BinaryNumber("010101");
            var bn2 = (BinaryNumber)"1111";    //明示的な型変換 
// string -> BinaryNumber BinaryNumber bn3 = bn1 + bn2; //演算子+のオーバーロードで実現 Console.WriteLine(bn3); //暗黙の型変換
// BinaryNumber -> int Console.WriteLine(bn3.ToString()); //ToString()のoverload int n1 = bn1; //暗黙の型変換
// BinaryNumber -> int int n2 = (int)bn2; //明示的な型変換
// int -> BinaryNumber int n3 = n1 + n2; Console.WriteLine(n3); BinaryNumber bn4 = new BinaryNumber(32); var n4 = n3 - bn4; //暗黙の型変換
// BinaryNumber -> int Console.WriteLine(n4); Console.ReadLine(); } } struct BinaryNumber { private int _num; public BinaryNumber(int num) { _num = num; } public BinaryNumber(string s) { _num = Convert.ToInt32(s, 2); } public static implicit operator int(BinaryNumber bn) { return bn._num; } public static explicit operator BinaryNumber(int n) { return new BinaryNumber(n); } public static explicit operator BinaryNumber(string s) { return new BinaryNumber(s); } public static BinaryNumber operator +(BinaryNumber b1, BinaryNumber b2) { return new BinaryNumber((int)b1 + (int)b2); } public static BinaryNumber operator -(BinaryNumber b1, BinaryNumber b2) { return new BinaryNumber((int)b1 - (int)b2); } public static BinaryNumber operator *(BinaryNumber b1, BinaryNumber b2) { return new BinaryNumber((int)b1 * (int)b2); } public static BinaryNumber operator /(BinaryNumber b1, BinaryNumber b2) { return new BinaryNumber((int)b1 / (int)b2); } public override string ToString() { return Convert.ToString(_num, 2); } } }


 

この記事へのトラックバックURL

http://trackback.blogsys.jp/livedoor/gushwell/52382365